google-cloud-platform - 使用用户帐户凭据访问私有(private) Cloud Run/Cloud Functions

标签 google-cloud-platform google-cloud-functions google-cloud-run google-iam

这是我的用例。

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

  • 但是,在我的本地环境中,我需要使用服务帐户 key 文件来实现这一点。 (例如,当我设置 GOOGLE_APPLICATION_CREDENTIALS 环境变量时)

    然而,我无法使用我的用户帐户凭据。

    Java、Node 或 Go 中的日志跟踪非常清楚:不可能在用户凭据类型上生成身份 token 。

    所以,
  • 为什么 google auth 库不允许这样做?
  • 为什么 Google 前端只接受 Google 签名的身份 token ?
  • 是否存在继续使用用户帐户的解决方法?

  • 还有一段上下文:我们要避免使用服务帐户 key 文件。今天,这是我们的主要安全漏洞(文件被复制、通过电子邮件发送,甚至在 Github 上公开提交......)。
    用户帐户默认凭据适用于所有 Google Cloud API,但不适用于 IAP 和 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界面
    
    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')
    

    节点

    使用节点,此代码与服务帐户一起使用
        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);
    

    但是使用我的用户帐户,我收到此错误
    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 .

    正如您从 Invoke a Google Cloud Run from java 中看到的或 How to call Cloud Run from out side of Cloud Run/GCP? ,您需要拥有服务帐户的 JSON key 文件,或者必须在 GCE/GKE/Cloud Run/App Engine/GCF 实例中运行。

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

    如果这不起作用,作为最后的手段,您可以重构代码以在本地工作时从环境变量(如果设置)中获取身份 token ,例如:

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

    附录

    根据纪尧姆的要求“此 gcloud auth print-identity-token 如何与我的个人 Google 凭据配合使用”?

    就是这样:
  • gcloud是注册到 Google 的 OAuth 客户端,要获得 JWT token ,您需要在 GCE/GCF/GKE/GAE/CR 环境中工作或拥有 OAuth 应用程序。
  • gcloud发出这样的请求:
    POST https://www.googleapis.com/oauth2/v4/token
    

    与 body :
    grant_type=refresh_token&client_id=REDACTED.apps.googleusercontent.com&client_secret=REDACTED&refresh_token=REDACTED
    

    最有可能 client_idclient_secret值对我们来说是相同的,因为它们是 gcloud 的。但是,它交换了您的 refresh_token用一个新的 token 。
  • /token响应将包含 access_tokenid_token .例如。:
    {
    "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为您打印身份 token 。

    如果您对代码如何使用 JSON key 文件感到好奇,您会看到非常相似的内容。例如,在 Go 中有 http://google.golang.org/api/idtoken包,你会看到一个 similar implementation there .

    关于google-cloud-platform - 使用用户帐户凭据访问私有(private) Cloud Run/Cloud Functions,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61754530/

    相关文章:

    python - 如何在本地使用 gcloud Python API

    java - Google Cloud Datastore 删除给定键的命名空间内的所有实体

    部署函数时 Firebase CLI 不起作用。错误 : HTTP Error: 404, 找不到方法

    google-cloud-platform - Cloud Run 无法发出出站 https) 请求 - 超时

    google-cloud-platform - 有谁知道cloud run是否支持http/2流媒体而不支持http1.1流媒体?

    google-app-engine - Google App Engine 源代码未与 Bitbucket 同步

    java - 如何获取存储在 google-cloud-storage 存储桶子目录中的图像的 URL

    firebase - Cloud Functions for Firebase 可以在用户登录时执行吗?

    node.js - Angular/Ionic 处理成功 200 作为错误

    docker - 如何请求由Go运行在Cloud Run上的gRPC服务器