云 运行:服务到服务 401,而 curl 工作

Cloud Run: Service-to-Service 401 while curl works

这是我几天来一直在努力解决的问题。

我的云 运行 应用程序的服务到服务通信总是导致 401。

对于服务中的令牌检索,我一直在使用以下代码片段:

tokenURL := fmt.Sprintf("/instance/service-accounts/default/identity?audience=%s", c.serviceURL)

var err error
token, err = metadata.Get(tokenURL)
if err != nil {
    return nil, fmt.Errorf("metadata.Get: failed to query id_token: %+v", err)
}

我也曾尝试向我的 Cloud 运行 服务提供 Service account key,但使用从 google.JWTAccessTokenSourceFromJSON 返回的令牌无济于事。

问题是返回的 JWT 在从 cURL 使用时确实有效,但在云 运行 上的 运行 服务中使用时无效。

云 运行 服务帐户和外部服务帐户(用于密钥)都具有 roles/run.invoker IAM 绑定。而观众是云运行发布的服务URL.

我尝试了以下方法:

似乎没有任何效果。 Cloud 运行 中 运行 时的每个请求都返回 401,并且日志显示 The request was not authorized to invoke this service. Read more at https://cloud.google.com/run/docs/securing/authenticating。使用 cURL 或 Postman 时,我可以访问该服务。

我试过这些方法来调用服务:

tokenURL := fmt.Sprintf("/instance/service-accounts/default/identity?audience=%s", c.serviceURL)

var err error
token, err := metadata.Get(tokenURL)
if err != nil {
    return nil, fmt.Errorf("metadata.Get: failed to query id_token: %+v", err)
}

// First one (ping)
req, _ := http.NewRequest("GET", "{{serviceURL}}", nil)
req.Header.Set("Authorization", "Bearer: "+token)
l, _ := cr.Do(req)
m, _ := ioutil.ReadAll(l.Body)
logrus.Println(l.Header)
logrus.Println(string(m))

// RoundTripper
r.Header.Set("Authorization", "Bearer: "+token)
return c.r.RoundTrip(r)

感谢您的回答。

谢谢!

在发布代码示例时,我刚刚意识到我在 Bearer 之后添加了一个额外的冒号 (:),这使得此请求失败。不敢相信我花了几天时间来解决这个问题!