首页 > 解决方案 > 使用 Cloud Run 进行内部 CLI 的 Google Cloud 身份验证

问题描述

我们使用 Cloud Run 构建了多项服务。我们的目标是构建一个内部 CLI,允许我们的开发人员调用这些服务。我们无法生成id_token与位于 Cloud Run 服务前面的 Identity Aware Proxy 一起使用的问题。

根据文档,调用 Cloud Run 服务可以通过使用gcloudgcloud auth print-identity-token命令来完成。这很好用。这也避免了下载服务帐户凭据并将其传递给我们的开发人员,因为此方法利用了您的应用程序默认凭据。

我们已经尝试实现一些东西来print-identity-token在 Go 中复制这个功能,但没有成功。生成的id_token返回 401 给我们所有的 Cloud Run API。生成令牌的示例代码:

func GetIDToken() string {
    ctx := context.Background()
    tokenSource, err := google.DefaultTokenSource(ctx, "openid", "email")

    if err != nil {
        log.Fatal(err)
    }

    token, err := tokenSource.Token()

    if err != nil {
        log.Fatal(err)
    }

    return fmt.Sprintf("%v", token.Extra("id_token"))
}

这将返回一个id_token但它不适用于 API。根据文档,范围似乎是正确的。

这给我们留下了两个问题:

  1. 这是为 IAP 生成 Id 令牌的正确方法吗?
  2. 有没有更好的方法来为我们的开发人员实现对这些内部 API 的身份验证?

标签: gogoogle-cloud-platformgcloudopenid-connectgoogle-cloud-run

解决方案


目前尚不清楚您为什么要尝试重新实现gcloud auth print-identity-token. 我强烈建议您不要尝试这样做。

gcloud如果您正在构建开发人员 CLI,如果您在开发机器中出现并调用此命令以检索 id_token ,您的工作会容易得多。

重新实现print-identity-token确实很困难。因为gcloud使用内部存储的 OAuth 令牌端点调用 OAuth 令牌端点以refresh_token获取. (运行命令以查看更多信息,并将相关的 gcloud 配置设置为不编辑来自 req/resp 正文的令牌。)id_tokenaccess_token--log-http

或者,如果没有gcloud在开发人员机器上使用 GSuite 帐户进行身份验证,您唯一的其他选择是将IAM 服务帐户密钥分发到每台开发人员机器。(另一方面,您需要确保这些密钥正确旋转并保持安全。)

您可以使用 IAM 服务帐户密钥https://www.googleapis.com/oauth2/v4/token通过适当的字段(如 client_secret、grant_type 等)进行 POST 以获得id_token. 我相信最简单的方法是将GOOGLE_APPLICATION_CREDENTIALSGo 程序中的 env 变量设置为密钥文件,audience在令牌交换请求中指定正确的参数,然后照常使用token.Extra("id_token")

另外:我还注意到您的身份字段在您的示例代码中未设置为 Cloud Run 服务的 URL。


推荐阅读