为Google Cloud Storage API提供凭据

我正在尝试组建一个用于测试Google云端存储的hello world程序。 我的目标是拥有一个最简单的程序,只需将硬编码文件上传到云存储。

我一直在互联网上搜索基础教程,但我能找到的最接近的是从App Engine使用云存储的指南 。 我把这个程序放在一起:

import java.io.FileInputStream; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.Arrays; import com.google.cloud.storage.Acl; import com.google.cloud.storage.Acl.Role; import com.google.cloud.storage.Acl.User; import com.google.cloud.storage.BlobInfo; import com.google.cloud.storage.Storage; import com.google.cloud.storage.StorageOptions; public class Main { public static void main(String[] args) throws FileNotFoundException{ FileInputStream fileInputStream = new FileInputStream("my-file.txt"); Storage storage = StorageOptions.getDefaultInstance().getService(); BlobInfo blobInfo = storage.create( BlobInfo .newBuilder("my-cloud-storage-bucket", "my-file.txt") .setAcl(new ArrayList(Arrays.asList(Acl.of(User.ofAllUsers(), Role.READER)))) .build(), fileInputStream); String fileUrl = blobInfo.getMediaLink(); System.out.println("Uploaded URL: " + fileUrl); } } 

当我运行该代码时,当我调用storage.create()时,我收到401 Unauthorized错误,这并不奇怪,因为我没有提供用户名或密码。 我收集的是因为该示例在App Engine中运行,它以这种方式提供凭据。

我试过通过属性文件传递我的凭据:

 Credential credential = new GoogleCredential.Builder() .setTransport(httpTransport) .setJsonFactory(jsonFactory) .setServiceAccountId("accountId") .setServiceAccountPrivateKeyFromP12File( new File("PRIVATE_KEY_PATH")) .setServiceAccountScopes(scopes).build(); Storage storage = new StorageOptions.DefaultStorageFactory().create(StorageOptions.newBuilder().setCredentials(credential).build()); 

但是这不能编译,因为setCredentials()函数需要Credentials实例,而不是Credential实例。

我一直在谷歌搜索和阅读云存储API ,但我仍然无法弄清楚我应该如何传递凭据,而无需经过复杂的设置过程。

所以, 我的问题是:为Google云端存储提供凭据以上传文件的最简单方法什么?

对于某些背景:我正在尝试比较和对比Google云端存储和Amazon S3。 我可以在S3中创建这样的程序没问题,但出于某种原因我正在用云存储打砖墙。 绝对欣赏任何人可以抛弃我的方式的任何见解或基本教程。

使用新的Google Cloud Client Library创建来自PKCS#12文件的凭据似乎并不那么容易,因为它曾与旧的Cloud Storage JSON API一起使用 。

最简单的方法是使用JSON格式,如此处所述,然后使用GoogleCredentials#fromStream方法加载它:

 Credentials credentials = GoogleCredentials.fromStream(new FileInputStream("credentials.json")); Storage storage = StorageOptions.newBuilder().setCredentials(credentials).build().getService(); 

如果您仍想使用PKCS#12,我相信这会起作用:

 PrivateKey privateKey = SecurityUtils.loadPrivateKeyFromKeyStore( SecurityUtils.getPkcs12KeyStore(), new FileInputStream("credentials.p12"), "notasecret", "privatekey", "notasecret"); Credentials credentials = new ServiceAccountCredentials(null, "accountId", privateKey, null, null); Storage storage = StorageOptions.newBuilder().setCredentials(credentials).build().getService(); 

适用于Java的Google Cloud客户端库允许您使用多个身份validation方案,但到目前为止最简单的方法是利用“ 应用程序默认凭据” 。 这些是与您的应用引擎应用运行的服务帐户相关联的凭据。 如果您在App Engine或Compute Engine上使用google-cloud Java客户端库,则以下内容应该可以正常工作:

 import static java.nio.charset.StandardCharsets.UTF_8; import com.google.cloud.storage.Blob; import com.google.cloud.storage.BlobId; import com.google.cloud.storage.BlobInfo; import com.google.cloud.storage.Storage; import com.google.cloud.storage.StorageOptions; Storage storage = StorageOptions.getDefaultInstance().getService(); BlobId blobId = BlobId.of("bucket", "blob_name"); BlobInfo blobInfo = BlobInfo.newBuilder(blobId).setContentType("text/plain").build(); Blob blob = storage.create(blobInfo, "Hello, Cloud Storage!".getBytes(UTF_8)); 

这可能是使用auth的最简单方法。 如果您在本地运行该程序而未部署到Google环境,则还可以安装gcloud命令行实用程序,然后运行gcloud auth application-default login ,此时应用程序默认凭据应启用上述代码以进行身份​​validation没有任何明确的认证逻辑。

如果要以编程方式指定特定服务帐户并将JSON密钥文件与其关联,则可以这样明确地执行此操作:

 Storage storage = StorageOptions.newBuilder() .setCredentials(ServiceAccountCredentials.fromStream( new FileInputStream("/path/to/my/key.json"))) .build() .getService(); 

您还可以使用环境变量GOOGLE_APPLICATION_CREDENTIALS指定服务帐户私钥的路径。 所以类似于:

 $> GOOGLE_APPLICATION_CREDENTIALS=/path/to/key.json java MyApp