このページでは、Identity-Aware Proxy(IAP)で保護されたリソースをユーザー アカウントまたはサービス アカウントから認証する方法について説明します。
ユーザー アカウントは、個々のユーザーに属します。ユーザーの代わりにアプリケーションが IAP で保護されたリソースにアクセスする必要がある場合、ユーザー アカウントを認証します。詳しくは、ユーザー アカウントをご覧ください。
サービス アカウントは、個々のユーザーではなくアプリケーションに属します。アプリケーションから IAP で保護されたリソースにアクセスできるようにする場合、サービス アカウントを認証します。詳しくは、サービス アカウントをご覧ください。
始める前に
始める前に、次のものが必要になります。
- デベロッパー アカウント、サービス アカウント、モバイルアプリの認証情報を使用してプログラムで接続する、IAP で保護されたアプリケーション。
ユーザー アカウントの認証
デスクトップまたはモバイルアプリからアプリへのユーザー アクセスを有効にすると、プログラムから IAP で保護されたリソースを操作できます。
モバイルアプリからの認証
- IAP で保護されたリソースと同じプロジェクトで、モバイルアプリの OAuth 2.0 クライアント ID を作成します。
- [認証情報] ページに移動します。
[認証情報] ページに移動 - IAP で保護されたリソースを含むプロジェクトを選択します。
- [認証情報を作成] をクリックし、[OAuth クライアント ID] を選択します。
- 認証情報を作成する [アプリケーションの種類] を選択します。
- 必要に応じて [名前] と [制限事項] を追加し、[作成] をクリックします。
- [認証情報] ページに移動します。
- 表示される [OAuth クライアント] ウィンドウで、接続先の IAP で保護されたリソースの [クライアント ID] をメモします。
- IAP で保護されたクライアント ID の ID トークンを取得します。
- Android: Google Sign-In API を使用して OpenID Connect(OIDC)トークンをリクエストします。
requestIdToken
クライアント ID を接続先のリソースのクライアント ID に設定します。 - iOS: Google ログインを使用して ID トークンを取得します。
serverClientID
を接続先のリソースのクライアント ID に設定します。
- Android: Google Sign-In API を使用して OpenID Connect(OIDC)トークンをリクエストします。
Authorization: Bearer
ヘッダーに ID トークンを含めて、IAP で保護されたリソースに認証済みリクエストを送信します。
デスクトップ アプリからの認証
このセクションでは、デスクトップ コマンドラインからユーザー アカウントを認証する方法について説明します。
クライアント ID の設定
デベロッパーがコマンドラインからアプリケーションにアクセスできるようにするには、まず [デスクトップ アプリ] タイプの OAuth クライアント ID 認証情報を作成する必要があります。
- [認証情報] ページに移動します。
[認証情報] ページに移動 - IAP で保護されたリソースを含むプロジェクトを選択します。
- [認証情報を作成] をクリックし、[OAuth クライアント ID] を選択します。
- [アプリケーションの種類] で [デスクトップ アプリ] を選択し、[名前] を追加して、[作成] をクリックします。
- 表示される [OAuth クライアント] ウィンドウで、[クライアント ID] と [クライアント シークレット] をメモします。認証情報を管理したり、デベロッパーと共有したりするには、これらをスクリプトで使用する必要があります。
- [認証情報] ウィンドウに、アプリケーションへのアクセスに使用するメイン クライアント ID とともに、新しい [デスクトップ アプリ] の認証情報が表示されます。
アプリケーションへのログイン
個々のデベロッパーが IAP で保護されたアプリにアクセスするには、まずログインする必要があります。gcloud CLI を使用するなどの方法で、プロセスをスクリプトにパッケージ化できます。次に、curl を使用してログインし、アプリケーションにアクセスするために使用できるトークンを生成する例を示します。
- Google Cloud リソースにアクセスできるアカウントにログインします。
-
受信リクエストをエコーできるローカル サーバーを起動します。
$ nc -k -l 4444
注: このコマンドでは NetCat ユーティリティを使用します。 任意のユーティリティを使用できます。 -
下記の URI に移動します。
DESKTOP_CLIENT_ID
は、上記で作成した [デスクトップ アプリ] のクライアント ID です。https://accounts.google.com/o/oauth2/v2/auth?client_id=DESKTOP_CLIENT_ID&response_type=code&scope=openid%20email&access_type=offline&redirect_uri=http://localhost:4444&cred_ref=true
-
ローカル サーバーの出力で、リクエスト パラメータを探します。次のようになります。
GET /?code=$CODE&scope=email%20openid%20https://www.googleapis.com/auth/userinfo.email&hd=google.com&prompt=consent HTTP/1.1
コードをコピーし、以下のAUTH_CODE
を上記で作成したデスクトップ アプリのクライアント ID とシークレットに置き換えます。IAP_CLIENT_ID
は、アプリケーションへのアクセスに使用するメイン クライアント ID です。curl --verbose \ --data client_id=DESKTOP_CLIENT_ID \ --data client_secret=DESKTOP_CLIENT_SECRET \ --data code=AUTH_CODE \ --data audience=IAP_CLIENT_ID \ --data redirect_uri=http://localhost:4444 \ --data grant_type=authorization_code \ https://oauth2.googleapis.com/token
このコードは、アプリケーションにアクセスするために使用できる
id_token
フィールドを含む JSON オブジェクトを返します。
アプリケーションへのアクセス
アプリにアクセスするには、次のように id_token
を使用します。
curl --verbose --header 'Authorization: Bearer ID_TOKEN' URL
トークンを更新
ログインフロー中に生成された更新トークンを使用して、新しい ID トークンを取得できます。これは、元の ID トークンが期限切れになった際に役立ちます。各 ID トークンは約 1 時間有効です。その間、特定のアプリに対して複数のリクエストを行うことができます。
次の curl を使用する例では、更新トークンを使用して新しい ID トークンを取得します。次の例では、REFRESH_TOKEN
はログインフローで生成したトークンです。IAP_CLIENT_ID
、DESKTOP_CLIENT_ID
、DESKTOP_CLIENT_SECRET
は、ログインフローで使用されるものと同じです。
curl --verbose \ --data client_id=DESKTOP_CLIENT_ID \ --data client_secret=DESKTOP_CLIENT_SECRET \ --data refresh_token=REFRESH_TOKEN \ --data grant_type=refresh_token \ --data audience=IAP_CLIENT_ID \ https://oauth2.googleapis.com/token
このコードは、アプリにアクセスするために使用できる新しい id_token
フィールドを含む JSON オブジェクトを返します。
サービス アカウントからの認証
OpenID Connect(OIDC)トークンを使用して、IAP で保護されたリソースに対してサービス アカウントを認証します。以下の手順に沿って、クライアント ID を確認します。
- IAP ページに移動します。
アクセスするリソースを見つけて、> [OAuth 構成に移動] をクリックします。
表示されるページで、クライアント ID をメモします。 バックエンド サービスのクライアント ID を変更するには、
gcloud compute backend-services update
コマンドを使用します。gcloud compute backend-services update BACKEND_SERVICE_NAME \ --iap='enabled,oauth2-client-id=OAUTH_CLIENT_ID,oauth2-client-secret=OAUTH_CLIENT_SECRET'
以下を置き換えます。
BACKEND_SERVICE_NAME
: バックエンド サービス アカウントの名前。-
OAUTH_CLIENT_ID
: 新しい OAuth クライアント ID。 -
OAUTH_CLIENT_SECRET
: 新しい OAuth クライアント シークレット。
また、IAP で保護されたプロジェクトのアクセスリストにサービス アカウントを追加する必要もあります。次のコードサンプルは、OIDC トークンを取得する方法を示しています。いずれのオプションを選択する場合でも、IAP で保護されたリソースに認証済みリクエストを送信するには、Authorization: Bearer
ヘッダーにトークンを含めます。
デフォルトのサービス アカウント用に OIDC トークンを取得する
Compute Engine、App Engine、Cloud Run のデフォルトのサービス アカウント用 OIDC トークンを取得する場合は、以下のコードサンプルを使用してアクセス トークンを生成し、IAP で保護されたリソースにアクセスします。
C#
Go
IAP への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。
Java
Node.js
PHP
IAP への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。
Python
IAP への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。
Ruby
IAP への認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。
ローカルのサービス アカウント キー ファイルから OIDC トークンを取得する
サービス アカウント キー ファイルがある場合は、上記のサンプルコードでサービス アカウント キー ファイルを指定できます。
Bash
#!/usr/bin/env bash
set -euo pipefail
get_token() {
# Get the bearer token in exchange for the service account credentials.
local service_account_key_file_path="${1}"
local iap_client_id="${2}"
local iam_scope="https://www.googleapis.com/auth/iam"
local oauth_token_uri="https://www.googleapis.com/oauth2/v4/token"
local private_key_id="$(cat "${service_account_key_file_path}" | jq -r '.private_key_id')"
local client_email="$(cat "${service_account_key_file_path}" | jq -r '.client_email')"
local private_key="$(cat "${service_account_key_file_path}" | jq -r '.private_key')"
local issued_at="$(date +%s)"
local expires_at="$((issued_at + 3600))"
local header="{'alg':'RS256','typ':'JWT','kid':'${private_key_id}'}"
local header_base64="$(echo "${header}" | base64)"
local payload="{'iss':'${client_email}','aud':'${oauth_token_uri}','exp':${expires_at},'iat':${issued_at},'sub':'${client_email}','target_audience':'${iap_client_id}'}"
local payload_base64="$(echo "${payload}" | base64)"
local signature_base64="$(printf %s "${header_base64}.${payload_base64}" | openssl dgst -binary -sha256 -sign <(printf '%s\n' "${private_key}") | base64)"
local assertion="${header_base64}.${payload_base64}.${signature_base64}"
local token_payload="$(curl -s \
--data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer" \
--data-urlencode "assertion=${assertion}" \
https://www.googleapis.com/oauth2/v4/token)"
local bearer_id_token="$(echo "${token_payload}" | jq -r '.id_token')"
echo "${bearer_id_token}"
}
main(){
# TODO: Replace the following variables:
SERVICE_ACCOUNT_KEY="service_account_key_file_path"
IAP_CLIENT_ID="iap_client_id"
URL="application_url"
# Obtain the ID token.
ID_TOKEN=$(get_token "${SERVICE_ACCOUNT_KEY}" "${IAP_CLIENT_ID}")
# Access the application with the ID token.
curl --header "Authorization: Bearer ${ID_TOKEN}" "${URL}"
}
main "$@"
OIDC トークンを取得するほかのケース
上記以外の場合は、IAP で保護されたリソースにアクセスする直前に IAM 認証情報 API を使用し、ターゲット サービス アカウントになりすまして OIDC トークンを生成します。このプロセスには、次のステップが含まれます。
呼び出し側のサービス アカウント(ID トークンを取得するコードに関連付けられたサービス アカウント)に、サービス アカウントの OpenID Connect ID トークン作成者ロール(
roles/iam.serviceAccountOpenIdTokenCreator
)を付与します。これにより、呼び出し元のサービス アカウントが、ターゲット サービス アカウントの権限を借用できるようになります。
呼び出し側のサービス アカウントが提供する認証情報を使用して、ターゲット サービス アカウントの generateIdToken メソッドを呼び出します。
audience
フィールドにクライアント ID を設定します。
手順については、ID トークンを作成するをご覧ください。
Proxy-Authorization ヘッダーからの認証
アプリケーションが Authorization
リクエスト ヘッダーを占有する場合は、代わりに Proxy-Authorization: Bearer
ヘッダーに ID トークンを含めることができます。有効な ID トークンが Proxy-Authorization
ヘッダーで見つかった場合、IAP はそのトークンを使用してリクエストを承認します。リクエストを承認すると、IAP はコンテンツを処理せずに Authorization
ヘッダーをアプリケーションに渡します。
Proxy-Authorization
ヘッダーに有効な ID トークンが見つからない場合、IAP は Authorization
ヘッダーの処理を続行し、Proxy-Authorization
ヘッダーを削除してから、リクエストをアプリケーションに渡します。
次のステップ
- Authorization: Bearer トークンの詳細を確認する。
- Android 用のログインまたは iOS 用のログインを試す。