如果推送订阅使用身份验证,则 Pub/Sub 服务会签署 JWT 并在推送请求的授权标头中发送 JWT。JWT 包含声明和签名。
订阅者可以验证 JWT 并验证以下内容:
- 声明准确无误。
- Pub/Sub 服务签署了声明。
如果订阅者使用防火墙,则无法接收推送请求。要接收推送请求,您必须关闭防火墙并验证 JWT。
准备工作
JWT 格式
JWT 是一个 OpenIDConnect JWT,包含标头、声明集和签名三个部分。Pub/Sub 服务将 JWT 编码为具有英文句点分隔符的 base64 字符串。
例如,以下授权标头包含已编码的 JWT:
"Authorization" : "Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjdkNjgwZDhjNzBkNDRlOTQ3MTMzY2JkNDk5ZWJjMWE2MWMzZDVh YmMiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJodHRwczovL2V4YW1wbGUuY29tIiwiYXpwIjoiMTEzNzc0M jY0NDYzMDM4MzIxOTY0IiwiZW1haWwiOiJnYWUtZ2NwQGFwcHNwb3QuZ3NlcnZpY2VhY2NvdW50LmNvb SIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJleHAiOjE1NTAxODU5MzUsImlhdCI6MTU1MDE4MjMzNSwia XNzIjoiaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tIiwic3ViIjoiMTEzNzc0MjY0NDYzMDM4MzIxO TY0In0.QVjyqpmadTyDZmlX2u3jWd1kJ68YkdwsRZDo-QxSPbxjug4ucLBwAs2QePrcgZ6hhkvdc4UHY 4YF3fz9g7XHULNVIzX5xh02qXEH8dK6PgGndIWcZQzjSYfgO-q-R2oo2hNM5HBBsQN4ARtGK_acG-NGG WM3CQfahbEjZPAJe_B8M7HfIu_G5jOLZCw2EUcGo8BvEwGcLWB2WqEgRM0-xt5-UPzoa3-FpSPG7DHk7 z9zRUeq6eB__ldb-2o4RciJmjVwHgnYqn3VvlX9oVKEgXpNFhKuYA-mWh5o7BCwhujSMmFoBOh6mbIXF cyf5UiVqKjpqEbqPGo_AvKvIQ9VTQ"
标头和声明集是 JSON 字符串。解码后,它们将采用以下格式:
{"alg":"RS256","kid":"7d680d8c70d44e947133cbd499ebc1a61c3d5abc","typ":"JWT"} { "aud":"https://example.com", "azp":"113774264463038321964", "email":"gae-gcp@appspot.gserviceaccount.com", "sub":"113774264463038321964", "email_verified":true, "exp":1550185935, "iat":1550182335, "iss":"https://accounts.google.com" }
附加到发送到推送端点的请求的令牌可具有最长达一个小时的生命周期。
为推送身份验证配置 Pub/Sub
以下示例展示了如何将推送身份验证服务账号设置为您选择的服务账号,以及如何向 service-{PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com
服务代理授予 iam.serviceAccountTokenCreator
角色。
控制台
gcloud
# Configure the push subscription gcloud pubsub subscriptions (create|update|modify-push-config) ${SUBSCRIPTION} \ --topic=${TOPIC} \ --push-endpoint=${PUSH_ENDPOINT_URI} \ --push-auth-service-account=${SERVICE_ACCOUNT_EMAIL} \ --push-auth-token-audience=${OPTIONAL_AUDIENCE_OVERRIDE} # Your service agent # `service-{PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com` needs to have the # `iam.serviceAccountTokenCreator` role. PUBSUB_SERVICE_ACCOUNT="service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com" gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:${PUBSUB_SERVICE_ACCOUNT}"\ --role='roles/iam.serviceAccountTokenCreator'
为推送通知订阅启用身份验证时,您可能会遇到 permission denied
或 not authorized
错误。如需解决此问题,请向发起订阅创建或更新的主账号授予对服务账号的 iam.serviceAccounts.actAs
权限。如需了解详情,请参阅“创建推送订阅”中的身份验证。
如果您将经过身份验证的推送订阅与使用 Identity-Aware Proxy 进行保护的 App Engine 应用搭配使用,则必须提供 IAP 客户端 ID 作为推送身份验证令牌的受众群体。如需在 App Engine 应用上启用 IAP,请参阅启用 IAP。如需查找 IAP 客户端 ID,请在凭据页面上查找 IAP-App-Engine-app
客户端 ID。
声明
JWT 可用于验证由 Google 签名的声明(包括 email
和 aud
声明)。如需详细了解 Google 的 OAuth 2.0 API 如何用于身份验证和授权,请参阅 OpenID Connect。
可通过两种机制使声明变得有意义。首先,Pub/Sub 要求发出 CreateSubscription、UpdateSubscription 或 ModifyPushConfig 调用的用户或服务账号对推送身份验证服务账号具有 iam.serviceAccounts.actAs
权限的角色。roles/iam.serviceAccountUser
角色就是此类角色的一个示例。
其次,严格控制对用于为令牌签名的证书的访问。 如需创建令牌,Pub/Sub 必须使用单独的签名服务账号身份(即服务代理 service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com
)调用内部 Google 服务。此签名服务账号必须对推送身份验证服务账号(或推送身份验证服务账号的任何祖先资源,例如项目)拥有 iam.serviceAccounts.getOpenIdToken
权限或 Service Account Token Creator 角色 (roles/iam.serviceAccountTokenCreator
)。
验证令牌
验证 Pub/Sub 发送到推送端点的令牌涉及:
- 通过使用签名验证检查令牌完整性。
- 确保令牌中的 email 和 audience 声明与推送订阅配置中设置的值匹配。
以下示例展示了如何对发送到未使用 Identity-Aware Proxy 保护的 App Engine 应用的推送请求进行身份验证。如果您的 App Engine 应用使用 IAP 进行保护,则包含 IAP JWT 的 HTTP 请求标头为 x-goog-iap-jwt-assertion
,并且必须进行相应的验证。
协议
请求:
GET https://oauth2.googleapis.com/tokeninfo?id_token={BEARER_TOKEN}
响应:
200 OK
{ "alg": "RS256", "aud": "example.com", "azp": "104176025330667568672", "email": "{SERVICE_ACCOUNT_NAME}@{YOUR_PROJECT_NAME}.iam.gserviceaccount.com", "email_verified": "true", "exp": "1555463097", "iat": "1555459497", "iss": "https://accounts.google.com", "kid": "3782d3f0bc89008d9d2c01730f765cfb19d3b70e", "sub": "104176025330667568672", "typ": "JWT" }
C#
在尝试此示例之前,请按照《快速入门:使用客户端库》中的 C# 设置说明进行操作。 如需了解详情,请参阅 Pub/Sub C# API 参考文档。
Go
Java
Node.js
Python
Ruby
如需了解上述代码示例中使用的环境变量 PUBSUB_VERIFICATION_TOKEN
,请参阅编写和响应 Pub/Sub 消息。
可在面向网站的 Google 登录指南中找到其他有关如何验证不记名 JWT 的示例。如需详细了解 OpenID 令牌,请参阅 OpenID Connect 指南,包括有助于验证 JWT 的客户端库列表。
通过其他 Google Cloud 服务进行身份验证
Cloud Run、App Engine 和 Cloud Run 函数通过验证 Pub/Sub 生成的令牌来对来自 Pub/Sub 的 HTTP 调用进行身份验证。您所需的唯一配置是向调用者账号授予必要的 IAM 角色。
如需了解这些服务的不同使用场景,请参阅以下指南和教程:
Cloud Run
- 通过 Pub/Sub 推送触发:您的推送身份验证服务账号必须具有
roles/run.invoker
角色,并且绑定到 Cloud Run 服务才能调用相应的 Cloud Run 服务 - 教程:将 Pub/Sub 与 Cloud Run 搭配使用
App Engine
Cloud Run functions
- HTTP 触发器:如果您打算将 Pub/Sub 推送请求用作函数的 HTTP 触发器,则您的推送身份验证服务账号必须具有
roles/cloudfunctions.invoker
角色才能调用函数 - Google Cloud Pub/Sub 触发器:如果您使用 Pub/Sub 触发器调用函数,系统会自动配置 IAM 角色和权限