【问题标题】:GCP: "Invalid JWT Signature" when using Service Account JSONGCP:使用服务帐户 JSON 时出现“无效的 JWT 签名”
【发布时间】:2021-01-16 00:12:17
【问题描述】:

我正在使用 Google 的 gRPC 库来访问我的 GCP 域中的数据。 我的代码使用服务帐户 JSON 密钥执行身份验证。 它运行了大约一个月,直到最近我开始在尝试执行的任何操作时收到以下错误:

{"error":"invalid_grant","error_description":"Invalid JWT Signature."}

我应该注意到身份验证过程的执行没有错误,服务对象的创建也是如此(参见下面的 Java 代码示例)。当我尝试执行任何数据访问操作时抛出错误,例如下面示例中的 listSecrets 方法。

在网上搜索这个问题,我发现主要是指向系统时间/时区错误的答案;但是,我电脑上的日期、时间和时区是完全准确的。 有什么建议吗?

我的 Java 代码示例:

String projectId = "my-project";
GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream("C:\\Users\\elisha.l\\Downloads\\co-club-project-01-3588a3330456.json"));
SecretManagerServiceClient client = SecretManagerServiceClient.create();
ProjectName parent = ProjectName.of(projectId);
ListSecretsPagedResponse response = client.listSecrets(parent);

错误的堆栈跟踪:

Exception in thread "main" com.google.api.gax.rpc.UnavailableException: io.grpc.StatusRuntimeException: UNAVAILABLE: Credentials failed to obtain metadata
    at com.google.api.gax.rpc.ApiExceptionFactory.createException(ApiExceptionFactory.java:69)
    at com.google.api.gax.grpc.GrpcApiExceptionFactory.create(GrpcApiExceptionFactory.java:72)
    at com.google.api.gax.grpc.GrpcApiExceptionFactory.create(GrpcApiExceptionFactory.java:60)
    at com.google.api.gax.grpc.GrpcExceptionCallable$ExceptionTransformingFuture.onFailure(GrpcExceptionCallable.java:97)
    at com.google.api.core.ApiFutures$1.onFailure(ApiFutures.java:68)
    at com.google.common.util.concurrent.Futures$CallbackListener.run(Futures.java:1050)
    at com.google.common.util.concurrent.DirectExecutor.execute(DirectExecutor.java:30)
    at com.google.common.util.concurrent.AbstractFuture.executeListener(AbstractFuture.java:1176)
    at com.google.common.util.concurrent.AbstractFuture.complete(AbstractFuture.java:969)
    at com.google.common.util.concurrent.AbstractFuture.setException(AbstractFuture.java:760)
    at io.grpc.stub.ClientCalls$GrpcFuture.setException(ClientCalls.java:563)
    at io.grpc.stub.ClientCalls$UnaryStreamToFuture.onClose(ClientCalls.java:533)
    at io.grpc.internal.ClientCallImpl.closeObserver(ClientCallImpl.java:434)
    at io.grpc.internal.ClientCallImpl.access$500(ClientCallImpl.java:66)
    at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInternal(ClientCallImpl.java:763)
    at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInContext(ClientCallImpl.java:742)
    at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37)
    at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:123)
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(Unknown Source)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
    Suppressed: com.google.api.gax.rpc.AsyncTaskException: Asynchronous task failed
        at com.google.api.gax.rpc.ApiExceptions.callAndTranslateApiException(ApiExceptions.java:57)
        at com.google.api.gax.rpc.UnaryCallable.call(UnaryCallable.java:112)
        at com.google.cloud.secretmanager.v1.SecretManagerServiceClient.listSecrets(SecretManagerServiceClient.java:245)
        at com.google.cloud.secretmanager.v1.SecretManagerServiceClient.listSecrets(SecretManagerServiceClient.java:196)
        at google.Secret.main(Secret.java:26)
Caused by: io.grpc.StatusRuntimeException: UNAVAILABLE: Credentials failed to obtain metadata
    at io.grpc.Status.asRuntimeException(Status.java:533)
    ... 14 more
Caused by: java.io.IOException: Error getting access token for service account: 400 Bad Request
POST https://oauth2.googleapis.com/token
{"error":"invalid_grant","error_description":"Invalid JWT Signature."}
    at com.google.auth.oauth2.ServiceAccountCredentials.refreshAccessToken(ServiceAccountCredentials.java:444)
    at com.google.auth.oauth2.OAuth2Credentials.refresh(OAuth2Credentials.java:157)
    at com.google.auth.oauth2.OAuth2Credentials.getRequestMetadata(OAuth2Credentials.java:145)
    at com.google.auth.oauth2.ServiceAccountCredentials.getRequestMetadata(ServiceAccountCredentials.java:603)
    at com.google.auth.Credentials.blockingGetToCallback(Credentials.java:112)
    at com.google.auth.Credentials$1.run(Credentials.java:98)
    ... 7 more
Caused by: com.google.api.client.http.HttpResponseException: 400 Bad Request
POST https://oauth2.googleapis.com/token
{"error":"invalid_grant","error_description":"Invalid JWT Signature."}
    at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1113)
    at com.google.auth.oauth2.ServiceAccountCredentials.refreshAccessToken(ServiceAccountCredentials.java:441)
    ... 12 more

【问题讨论】:

  • 要查找常见问题,您能否提供上次看到错误时的时间戳和时区?
  • @MrTech,当然。一分钟前:2020-10-01T11:36:36.224+03:00[Asia/Jerusalem]
  • 当时我没能找到一个常见的问题,但能够找到这个帖子,里面有很多东西可以尝试。 stackoverflow.com/questions/42651549/…
  • 我收到此错误是因为我的系统时间运行得很快。

标签: java google-cloud-platform


【解决方案1】:

我应该注意到身份验证过程的执行没有错误,服务对象的创建也是如此(参见下面的 Java 代码示例)。当我尝试执行任何数据访问操作时抛出错误,例如下面示例中的 listSecrets 方法。

我认为您是说 GoogleCredentials 和 SecretManagerServiceClient 对象的实例化不会引发任何异常。但在您调用客户端对象上的方法(如listServices)之前,这些实际上不会验证您的凭据。 (如果我误解了,请让我知道 SecretManagerServiceClient 上的 一些 方法实际上正确验证并成功)。

您的服务帐户 JSON 密钥似乎存在一些问题,因此我将首先确定它是否与 Java 代码分开工作。您可以按照https://cloud.google.com/service-usage/docs/getting-started#test 的说明使用 oauth2l 从您的服务帐户获取不记名令牌,然后通过 curl 使用此不记名令牌直接调用秘密管理器 API,如 https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets 所示。比如:

curl "https://secretmanager.googleapis.com/v1/projects/project-id/secrets?secretId=secret-id" \
    --request "POST" \
    --header "authorization: Bearer <bearer token from oauth2l>" \
    --header "content-type: application/json" \
    --header "x-goog-user-project: project-id" \
    --data "{\"replication\": {\"automatic\": {}}}"

如果这有效而 Java 代码无效,那么您可能希望通过在 https://github.com/googleapis/java-secretmanager 存储库上提交问题来继续。

上述所有方法的替代方案:创建一个新的服务帐户并查看它是否有效,而不是准确调试当前帐户的问题可能更快。

【讨论】:

  • 感谢您的回复。创建一个新的服务帐户并没有解决问题;但是,直接调用 API 可以正常工作。该问题并非 Secret Manager API 独有;我在使用其他 Google Compute Engine 和 Security Manager API 时也遇到了同样的问题。
  • 我会向 java-secretmanager 存储库或 github.com/googleapis/google-auth-library-java 提出问题。
猜你喜欢
  • 2020-09-01
  • 2021-10-03
  • 1970-01-01
  • 1970-01-01
  • 2021-12-06
  • 1970-01-01
  • 2021-12-01
  • 2022-10-18
  • 1970-01-01
相关资源
最近更新 更多