【问题标题】:Generate bearer token for google cloud function - Java为谷歌云功能生成不记名令牌 - Java
【发布时间】:2022-08-05 21:30:55
【问题描述】:

我正在尝试从 java 连接到云功能,例如 https://us-west1-<>.cloudfunctions.net,并且我正在尝试使用如下代码为该功能生成不记名令牌:

String audience = https://<projectname>-<region>-<projectid>.cloudfunctions.net/<myFunction>;

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

IdTokenCredentials tokenCredential =
                IdTokenCredentials.newBuilder()
                    .setIdTokenProvider((IdTokenProvider) credentials)
                    .setTargetAudience(audience)
                    .build();
        
tokenCredential.refresh();
        
String token = tokenCredential.getIdToken().getTokenValue();

当我运行应用程序时,会生成令牌。但是如果我把令牌放在邮递员身上,服务器会返回 401 错误:401未经授权.

如果我在 GCP 云 shell 终端中使用 GCP 命令“gcloud auth print-identity-token”并在邮递员中使用此令牌,则云函数调用成功。

用于获取凭证的 Json 文件类似于:

{
  \"type\": \"service_account\",
  \"project_id\": \"<project_id>\",
  \"private_key_id\": \"<private_key_id>\",
  \"private_key\": \"-----BEGIN PRIVATE KEY----------END PRIVATE KEY-----\\n\",
  \"client_email\": \"aaa@<project_id>.iam.gserviceaccount.com\",
  \"client_id\": \"<client_id>\",
  \"auth_uri\": \"https://accounts.google.com/o/oauth2/auth\",
  \"token_uri\": \"https://oauth2.googleapis.com/token\",
  \"auth_provider_x509_cert_url\": \"https://www.googleapis.com/oauth2/v1/certs\",
  \"client_x509_cert_url\": \"https://www.googleapis.com/robot/v1/metadata/x509/<principle>\"
}

请帮助我弄清楚如何在 Java 中生成不记名令牌以调用谷歌云功能。

谢谢

  • 使用 gcloud auth print...,您可以使用专用于 GCLOUD CLI 的 gcloud auth login 凭据。当您使用代码时,您使用 ADC:GOOGLE_APPLICATION_CREDENTIALS env var(如果已设置)或命令的凭据gcloud auth application-default login。检查您的凭据,然后重试。
  • 谢谢@guillaumeblaquiere 的建议。我的问题是由于我为观众使用的值不正确。当我给出正确的受众价值时,它就修复了。请参阅我的回答,了解我给出的受众价值。

标签: google-cloud-functions serverless


【解决方案1】:

当我使用正确的受众值时,这个问题得到了解决,如下所示。

https://功能网址/projects/项目编号/locations/地区/functions/函数名

在上述 URI 中,将 function-url、project-id、region 和 function-name 替换为您的值。

以下是工作代码。

public String getAccessToken(String audience) throws IOException {
        
        InputStream resource = new ClassPathResource(
                  "gcp/service-account.json").getInputStream();
        
        GoogleCredentials credentials = GoogleCredentials
                 .fromStream(resource)
                 .createScoped(Arrays.asList("https://www.googleapis.com/auth/cloud-platform"));
        
        credentials.refreshAccessToken();
        
        IdTokenCredentials tokenCredential =
                IdTokenCredentials.newBuilder()
                    .setIdTokenProvider((IdTokenProvider) credentials)
                    .setTargetAudience(audience)
                    .build();
                
        tokenCredential.refresh();
        
        return tokenCredential.getIdToken().getTokenValue();
      }

在上面的代码中,

  1. “gcp/service-account.json”是我的服务帐户 json 文件的路径。它位于我的 spring-boot 项目中的 src/main/resources 文件夹(即类路径)下。
  2. 可能不需要credentials.refreshAccessToken();tokenCredential.refresh();。我没有尝试删除这些。有时间会试试。

    希望对大家有帮助!!由于我在“受众”价值上找不到太多帮助,所以我花了一些时间通过反复试验找出正确的价值。

【讨论】:

  • 如果我没有 src 主要资源下的文件并且我使用 GOOGLE_APPLICATION_CREDENTIALS ,你将如何加载它?它也像这样使用:spring.cloud.gcp.credentials.location: file:${GOOGLE_APPLICATION_CREDENTIALS}
  • @TiagoMedici,然后使用下面的代码加载。 GoogleCredentials credentials = GoogleCredentials .getApplicationDefault() .createScoped(Arrays.asList("https://www.googleapis.com/auth/cloud-platform"));
  • 我正在使用服务帐户调用 Firebase 云功能,它会抛出:Firebase ID 令牌具有不正确的“aud”(观众)声明,请确保 ID 令牌来自与用于验证此 SDK 的服务帐户相同的 Firebase 项目。看起来我需要与 IdTokenCredentials 不同的 firebase 令牌
  • 我不确定这对你有什么作用。这看起来像它只生成一个刷新令牌而不是一个访问令牌?
猜你喜欢
  • 2016-07-29
  • 2021-11-05
  • 2013-06-15
  • 1970-01-01
  • 2017-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-21
相关资源
最近更新 更多