为Google Cloud Storage API提供凭据

Cat*_*ass 8 java google-cloud-storage google-cloud-platform

我正在尝试组建一个用于测试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);
    }
}
Run Code Online (Sandbox Code Playgroud)

当我运行该代码时,我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());
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

Hel*_*ira 14

使用新的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();
Run Code Online (Sandbox Code Playgroud)

如果您仍想使用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();
Run Code Online (Sandbox Code Playgroud)


Bra*_*ugh 6

适用于 JavaGoogle Cloud 客户端库允许您使用多种身份验证方案,但目前最简单的是利用“应用程序默认凭据”。这些是与您的应用引擎应用运行的服务帐户相关联的凭据。如果您在 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));
Run Code Online (Sandbox Code Playgroud)

这可能是使用 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();
Run Code Online (Sandbox Code Playgroud)

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

$> GOOGLE_APPLICATION_CREDENTIALS=/path/to/key.json java MyApp
Run Code Online (Sandbox Code Playgroud)