本页面介绍如何从用户帐号或服务帐号向受 Identity-Aware Proxy (IAP) 保护的资源进行身份验证。
用户账号属于个别用户。当您的应用需要代表用户访问受 IAP 保护的资源,则对用户账号进行身份验证。如需了解详情,请参阅用户帐号。
服务账号属于应用而非个别用户。 如果要允许应用访问受 IAP 保护的资源,则对服务账号进行身份验证。如需了解详情,请参阅服务帐号。
准备工作
在开始之前,您需要做好以下准备:
- 一个受 IAP 保护的应用,您希望使用开发者帐号、服务帐号或移动应用凭据以编程方式连接到该应用。
对用户账号进行身份验证
您可以允许用户从桌面应用或移动应用访问您的应用,从而允许程序与受 IAP 保护的资源进行交互。
从移动应用进行身份验证
- 为您的移动应用创建或使用现有的 OAuth 2.0 客户端 ID。如要使用现有的 OAuth 2.0 客户端 ID,请按照如何共享 OAuth 客户端中的步骤操作。
- 将用于以编程方式访问应用的 OAuth 客户端 ID 列入许可名单。
- 获取受 IAP 保护的客户端 ID 的 ID 令牌。
- Android:使用 Google Sign-In API 请求 OpenID Connect (OIDC) 令牌。将
requestIdToken
客户端 ID 设置为您要连接的资源的客户端 ID。 - iOS:使用 Google 登录获取 ID 令牌。
- Android:使用 Google Sign-In API 请求 OpenID Connect (OIDC) 令牌。将
- 在
Authorization: Bearer
标头中包含 ID 令牌以向受 IAP 保护的资源发出经过身份验证的请求。
从桌面应用进行身份验证
本部分介绍如何使用桌面命令行对用户账号进行身份验证。
- 要允许开发者通过命令行访问您的应用,请创建一个桌面 OAuth 2.0 客户端 ID 或共享一个现有的桌面 OAuth 客户端 ID。
- 将用于以编程方式访问应用的 OAuth 客户端 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 和密钥:curl --verbose \ --data client_id=DESKTOP_CLIENT_ID \ --data client_secret=DESKTOP_CLIENT_SECRET \ --data code=AUTH_CODE \ --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 令牌的有效期约为一小时,在此期间,您可以向特定应用发出多个请求。
以下示例使用 curl,使用刷新令牌来获取新的 ID 令牌。在以下示例中,REFRESH_TOKEN
是登录流程中的令牌。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 \ https://oauth2.googleapis.com/token
此代码会返回一个带有新 id_token
字段的 JSON 对象,您可以使用该字段来访问应用。
从服务账号进行身份验证
使用 OpenID Connect (OIDC) 令牌向受 IAP 保护的资源验证服务帐号的身份。
- 创建或使用现有的 OAuth 2.0 客户端 ID。如要使用现有的 OAuth 2.0 客户端 ID,请按照如何共享 OAuth 客户端中的步骤操作。
- 将用于以编程方式访问应用的 OAuth 客户端 ID 列入许可名单。
您还需要将服务账号添加到受 IAP 保护的项目的访问列表中。以下代码示例显示了如何获取 OIDC 令牌。您必须在 Authorization: Bearer
标头中添加令牌,才能向受 IAP 保护的资源发出身份验证请求。
获取默认服务账号的 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 + 600))"
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 令牌的代码相关联的服务帐号)提供 Service Account OpenID Connect Identity Token Creator 角色 (
roles/iam.serviceAccountOpenIdTokenCreator
)。这使调用服务帐号能够模拟目标服务帐号。
使用调用服务帐号提供的凭据对目标服务帐号调用 generateIdToken 方法。
将
audience
字段设置为您的客户端 ID。
如需查看分步说明,请参阅创建 ID 令牌。
从 Proxy-Authorization 标头进行身份验证
如果您的应用使用 Authorization
请求标头,您可以改为在 Proxy-Authorization: Bearer
标头中包含 ID 令牌。如果在 Proxy-Authorization
标头中找到了有效的 ID 令牌,则 IAP 会用它授权请求。授权请求后,IAP 会将 Authorization
标头传递给您的应用,而不处理内容。
如果在 Proxy-Authorization
标头中未找到有效的 ID 令牌,则 IAP 会继续处理 Authorization
标头并在将请求传递给应用之前去除 Proxy-Authorization
标头。
后续步骤
- 详细了解 Authorization: Bearer 令牌。
- 尝试 Android 登录或 iOS 登录。