本页面介绍了如何从用户帐号或服务帐号向受 Identity-Aware Proxy (IAP) 保护的资源进行身份验证。
用户帐号属于个别用户。当您的应用需要代表用户访问受 IAP 保护的资源,则对用户帐号进行身份验证。如需了解详情,请参阅用户帐号。
服务帐号属于应用而非个别用户。 如果要允许应用访问受 IAP 保护的资源,则对服务帐号进行身份验证。如需了解详情,请参阅服务帐号。
准备工作
在开始之前,您需要做好以下准备:
- 要使用开发者帐号、服务帐号或移动应用凭据以编程方式连接并且受 IAP 保护的应用。
对用户帐号进行身份验证
您可以允许用户从桌面应用或移动应用访问您的应用,从而支持程序与受 IAP 保护的资源进行交互。
从移动应用进行身份验证
- 在受 IAP 保护的资源所在的项目中,为您的移动应用创建一个 OAuth 2.0 客户端 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
复制 CODE 以替换下面的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 令牌的有效期约为一小时,在此期间,您可以向特定应用发出多个请求。
以下示例展示了如何使用 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。您可以使用
gcloud compute backend-services update
命令更改后端服务的客户端 ID。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 令牌。无论您选择哪一种方法,您都需要在 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 + 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 令牌
在所有其他情况下,请使用 IAM 凭据 API 生成 OIDC 令牌,方法是在访问受 IAP 保护的资源之前模拟目标服务帐号。此过程涉及以下步骤:
为调用服务帐号(与获取 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 登录。