云运行:curl工作时服务到服务401



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

对于我的云运行应用程序,服务对服务的通信总是导致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 Run服务提供Service account key,并使用从google.JWTAccessTokenSourceFromJSON返回的令牌,但没有成功。

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

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

我尝试过以下几种:

  • 使用元数据服务进行令牌检索(Cloud Run中的401,但在cURL和Postman中使用令牌时有效(
  • 使用JWTAccessTokenSourceFromJSON进行令牌检索(Cloud Run中的401,但在cURL和Postman中使用令牌时有效(
  • 尝试在使用已颁发的令牌之前添加延迟(以防令牌未传播(
  • 尝试在延迟后使用给定令牌手动ping云运行服务几次(使用http.Client(

似乎什么都不起作用。在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)

我很感激你的回答。

谢谢!

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

最新更新