使用用户帐户凭据访问私有云运行/云功能 [英] Use user account Credential for reaching private Cloud Run/Cloud Functions

查看:106
本文介绍了使用用户帐户凭据访问私有云运行/云功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的用例.

  • 我已经有一个以私有模式部署的Cloud Run服务. (与Cloud Function相同的问题)
  • 我正在开发使用此Cloud Run的新服务.我在应用程序中使用默认凭据进行身份验证.它可以在Compute Engine和Cloud Run上使用,因为默认证书是从元数据服务器获取的.

但是,在我的本地环境中,我需要使用服务帐户密钥文件来实现此目的. (例如,当我设置GOOGLE_APPLICATION_CREDENTIALS环境变量时)

But, on my local environment, I need to use a service account key file for achieving this. (for example, when I set the GOOGLE_APPLICATION_CREDENTIALS env var)

但是,我无法使用我的用户帐户凭据.

在Java,Node或Go中,日志跟踪非常清晰:无法在用户凭证类型上生成身份令牌.

The log trace are very clear in Java, Node or Go: impossible to generate an identity token on a user credential type.

所以

  • 为什么Google身份验证库不允许这样做?
  • 为什么Google前端仅接受Google签名的身份令牌?
  • 是否存在继续使用用户帐户的解决方法?

还有一段上下文: 我们要避免使用服务帐户密钥文件.今天,这是我们的主要安全漏洞(文件被复制,通过电子邮件发送,甚至在Github上公开提交...). 用户帐户默认凭据可用于所有Google Cloud API,但不能与IAP和CLoud Run/Functions一起使用.

And a piece of context: we want to avoid to use service account key file. Today, it's our major security breach (files are copied, sent by email, even committed on Github publicly...). The user account default credential work with all Google Cloud API but not with IAP and CLoud Run/Functions.

编辑

这里有一些错误示例.

JAVA

我这样做

        Credentials credentials = GoogleCredentials.getApplicationDefault().createScoped("https://www.googleapis.com/auth/cloud-platform");

        IdTokenCredentials idTokenCredentials = IdTokenCredentials.newBuilder()
                .setIdTokenProvider((IdTokenProvider) credentials)
                .setTargetAudience(myUri).build();

        HttpRequestFactory factory = new NetHttpTransport().createRequestFactory(new HttpCredentialsAdapter(idTokenCredentials));

我的用户凭证不符合IdTokenProvider界面

And my user credential is not compliant with IdTokenProvider interface


Caused by: java.lang.ClassCastException: class com.google.auth.oauth2.UserCredentials cannot be cast to class com.google.auth.oauth2.IdTokenProvider (com.google.auth.oauth2.UserCredentials and com.google.auth.oauth2.IdTokenProvider are in unnamed module of loader 'app')

节点

使用节点,此代码可用于服务帐户

With node, this code work with a service account

    const {GoogleAuth} = require('google-auth-library');
    const auth = new GoogleAuth()
    const client = await auth.getIdTokenClient(url);
    const res = await client.request({url});
    console.log(res.data);

但是使用我的用户帐户,我收到了此错误

But with my user account, I got this error

Error: Cannot fetch ID token in this environment, use GCE or set the GOOGLE_APPLICATION_CREDENTIALS environment variable to a service account credentials JSON file.
    at GoogleAuth.getIdTokenClient(....)

推荐答案

gcloud auth activate-service-account --key-file仅适用于您"运行gcloud命令,不会被需要GOOGLE_APPLICATION_CREDENTIALS的应用程序"使用.

gcloud auth activate-service-account --key-file is only for "you" running gcloud commands, it won’t be picked up by "applications" that need GOOGLE_APPLICATION_CREDENTIALS.

从Java调用Google Cloud Run 如何从在Cloud Run/GCP之外?,您要么需要具有Service Account的JSON密钥文件,要么必须在GCE/GKE/Cloud Run/App Engine/GCF实例中运行.

As you can see from Invoke a Google Cloud Run from java or How to call Cloud Run from out side of Cloud Run/GCP?, you either need to have the JSON key file of Service Account, or have to be running inside a GCE/GKE/Cloud Run/App Engine/GCF instance.

要使其在您的本地环境中正常工作,建议您使用gcloud auth application-default login命令登录(此命令的作用就像您在本地设置了GOOGLE_APPLICATION_CREDENTIALS一样).让我知道这是否有效.

For this to work on your local environment, I recommend logging in with gcloud auth application-default login command (this command is meant to work like as if you’ve set GOOGLE_APPLICATION_CREDENTIALS locally). Let me know if this works.

如果这不起作用,则万不得已时,您可以重构代码以在本地工作时从环境变量(如果设置)中获取身份令牌,例如:

If that doesn't work, as a last resort you can refactor your code to pick up identity token from an environment variable (if set) while working locally, such as:

$ export ID_TOKEN="$(gcloud auth print-identity-token -q)"
$ ./your-app

附录

按照Guillaume的要求,此gcloud auth print-identity-token如何与我的个人Google凭据配合使用"?

Appendix

Per Guillaume's request "how does this gcloud auth print-identity-token work with my personal Google credentials"?

方法如下:

  1. gcloud是向Google注册的OAuth客户端,要获取JWT令牌,您需要在GCE/GCF/GKE/GAE/CR环境中工作或拥有OAuth应用.

  1. gcloud is an OAuth client registered to Google, to get a JWT token you either need to work inside a GCE/GCF/GKE/GAE/CR environment OR have an OAuth app.

gcloud发出这样的请求:

POST https://www.googleapis.com/oauth2/v4/token

连身:

grant_type=refresh_token&client_id=REDACTED.apps.googleusercontent.com&client_secret=REDACTED&refresh_token=REDACTED

对于我们来说,最可能的client_idclient_secret值是相同的,因为它们是gcloud的值.但是,它将用新令牌交换您的refresh_token.

Most likely client_id and client_secret values are the same for us because they are gcloud’s. However, it exchanges your refresh_token with a new token.

/token响应将包含一个access_tokenid_token.例如:

The /token response will contain an access_token and id_token. e.g.:

{
"access_token": ".....",
"id_token": "eyJhbG....."
"expires_in": 3599,
"scope": "https://www.googleapis.com/auth/userinfo.email 
https://www.googleapis.com/auth/appengine.admin 
https://www.googleapis.com/auth/compute 
https://www.googleapis.com/auth/cloud-platform 
https://www.googleapis.com/auth/accounts.reauth openid",
"token_type": "Bearer",
}

gcloud这是为您打印身份令牌的方式.

This is how gcloud prints an identity token for you.

如果您对代码如何使用JSON密钥文件感到好奇,将会看到非常相似的内容.例如,在Go中有 http://google.golang.org/api/idtoken 包并且您会看到在那里有类似的实现方式.

If you are curious how does the code do it with a JSON key file, you’ll see something very similar. For example, in Go there's http://google.golang.org/api/idtoken package and you'll see a similar implementation there.

这篇关于使用用户帐户凭据访问私有云运行/云功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆