如何使用 Google 云存储验证我的 Java 应用程序?
How do I authenticate my Java application with Google Cloud Storage?
我正在编写一个 Java 应用程序来与 Google 云存储中的文件进行交互。我找到了 gcloud-java
,我正试图开始工作。
查看他们的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. I'm trying to run 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
很明显我的环境出了点问题,但我该怎么做才能修复它?我想更正我的环境而不是对示例进行更改。
备注:
- 我 运行 在 Windows 10
上使用 Cygwin 2.0.4
- 我不是通过 Maven 构建的,但我假设这不是问题的根源
gcloud auth login
不起作用的原因是 Java 不能很好地与 Cygwin 配合使用,特别是在绝对路径方面。
gcloud
将您的设置和凭据存储在您的 Cygwin 主目录中,~/.config/gcloud
,但 Java 将在您的 [=45= 中查找它们] 主目录通过 System.getProperty("user.home")
。您可以通过 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 ....
请注意,我们不必指定项目,但由于某种原因我们仍未登录。事实证明,演示应用程序在报告身份验证错误方面表现不佳。在 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.
所以现在我们至少有 GOOGLE_APPLICATION_CREDENTIALS
环境变量可以继续。但是为什么 gcloud
不为我们配置东西呢?看起来这实际上是库中的 bug;它现在应该 能够找到我们的登录令牌。
同时,我们也可以通过显式指定凭据路径来解决此问题:
$ 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=...}
成功!
我正在编写一个 Java 应用程序来与 Google 云存储中的文件进行交互。我找到了 gcloud-java
,我正试图开始工作。
查看他们的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. I'm trying to run 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
很明显我的环境出了点问题,但我该怎么做才能修复它?我想更正我的环境而不是对示例进行更改。
备注:
- 我 运行 在 Windows 10 上使用 Cygwin 2.0.4
- 我不是通过 Maven 构建的,但我假设这不是问题的根源
gcloud auth login
不起作用的原因是 Java 不能很好地与 Cygwin 配合使用,特别是在绝对路径方面。
gcloud
将您的设置和凭据存储在您的 Cygwin 主目录中,~/.config/gcloud
,但 Java 将在您的 [=45= 中查找它们] 主目录通过 System.getProperty("user.home")
。您可以通过 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 ....
请注意,我们不必指定项目,但由于某种原因我们仍未登录。事实证明,演示应用程序在报告身份验证错误方面表现不佳。在 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.
所以现在我们至少有 GOOGLE_APPLICATION_CREDENTIALS
环境变量可以继续。但是为什么 gcloud
不为我们配置东西呢?看起来这实际上是库中的 bug;它现在应该 能够找到我们的登录令牌。
同时,我们也可以通过显式指定凭据路径来解决此问题:
$ 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=...}
成功!