def _get_google_oidc_token(): """Get an OpenID Connect token issued by Google for the environment's service account. This function: 1. Generates a JWT signed with the service account's private key containing a special "target_audience" claim. 2. Sends it to the OAUTH_TOKEN_URI endpoint. Because the JWT in #1 has a target_audience claim, that endpoint will respond with an OpenID Connect token for the service account -- in other words, a JWT signed by *Google*. The aud claim in this JWT will be set to the value from the target_audience claim in #1. For more information, see https://developers.google.com/identity/protocols/OAuth2ServiceAccount . The HTTP/REST example on that page describes the JWT structure and demonstrates how to call the token endpoint. (The example on that page shows how to get an OAuth2 access token; this code is using a modified version of it to get an OpenID Connect token.) """ credentials = Credentials( _signer, _adc_credentials.service_account_email, token_uri=OAUTH_TOKEN_URI, additional_claims={'target_audience': os.getenv('CLIENT_ID')} ) service_account_jwt = credentials._make_authorization_grant_assertion() request = GRequest() body = { 'assertion': service_account_jwt, 'grant_type': google.oauth2._client._JWT_GRANT_TYPE, } token_response = google.oauth2._client._token_endpoint_request( request, OAUTH_TOKEN_URI, body) return OIDCToken(token_response['id_token'])
service_account_credentials_path = './kr-co-vcnc-tada-7cb37e11e075.json' dag_name = 'dag_server_log_parquet' data = {'conf': {'date_kr': '2019-11-24'}} # service account credentials 파일로 bootstrap credentials 을 생성합니다. bootstrap_credentials = Credentials.from_service_account_file(service_account_credentials_path) signer_email = bootstrap_credentials.service_account_email signer = bootstrap_credentials.signer # OAuth 2.0 service account credentials 을 생성합니다. # token_uri 값을 바꾸고, additional_claims 을 추가합니다. service_account_credentials = Credentials(signer, signer_email, oauth_token_uri, additional_claims={'target_audience': client_id}) # OpenID Connect token 을 획득합니다. service_account_jwt = service_account_credentials._make_authorization_grant_assertion() body = {'assertion': service_account_jwt, 'grant_type': _JWT_GRANT_TYPE} token_response = _token_endpoint_request(Request(), oauth_token_uri, body) google_open_id_connect_token = token_response['id_token'] # 획득한 token 을 HTTP Header 에 담아서, Airflow Web Server 의 REST API 를 호출합니다. resp = requests.request('POST', f'https://{web_server_id}.appspot.com/api/experimental/dags/{dag_name}/dag_runs', headers={'Authorization': f'Bearer {google_open_id_connect_token}'}, json=data) if resp.status_code == 403: raise Exception(f'Service account {signer_email} does not have permission to ' f'access the IAP-protected application.') elif resp.status_code != 200: raise Exception(f'Bad response from application: {resp.status_code} / {resp.headers} / {resp.text}')