首页 > 解决方案 > Cloud Run:服务到服务 401,而 curl 工作

问题描述

这是我这几天一直在想办法解决的问题。

对于我的 Cloud Run 应用程序,服务到服务的通信始终会导致 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)
}

我还尝试向Service account key我的 Cloud Run 服务提供一个并使用返回的令牌google.JWTAccessTokenSourceFromJSON无济于事。

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

Cloud Run 服务帐号和外部服务帐号(用于密钥)都具有roles/run.invokerIAM 绑定。受众是 Cloud Run 发布的服务 URL。

我尝试了以下方法:

似乎没有任何效果。在 Cloud Run 中运行的每个请求都返回 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)

我很感激任何答案。

谢谢!

标签: google-cloud-run

解决方案


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


推荐阅读