Google Cloud Run 身份验证服务到服务

Posted

技术标签:

【中文标题】Google Cloud Run 身份验证服务到服务【英文标题】:Google Cloud Run Authentication Service-to-Service 【发布时间】:2020-02-29 04:12:49 【问题描述】:

我在 GCP Cloud Run 上部署了两个服务 (API)。打电话给他们service-one.myDomain.comservice-two.myDomain.com。我希望在调用服务二时对服务一进行身份验证,而与任何用户的操作无关。

我已阅读并实施了 GCP Cloud Run 文档中关于身份验证服务到服务 (https://cloud.google.com/run/docs/authenticating/service-to-service) 的说明,但 service-one.myDomain.com 未能成功调用 service-two.myDomain.com 并收到 401:Unauthorized 响应。

关于如何让service-one 成功调用service-two 有什么想法吗?

这是我的设置:

IAM 和服务帐号:

在 google IAM 上,我创建了两个服务帐户并授予它们“Cloud Run Invoker”(roles/run.invoker) 角色: service-one@myproject.iam.gserviceaccount.com service-two@myproject.iam.gserviceaccount.com

在 Cloud Run 中,我将服务帐户从“默认计算服务帐户”更改为我创建的服务帐户。我将service-one@myproject.iam.gserviceaccount.com 分配给service-one.myDomain.com,将service-two@myproject.iam.gserviceaccount.com 分配给service-two.myDomain.com

OIDC 认证令牌:

service-one.myDomain.com 中,我调用元数据服务器以从以下 url 获取令牌 (jwt): http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience=https://service-two.myDomain.com 请求标头设置为'Metadata-Flavor': 'Google' 请求成功,我收到的令牌被解码为具有以下负载:


  "alg": "RS256",
  "kid": "9cef5340642b157fa8a4f0d874fe7543872d82db",
  "typ": "JWT"



  "aud": "https://service-two.mydomain.com",
  "azp": "100959068407876085761",
  "email": "service-one@myproject.iam.gserviceaccount.com",
  "email_verified": true,
  "exp": 1572806540,
  "iat": 1572802940,
  "iss": "https://accounts.google.com",
  "sub": "100953168404568085761"

Http请求:

我使用令牌从service-one.myDomain.comservice-two.myDomain.com 上的http 端点发出请求。我使用'Authorization': 'Bearer token' 设置请求标头(token 是令牌的值)。

Http 响应:

响应是 401 Unauthorized,我的日志显示要包含的响应标头:

'WWW-Authenticate': 'Bearer error="invalid_token" error_description="The access token could not be verified"'

内容为:

"
<html><head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>401 Unauthorized</title>
</head>
<body text=#000000 bgcolor=#ffffff>
<h1>Error: Unauthorized</h1>
<h2>Your client does not have permission to the requested URL <code>/health</code>.</h2>
<h2></h2>
</body></html>
" 

我很难过......关于我缺少什么让service-oneservice-two 进行身份验证有什么想法吗?

【问题讨论】:

可以执行这个命令吗:gcloud beta run services get-iam-policy &lt;service-two&gt;(把service-2换成真名)?还有这个命令gcloud iam service-accounts get-iam-policy &lt;service-one@myproject.iam.gserviceaccount.com&gt;(同样有正确的替换)?最后一个问题,您使用自定义域吗? 所以我觉得自己像个傻瓜,@guillaumeblaquiere 你的评论让我找到了答案。我正在使用自定义域。它确实在文档中说不支持自定义域。在为云运行生成的 url 切换我的自定义域后,服务一能够成功地向服务二发出请求。 乐于助人 :-) 【参考方案1】:

答案是使用 gcp 云运行生成的 Url 作为 OIDC 令牌请求中的受众。与 jwt 中的“aud”字段相关。

我发现云运行中的服务到服务身份验证不支持自定义域 (myDomain.com)。我正在使用我的自定义域。

(我觉得自己像个白痴)谢谢@guillaumeblaquiere

【讨论】:

正确,生成身份令牌的audience参数目前不支持自定义域。

以上是关于Google Cloud Run 身份验证服务到服务的主要内容,如果未能解决你的问题,请参考以下文章

Google Cloud Run 最终用户身份验证

Cloud Scheduler 调用 Cloud Run 服务的身份验证

如何从Java脚本安全地调用Google Cloud Run服务?

如何对 GCP Cloud Run 上的联合 GraphQL 服务进行身份验证?

谷歌玩游戏服务。为啥选择 Google Cloud 进行身份验证?

使用 Postman 的服务帐户对 Google Cloud Storage JSON API 进行身份验证