根据以下指南在与自定义端点一起使用时获取StatusRuntimeException: UNAUTHENTICATED
:Google Vision API-多区域支持
但当使用默认端点时,一切都很好。请参阅下面的代码示例:
Credentials credentials = ServiceAccountCredentials.fromStream(new FileInputStream(credPath));
// Works fine
ImageAnnotatorSettings settings = ImageAnnotatorSettings.newBuilder().setCredentialsProvider(FixedCredentialsProvider.create(credentials)).build();
// Works fine as well
ImageAnnotatorSettings settings = ImageAnnotatorSettings.newBuilder().setCredentialsProvider(FixedCredentialsProvider.create(credentials)).setEndpoint("vision.googleapis.com:443").build();
// Doesn't work - throws exception:
ImageAnnotatorSettings settings = ImageAnnotatorSettings.newBuilder().setCredentialsProvider(FixedCredentialsProvider.create(credentials)).setEndpoint("us-vision.googleapis.com:443").build();
visionClient = ImageAnnotatorClient.create(settings);
例外情况如下:
com.google.api.gax.rpc.UnauthenticatedException: io.grpc.StatusRuntimeException: UNAUTHENTICATED: Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.
at com.google.api.gax.rpc.ApiExceptionFactory.createException(ApiExceptionFactory.java:73)
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:1074)
at com.google.common.util.concurrent.DirectExecutor.execute(DirectExecutor.java:30)
at com.google.common.util.concurrent.AbstractFuture.executeListener(AbstractFuture.java:1213)
at com.google.common.util.concurrent.AbstractFuture.complete(AbstractFuture.java:983)
at com.google.common.util.concurrent.AbstractFuture.setException(AbstractFuture.java:771)
at io.grpc.stub.ClientCalls$GrpcFuture.setException(ClientCalls.java:563)
at io.grpc.stub.ClientCalls$UnaryStreamToFuture.onClose(ClientCalls.java:533)
at io.grpc.internal.DelayedClientCall$DelayedListener$3.run(DelayedClientCall.java:463)
at io.grpc.internal.DelayedClientCall$DelayedListener.delayOrExecute(DelayedClientCall.java:427)
at io.grpc.internal.DelayedClientCall$DelayedListener.onClose(DelayedClientCall.java:460)
at io.grpc.internal.ClientCallImpl.closeObserver(ClientCallImpl.java:557)
at io.grpc.internal.ClientCallImpl.access$300(ClientCallImpl.java:69)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInternal(ClientCallImpl.java:738)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInContext(ClientCallImpl.java:717)
at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37)
at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:133)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:829)
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.vision.v1.ImageAnnotatorClient.batchAnnotateImages(ImageAnnotatorClient.java:203)
at com.google.cloud.vision.v1.ImageAnnotatorClient.batchAnnotateImages(ImageAnnotatorClient.java:179)
...
at com.sun.ejb.containers.EjbAsyncTask.call(EjbAsyncTask.java:101)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
... 3 more
Caused by: io.grpc.StatusRuntimeException: UNAUTHENTICATED: Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.
at io.grpc.Status.asRuntimeException(Status.java:535)
... 13 more
有什么想法吗?谢谢
为了防止它对某人有所帮助,我遇到了这个问题:Google DocumentAI Java示例在io.grpc.StatusRuntimeException中失败:INVALID_ARGUMENT:请求包含无效参数,然后我用这种方式解决了这里描述的同一问题:
- 我尝试了文档中提供的原始身份验证方式:
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/my/key.json
- 它使用这种身份验证方法,但当我手动添加凭据时,它就停止了工作:
.setCredentialsProvider(FixedCredentialsProvider.create(credentials))
- 我决定使用settingsBuilder.getCredentialsProvider来记录这两个凭据,似乎自动凭据自动设置了一个自定义作用域"https://www.googleapis.com/auth/cloud-platform"在生成的key.kson文件中没有指示(作用域数组为空(。在谷歌文档中,并没有指出我们在通过InputStream进行身份验证时必须添加它https://github.com/googleapis/google-cloud-java#authentication截至今日:
.setCredentials(ServiceAccountCredentials.fromStream(new FileInputStream("/path/to/my/key.json")))
- 所以我写了以下代码:
Credentials credentials =
ServiceAccountCredentials
.fromStream(credentialStream)
.createScoped("https://www.googleapis.com/auth/cloud-platform")
它成功了!如果你编辑key.json文件在数组中添加作用域,它也可以工作,我还没有测试过
这两个问题都源于Java库中缺乏文档,所以如果谷歌的人阅读了这个答案,请完成文档。