为什么对 Cloud Functions 的身份验证与 Cloud Endpoints 不同?
Why is authentication to Cloud Functions different than Cloud Endpoints?
为了使用 Cloud Endpoints for OpenAPI 进行身份验证,我必须使用 google-auth 构建一个 Python 请求会话,如下所示:
from google.auth.transport.requests import AuthorizedSession
creds = google.auth.jwt.Credentials.from_service_account_file(
creds_path, audience=my_audience)
session = AuthorizedSession(creds)
但是当我想对 Cloud Functions 进行身份验证时,我必须做一些不同的事情:
creds = google.oauth2.service_account.IDTokenCredentials.from_service_account_file(creds_path, target_audience=function_url)
session = AuthorizedSession(creds)
所有这些都是当我使用服务帐户文件时,例如当 运行 从我的本地计算机或 GKE 上使用时。但是当它在 App Engine 上使用时,还有另一种变体:
调用云端点 -
boostrap_creds, _ = google.auth.default()
creds = google.auth.jwt.Credentials.from_signing_credentials(boostrap_creds, my_audience)
session = AuthorizedSession(creds)
调用云函数--
IAM_SCOPE = 'https://www.googleapis.com/auth/iam'
OAUTH_TOKEN_URI = 'https://www.googleapis.com/oauth2/v4/token'
bootstrap_credentials, _ = google.auth.default(scopes=[IAM_SCOPE])
signer_email = bootstrap_credentials.service_account_email
signer = bootstrap_credentials.signer
creds = google.oauth2.service_account.IDTokenCredentials(
signer, signer_email, token_uri=OAUTH_TOKEN_URI, target_audience=function_url)
session = AuthorizedSession(creds)
为什么会有差异,这意味着什么?
在 Cloud Endpoints 中,当您使用:google.auth.jwt.Credentials
对用户进行身份验证时,客户端应用程序会在授权中发送 JSON Web 令牌 (JWT) header对后端的 HTTP 请求 API。令牌有两个组成部分,public 和私有字符串。私有字符串在签署请求时使用,并且永远不会通过网络发送。可扩展服务代理 (ESP) 验证您 API 的令牌,因此您无需在 API 中添加任何代码来处理身份验证。这些访问令牌并不旨在携带有关用户的信息。它们只允许访问某些已定义的服务器资源。端点使用纯 OAuth 2.
在 Cloud Function 中使用时:google.oauth2.service_account.IDTokenCredentials
使用 oAuth2 ID 令牌进行身份验证。 ID 令牌是由 OpenID 提供商授予的令牌,其中包含有关 End-User 的信息,在这种情况下是关于服务帐户的。此信息告诉客户端应用程序用户已通过身份验证,还可以提供用户名等信息。
您可以在客户端的不同组件周围传递 ID 令牌,这些组件可以使用 ID 令牌来确认用户已通过身份验证并检索有关它们的信息。 Functions 使用更高级的 OpenID Connect。
如果您想了解更多关于 OAuth 的信息:
为了使用 Cloud Endpoints for OpenAPI 进行身份验证,我必须使用 google-auth 构建一个 Python 请求会话,如下所示:
from google.auth.transport.requests import AuthorizedSession
creds = google.auth.jwt.Credentials.from_service_account_file(
creds_path, audience=my_audience)
session = AuthorizedSession(creds)
但是当我想对 Cloud Functions 进行身份验证时,我必须做一些不同的事情:
creds = google.oauth2.service_account.IDTokenCredentials.from_service_account_file(creds_path, target_audience=function_url)
session = AuthorizedSession(creds)
所有这些都是当我使用服务帐户文件时,例如当 运行 从我的本地计算机或 GKE 上使用时。但是当它在 App Engine 上使用时,还有另一种变体:
调用云端点 -
boostrap_creds, _ = google.auth.default()
creds = google.auth.jwt.Credentials.from_signing_credentials(boostrap_creds, my_audience)
session = AuthorizedSession(creds)
调用云函数--
IAM_SCOPE = 'https://www.googleapis.com/auth/iam'
OAUTH_TOKEN_URI = 'https://www.googleapis.com/oauth2/v4/token'
bootstrap_credentials, _ = google.auth.default(scopes=[IAM_SCOPE])
signer_email = bootstrap_credentials.service_account_email
signer = bootstrap_credentials.signer
creds = google.oauth2.service_account.IDTokenCredentials(
signer, signer_email, token_uri=OAUTH_TOKEN_URI, target_audience=function_url)
session = AuthorizedSession(creds)
为什么会有差异,这意味着什么?
在 Cloud Endpoints 中,当您使用:
google.auth.jwt.Credentials
对用户进行身份验证时,客户端应用程序会在授权中发送 JSON Web 令牌 (JWT) header对后端的 HTTP 请求 API。令牌有两个组成部分,public 和私有字符串。私有字符串在签署请求时使用,并且永远不会通过网络发送。可扩展服务代理 (ESP) 验证您 API 的令牌,因此您无需在 API 中添加任何代码来处理身份验证。这些访问令牌并不旨在携带有关用户的信息。它们只允许访问某些已定义的服务器资源。端点使用纯 OAuth 2.在 Cloud Function 中使用时:
google.oauth2.service_account.IDTokenCredentials
使用 oAuth2 ID 令牌进行身份验证。 ID 令牌是由 OpenID 提供商授予的令牌,其中包含有关 End-User 的信息,在这种情况下是关于服务帐户的。此信息告诉客户端应用程序用户已通过身份验证,还可以提供用户名等信息。 您可以在客户端的不同组件周围传递 ID 令牌,这些组件可以使用 ID 令牌来确认用户已通过身份验证并检索有关它们的信息。 Functions 使用更高级的 OpenID Connect。
如果您想了解更多关于 OAuth 的信息: