Skip to content

Instantly share code, notes, and snippets.

@eyalzek
Created December 14, 2022 10:42
Show Gist options
  • Save eyalzek/873c4574b1f259bbaa4d486b92c482bc to your computer and use it in GitHub Desktop.
Save eyalzek/873c4574b1f259bbaa4d486b92c482bc to your computer and use it in GitHub Desktop.
Python wrapper to make request to IAP protected sites using external ID token
export GCIP_KEYCLOAK_URL=
export GCIP_KEYCLOAK_USER=
export GCIP_KEYCLOAK_PASSWORD=
export GCIP_KEYCLOAK_CLIENT_ID=
export GCIP_KEYCLOAK_CLIENT_SECRET=
export GCIP_GOOGLE_API_KEY=
export GCIP_EXTERNAL_PROVIDER_ID=

Install python requirements:

pip install -r requirements.txt

Run script (arguments can be passed inline or as env variables):

# with inline arguments:
python gcip.py <IAP_PROTECTED_URL>
  -kc KEYCLOAK_URL \
  -u KEYCLOAK_USERNAME \
  -p KEYCLOAK PASSWORD \
  -c KEYCLOAK_CLIENT_ID \
  -s KEYCLOAK_CLIENT_SECRET \
  -a GOOGLE_API_KEY \
  -i EXTERNAL_PROVIDER_ID
  
  
# with env variables:
# update .env file with correct values and load to environment
source .env
python gcip.py <IAP_PROTECTED_URL>
#!/usr/bin/env python3
import click
import logging
import requests
def init_logger(debug):
level = logging.DEBUG if debug else logging.INFO
logging.basicConfig(level=level, format='%(message)s')
return logging.getLogger()
def get_keycloak_token(url, user, password, client_id, client_secret):
"""
Retrieve Keycloak token
"""
r = requests.post(url, data={
'username': user,
'password': password,
'client_id': client_id,
'client_secret': client_secret,
'grant_type': 'password'
})
r.raise_for_status()
return r.json()['access_token']
def get_gcip_token(api_key, provider_id, kc_token):
"""
Exchange Keycloak token for GCIP token
https://cloud.google.com/identity-platform/docs/reference/rest/v1/accounts/signInWithIdp
"""
url = ('https://content-identitytoolkit.googleapis.com'
'/v1/accounts:signInWithIdp?alt=json&key=%s' % api_key)
r = requests.post(url, json={
'returnSecureToken': True,
'requestUri': 'http://localhost',
'postBody': 'id_token=%s&providerId=%s' % (kc_token, provider_id)
})
r.raise_for_status()
return r.json()['idToken']
def make_iap_request(url, gcip_token):
"""
Make request to IAP protected URL
"""
r = request.get(url, headers={'Authorization': 'Bearer %s' % gcip_token})
r.raise_for_status()
logger.info(r.json())
@click.command()
@click.option('--debug', is_flag=True, default=False)
@click.option('-kc', '--keycloak-url', required=True)
@click.option('-u', '--keycloak-user', required=True)
@click.option('-p', '--keycloak-password', required=True)
@click.option('-c', '--keycloak-client-id', required=True)
@click.option('-s', '--keycloak-client-secret', required=True)
@click.option('-a', '--google-api-key', required=True)
@click.option('-i', '--external-provider-id', required=True)
@click.argument('url')
def main(debug, keycloak_url, keycloak_user, keycloak_password,
keycloak_client_id, keycloak_client_secret,
google_api_key, external_provider_id, url):
logger = init_logger(debug)
kc_token = get_keycloak_token(
keycloak_url, keycloak_user, keycloak_password,
keycloak_client_id, keycloak_client_secret)
logger.debug('Got Keycloak token: %s' % kc_token)
gcip_token = get_gcip_token(google_api_key, external_provider_id, kc_token)
logger.debug('Got GCIP token: %s' % gcip_token)
make_iap_request(url, gcip_token)
if __name__ == '__main__':
main(auto_envvar_prefix='GCIP')
# install with: pip install -r requirements.txt
click==8.1.3
requests==2.28.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment