从Java调用Google Cloud Run [英] Invoke a Google Cloud Run from java

查看:71
本文介绍了从Java调用Google Cloud Run的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从外部应用程序调用Cloud Run.外部应用程序用Kotlin(java)编写,并在JDK 11 JVM上运行.它使用服务帐户进行身份验证

I want to invoke a Cloud Run from an external application. The external application is written in Kotlin (java) and run on the JDK 11 JVM. It authenticates using a service account

ServiceAccountCredentials.fromStream(serviceAccount).createScoped("https://www.googleapis.com/auth/cloud-platform")

其中服务帐户是有效的JSON文件.我已经测试了在Google云控制台内调用服务帐户运行的云的权限.

where the service account is is a valid JSON file. I have tested the permissions to invoke a cloud run for the service account inside the google cloud console.

我还没有找到官方的API,所以我使用了Google的GoogleNetHttpTransport来运行HTTP发布请求.为了调用云运行,我尝试使用 HttpCredentialsAdapter

I have not found an official API so I used google's GoogleNetHttpTransport to run an HTTP post request. To invoke the cloud run I have tried to use the HttpCredentialsAdapter

transport.createRequestFactory(HttpCredentialsAdapter(googleCredentials))
   .buildPostRequest(GenericUrl(url), JsonHttpContent(JacksonFactory(), data))

我尝试直接使用访问令牌

val headers = HttpHeaders()
googleCredentials.refreshIfExpired()
headers.authorization = "Bearer " + googleCredentials.accessToken.tokenValue
postRequest.headers = headers

而且我尝试使用喷气机服务帐户并使用 jwt请求元数据

And I have tried to use a jet service account and use the jwt request metadata

val headers = HttpHeaders()
jwtCredentials = ServiceAccountJwtAccessCredentials.fromStream(serviceAccount)
jwtCredentials.getRequestMetadata(URI(url)).forEach {
    headers.set(it.key, it.value)
}
postRequest.headers = headers

在所有这些情况下,它都会返回此错误

In all these cases it returns this error

[20:35:00 WARN]: Exception in thread "TestThread" com.google.api.client.http.HttpResponseException: 401 Unauthorized
[20:35:00 WARN]:    at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1113)
[20:35:00 WARN]:    at ***.CloudRun$invoke$3.invokeSuspend(CloudRun.kt:34)
[20:35:00 WARN]:    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
[20:35:00 WARN]:    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
[20:35:00 WARN]:    at java.base/java.lang.Thread.run(Thread.java:834)

感谢您的提前支持

推荐答案

我花了一些时间在OAuth2 Java库上,问题出在下面.类 ServiceAccountCredentials 添加一个 AccessToken 作为授权,而类 ServiceAccountJwtAccessCredentials 添加一个自签名 identity令牌.

I spent time on the OAuth2 Java library and the problem is the following. The class ServiceAccountCredentials add an AccessToken as authorization, and the class ServiceAccountJwtAccessCredentials add a self-signed identity token.

我会更深入地介绍它,但是现在您可以手动设置标题

I will go deeper into it, but for now you can set the header manually

        String myUri = "https://.....";

        Credentials credentials =  ServiceAccountCredentials
                .fromStream(resourceLoader.getResource("classpath:./key.json")
                        .getInputStream()).createScoped("https://www.googleapis.com/auth/cloud-platform");

        String token = ((IdTokenProvider)credentials).idTokenWithAudience(myUri, Collections.EMPTY_LIST).getTokenValue();

        HttpRequestFactory factory = new NetHttpTransport().createRequestFactory();
        HttpRequest request = factory.buildGetRequest(new GenericUrl(myUri));
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization","Bearer " + token);
        request.setHeaders(headers);
        HttpResponse httpResponse = request.execute();
        System.out.println(CharStreams.toString(new InputStreamReader(httpResponse.getContent(), Charsets.UTF_8)));

片段在这里,但不能一起工作.

The pieces are here, but not work together.

编辑

在GitHub上进行了一些交流之后,谷歌为我提供了解决方案.现在,将自动为标头提供一个经过签名的ID令牌

After some exchange on GitHub, a Google provide me the solution. Now the header is automatically provisioned with a signed id Token

        Credentials credentials =  ServiceAccountCredentials
                .fromStream(resourceLoader.getResource("classpath:./key.json")
                        .getInputStream()).createScoped("https://www.googleapis.com/auth/cloud-platform");


        IdTokenCredentials idTokenCredentials = IdTokenCredentials.newBuilder()
                .setIdTokenProvider((ServiceAccountCredentials)credentials)
                .setTargetAudience(myUri).build();

        HttpRequestFactory factory = new NetHttpTransport().createRequestFactory(new HttpCredentialsAdapter(idTokenCredentials));
        HttpRequest request = factory.buildGetRequest(new GenericUrl(myUri));
        HttpResponse httpResponse = request.execute();
        System.out.println(CharStreams.toString(new InputStreamReader(httpResponse.getContent(), Charsets.UTF_8)));

这篇关于从Java调用Google Cloud Run的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆