Cloud Run-通过服务帐户进行gRPC身份验证-Java

时间:2020-06-09 21:46:03

标签: authentication grpc service-accounts google-cloud-run grpc-java

我已将一台gRPC服务器部署到Google Cloud Run(完全托管),并将“必需的身份验证”选项设置为true。

我正在尝试通过Google服务帐户对来自gRPC客户端的调用进行身份验证,但是我总是遇到异常。

Exception in thread "main" io.grpc.StatusRuntimeException: UNAUTHENTICATED: HTTP status code 401

下面是我创建gRPC频道并附加服务帐户的方式。

public GrpcClient(Channel channel) throws IOException {
    Credentials credentials = GoogleCredentials.getApplicationDefault();

    blockingStub = CalculatorServiceGrpc
            .newBlockingStub(channel)
            .withCallCredentials(MoreCallCredentials.from(credentials));
}

不好意思:env var GOOGLE_APPLICATION_CREDENTIALS设置了SA的路径,并且该SA具有Cloud Run Invoker特权

有什么我想念的吗?

2 个答案:

答案 0 :(得分:1)

从通用HTTP客户端调用Cloud Run服务器时,设置GOOGLE_APPLICATION_CREDENTIALS无效。 (仅在您使用Google客户端库调用Google API时有效。

即使将gRPC部署到Cloud Run,它也只是HTTP / 2,因此在Service-to-Service Authentication页上记录了对Cloud Run服务的身份验证。简而言之,这涉及到:

  • 从容器内的元数据服务端点获取JWT(身份令牌)
  • 将其设置为对Cloud Run应用程序的请求中的标头,如Authorization: Bearer [[ID_TOKEN]]

在gRPC中,标头称为“元数据”,因此您应该找到等效的gRPC Java方法进行设置。 (这可能是每个RPC选项。)

阅读有关Go example here的内容,它基本上向您说明,在Cloud Run上运行的gRPC服务器仍以相同的方式进行身份验证。在这种情况下,还要确保告诉Java:

  • 您需要连接到域:443(不是:80)
  • gRPC Java需要使用计算机根CA证书来验证Cloud Run提供的TLS证书的有效性(与跳过TLS验证相反)

答案 1 :(得分:1)

经过更多研究,我能够使用IdTokenCredentials对请求进行身份验证。参见下面的结果。

public GrpcClient(Channel channel) throws IOException {
    ServiceAccountCredentials saCreds = ServiceAccountCredentials
            .fromStream(new FileInputStream("path\to\sa"));

    IdTokenCredentials tokenCredential = IdTokenCredentials.newBuilder().setIdTokenProvider(saCreds)
            .setTargetAudience("https://{projectId}-{hash}-uc.a.run.app").build();

    blockingStub = CalculatorServiceGrpc
            .newBlockingStub(channel)
            .withCallCredentials(MoreCallCredentials.from(tokenCredential));
}