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

时间:2019-11-03 18:31:56

标签: google-cloud-platform google-oauth google-authentication google-cloud-run google-iam

我在GCP Cloud Run上部署了两个服务(API)。分别命名为service-one.myDomain.comservice-two.myDomain.com。我希望在调用服务2时对服务一进行身份验证,而与任何用户正在执行的操作无关。

我已阅读并实现了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

OAuth令牌:

service-one.myDomain.com中,我调用元数据服务器以从以下URL获取OAuth令牌(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未经授权,我的日志显示响应标头包括:

{'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所缺少的任何想法?

2 个答案:

答案 0 :(得分:1)

您在Google Cloud中的错误(HTTP 401)通常表示您的令牌格式无效/损坏/格式错误。

错误消息显示“无法验证访问令牌”,从而确认了这一假设。此消息表示令牌签名无效。

您显示的令牌似乎有效。 kid用于当前的Google公共签名证书,您可以在https://www.googleapis.com/oauth2/v1/certs

中找到该证书。

令牌的主体也是正确的,具有正确的听众,等等。

这留下了一个问题,在接收令牌和发送令牌之间,您可能破坏了令牌或不发送接收到的令牌。

[更新]

我从评论中注意到,最终的解决方案是使用正确的DNS终结点。使用错误的DNS名称将阻止授权(自定义域名)。

答案 1 :(得分:1)

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

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

(我觉得自己很傻)@guillaumeblaquiere