向Google Cloud Storage API提供凭据

时间:2017-08-03 15:55:13

标签: java google-cloud-platform google-cloud-storage

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

我一直在网上搜索一个基本的教程,但我最接近的是this guide从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);
    }
}

当我运行该代码时,我在调用401 Unauthorized时出现storage.create()错误,这并不奇怪,因为我没有提供用户名或密码。我收集的是因为该示例在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实例。

我一直在谷歌搜索并阅读Cloud Storage API,但我仍然无法弄清楚如果不经过复杂的设置过程我应该如何传递凭据。

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

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

2 个答案:

答案 0 :(得分:9)

使用新的Google Cloud Client Library创建来自PKCS#12文件的凭据似乎并不那么容易,就像过去使用旧的 Cloud Storage JSON API一样。

最简单的方法是使用JSON格式,而不是here所述,然后使用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();

答案 1 :(得分:1)

Google Cloud client library for Java允许您使用多个身份验证方案,但到目前为止最简单的方法是利用“Application Default Credentials”。这些是与您的应用引擎应用运行的服务帐户相关联的凭据。如果您在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,此时应用程序默认凭据应启用上述代码在没有任何明确的身份验证逻辑的情况下进行身份验证。

如果要以编程方式指定特定服务帐户并将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