[英]How do I authenticate my Java application with Google Cloud Storage?
I am writing a Java application to interact with files in Google Cloud Storage. 我正在编写一个Java应用程序以与Google Cloud Storage中的文件进行交互。 I found
gcloud-java
which I'm trying to get working. 我找到了要尝试工作的
gcloud-java
。
Looking at their examples it seems I should be able to simply run them after having logged-in with gcloud
, but it doesn't seem to be working. 查看他们的示例 ,看来我应该能够在使用
gcloud
登录后简单地运行它们,但是似乎没有用。 I'm trying to run StorageExample
, which says " logged-in project will be used if not supplied ", but despite logging in I cannot access my project whether I specify it or not. 我正在尝试运行
StorageExample
,它说“ 如果未提供 , 将使用登录的项目 ”,但是尽管登录,但无论是否指定,我都无法访问我的项目。
$ gcloud auth login
Your browser has been opened to visit:
https://accounts.google.com/o/oauth2/auth?....
Saved Application Default Credentials.
You are now logged in as [...].
Your current project is [...]. You can change this setting by running:
$ gcloud config set project PROJECT_ID
$ java -cp GCloudDemo.jar com.google.gcloud.examples.storage.StorageExample list
Exception in thread "main" java.lang.IllegalArgumentException: A project ID is required for this service but could not be determined from the builder or the environment. Please set a project ID using the builder.
at com.google.common.base.Preconditions.checkArgument(Preconditions.java:122)
at com.google.gcloud.ServiceOptions.<init>(ServiceOptions.java:317)
...
at com.google.gcloud.examples.storage.StorageExample.main(StorageExample.java:566)
$ java -cp GCloudDemo.jar com.google.gcloud.examples.storage.StorageExample ... list
Exception in thread "main" com.google.gcloud.storage.StorageException: Login Required
at com.google.gcloud.spi.DefaultStorageRpc.translate(DefaultStorageRpc.java:94)
at com.google.gcloud.spi.DefaultStorageRpc.list(DefaultStorageRpc.java:148)
...
at com.google.gcloud.examples.storage.StorageExample$ListAction.run(StorageExample.java:1)
at com.google.gcloud.examples.storage.StorageExample.main(StorageExample.java:579)
Caused by: com.google.api.client.googleapis.json.GoogleJsonResponseException: 401 Unauthorized
{
"code" : 401,
"errors" : [ {
"domain" : "global",
"location" : "Authorization",
"locationType" : "header",
"message" : "Login Required",
"reason" : "required"
} ],
"message" : "Login Required"
}
at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:145)
...
at com.google.gcloud.spi.DefaultStorageRpc.list(DefaultStorageRpc.java:138)
... 10 more
Clearly something is wrong with my environment, but what do I have to do to fix it? 显然,我的环境有问题,但是我应该怎么做才能解决? I'd like to correct my environment rather than make changes to the example.
我想更正我的环境,而不是更改示例。
Notes: 笔记:
The reason gcloud auth login
isn't working is because Java doesn't play well with Cygwin, specifically with regards to absolute paths. gcloud auth login
无法正常工作的原因是因为Java在Cygwin中的表现不佳,特别是在绝对路径方面。
gcloud
stores your settings and credentials in your Cygwin home directory, ~/.config/gcloud
, but Java is going to look for them in your Windows home directory via System.getProperty("user.home")
. gcloud
将您的设置和凭据存储在Cygwin主目录~/.config/gcloud
,但是Java会通过System.getProperty("user.home")
在Windows主目录中查找它们。 You can specify where the application should look for this directory via the CLOUDSDK_CONFIG
environment variable, like so (be sure to only specify it when calling java
; setting it for your shell will in turn break gcloud
): 您可以通过
CLOUDSDK_CONFIG
环境变量指定应用程序在哪里寻找该目录,如下所示(确保仅在调用java
时指定它;为您的shell设置它反而会破坏gcloud
):
$ CLOUDSDK_CONFIG=$(cygpath -w ~/.config/gcloud) \
java -cp GCloudDemo.jar com.google.gcloud.examples.storage.StorageExample list
Exception in thread "main" com.google.gcloud.storage.StorageException: Login Required
at ....
Notice that that we didn't have to specify a project, but we're still not logged in for some reason. 请注意,我们不必指定项目,但由于某些原因我们仍未登录。 It turns out the demo app doesn't do a great job of reporting authentication errors.
事实证明,演示应用程序在报告身份验证错误方面做得不好。 Adding an explicit call to
AuthCredentials.createApplicationDefaults()
at the start of the main()
method reports a much more helpful error message: 在
main()
方法的开头添加对AuthCredentials.createApplicationDefaults()
的显式调用会报告一条更有用的错误消息:
Exception in thread "main" java.io.IOException: The Application Default Credentials are not available. They are available if running in Google Compute Engine. Otherwise, the environment variable GOOGLE_APPLICATION_CREDENTIALS must be defined pointing to a file defining the credentials. See https://developers.google.com/accounts/docs/application-default-credentials for more information.
So now we at least have the GOOGLE_APPLICATION_CREDENTIALS
environment variable to go on. 因此,现在至少要有
GOOGLE_APPLICATION_CREDENTIALS
环境变量。 But why isn't gcloud
configuring things for us? 但是,为什么
gcloud
不为我们配置东西? It looks like that's actually a bug in the library; 看起来这实际上是库中的错误 ; it should now be able to find our login token.
现在,它应该能够找到我们的登录令牌。
In the meantime, we can workaround it by explicitly specifying the credentials path as well: 同时,我们也可以通过显式指定凭据路径来解决此问题:
$ CLOUDSDK_CONFIG=$(cygpath -w ~/.config/gcloud) \
GOOGLE_APPLICATION_CREDENTIALS=$(cygpath -w ~/.config/gcloud)/application_default_credentials.json \
java -cp GCloudDemo.jar com.google.gcloud.examples.storage.StorageExample list
Bucket{name=...}
Success! 成功!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.