Exemple #1
0
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}')