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.com
和service-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.com
向service-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-one
向service-two
进行身份验证有什么想法吗?
【问题讨论】:
可以执行这个命令吗:gcloud beta run services get-iam-policy <service-two>
(把service-2换成真名)?还有这个命令gcloud iam service-accounts get-iam-policy <service-one@myproject.iam.gserviceaccount.com>
(同样有正确的替换)?最后一个问题,您使用自定义域吗?
所以我觉得自己像个傻瓜,@guillaumeblaquiere 你的评论让我找到了答案。我正在使用自定义域。它确实在文档中说不支持自定义域。在为云运行生成的 url 切换我的自定义域后,服务一能够成功地向服务二发出请求。
乐于助人 :-)
【参考方案1】:
答案是使用 gcp 云运行生成的 Url 作为 OIDC 令牌请求中的受众。与 jwt 中的“aud”字段相关。
我发现云运行中的服务到服务身份验证不支持自定义域 (myDomain.com)。我正在使用我的自定义域。
(我觉得自己像个白痴)谢谢@guillaumeblaquiere
【讨论】:
正确,生成身份令牌的audience
参数目前不支持自定义域。以上是关于Google Cloud Run 身份验证服务到服务的主要内容,如果未能解决你的问题,请参考以下文章
Cloud Scheduler 调用 Cloud Run 服务的身份验证
如何从Java脚本安全地调用Google Cloud Run服务?
如何对 GCP Cloud Run 上的联合 GraphQL 服务进行身份验证?