【发布时间】:2021-11-23 05:16:31
【问题描述】:
目标:
我已经建立了一个谷歌 API 网关。 API 的后端是一个云函数(用 python 编写)。云功能应从 Google BigQuery (BQ) 查询数据。为此,我想创建一个 BQ 客户端 (google.cloud.bigquery.Client())。 API 应该由使用不同服务帐户的不同应用程序访问。服务帐户有权访问我项目中的特定数据集。因此,服务帐户/应用程序应该仅能够查询他们有权查询的数据集。因此,云函数中的 BQ Client 应使用向 API 发送请求的服务帐户进行初始化。
我尝试了什么:
API 使用以下 OpenAPI 定义进行保护,因此需要由服务帐户 SA-EMAIL 签名的 JWT 才能在那里发送请求:
securityDefinitions:
sec-def1:
authorizationUrl: ""
flow: "implicit"
type: "oauth2"
x-google-issuer: "SA-EMAIL"
x-google-jwks_uri: "https://www.googleapis.com/robot/v1/metadata/x509/SA-EMAIL"
x-google-audiences: "SERVICE"
对于使用我的云功能的路径,我使用如下后端配置:
x-google-backend:
address: https://PROJECT-ID.cloudfunctions.net/CLOUD-FUNCTION
path_translation: CONSTANT_ADDRESS
因此,在云函数本身中,我将转发的 JWT 作为 X-Forwarded-Authorization 以及已经验证的 base64url 编码的 JWT 有效负载作为来自 API 网关的 X-Apigateway-Api-Userinfo。
我尝试使用来自X-Forwarded-Authorization 的 JWT 来获取凭据:
bearer_token = request.headers.get('X-Forwarded-Authorization')
token = bearer_token.split(" ")[1]
cred = google.auth.credentials.Credentials(token)
起初,这似乎有效,因为cred.valid 返回True,但是当尝试使用google.cloud.bigquery.Client(credentials=cred) 创建客户端时,它在日志中返回以下错误:
google.auth.exceptions.RefreshError: The credentials do not contain
the necessary fields need to refresh the access token. You must
specify refresh_token, token_uri, client_id, and client_secret.
我对 auth/oauth 没有太多经验,但我认为我没有必要的令牌/属性,错误是说在我的云功能中缺少可用的。
另外,我不确定为什么会有RefreshError,因为我不想刷新令牌(也不要明确这样做)并再次使用它(可能是不好的做法?)。
问题:
是否有可能以我尝试过的方式或任何其他方式实现我的目标?
【问题讨论】:
-
我查看了一些旧代码...我不记得为什么,但我曾经在创建凭据后添加“cred.refresh(requests.Request())”。请求 - 是“来自 google.auth.transport 导入请求”。因此,总而言之:“ tgt_credentials = impersonated_credentials.Credentials( source_credentials=src_credentials, target_principal=, target_scopes=tgt_scopes, life=500) tgt_credentials.refresh(requests.Request()) ”跨度>
标签: python google-cloud-platform google-cloud-functions google-authentication google-api-gateway