在Java上使用目标凭据进行Google云存储URL签名

在Java上使用目标凭据进行Google云存储URL签名,java,google-app-engine,google-cloud-storage,acl,Java,Google App Engine,Google Cloud Storage,Acl,每次将对象上载到Google云存储后,ACL都会被覆盖 我正在使用预设ACL创建BlobInfo,以便上载的对象必须是公共读取的: String blobId = "PUBLIC/1"; com.google.cloud.storage.BlobInfo info = com.google.cloud.storage.BlobInfo.newBuilder(RuntimeConfig.USERDATA_BUCKET_NAME, blobId) .setCont

每次将对象上载到Google云存储后,ACL都会被覆盖

我正在使用预设ACL创建
BlobInfo
,以便上载的对象必须是公共读取的:

 String blobId = "PUBLIC/1";
 com.google.cloud.storage.BlobInfo info = com.google.cloud.storage.BlobInfo.newBuilder(RuntimeConfig.USERDATA_BUCKET_NAME, blobId)
                .setContentType(mimetype)
                .setMetadata(metadata)
                .setAcl(new ArrayList<>(Arrays.asList(Acl.of(Acl.User.ofAllUsers(), Acl.Role.READER)))) // <-- HERE
                .build();
然后,我从web上传文件,这很好,只有一个问题-没有带有公共读取的ACL

当然,我可以在上传完成后更改ACL,如下所示:

URL signedUrl = storage.signUrl(info, 30,
                    TimeUnit.MINUTES,
                    Storage.SignUrlOption.httpMethod(com.google.cloud.storage.HttpMethod.valueOf("PUT")),
                    Storage.SignUrlOption.withContentType());
storage.createAcl(info.getBlobId(), (Acl.of(Acl.User.ofAllUsers(), Acl.Role.READER)));
但是有没有一种方法可以直接在已签名的URL中设置它,而在成功上传后不需要从web上附加触发器

谢谢

访问控制列表(ACL)签名URL(查询字符串验证)不是一回事

虽然它们都提供了对谁有权访问您的云存储存储存储桶和对象以及它们的访问级别的控制,ACL授予用户对单个存储桶或对象的读或写访问权。在大多数情况下,云IAM权限用于ACL,因为ACL仅在需要对单个对象进行细粒度控制时使用

另一方面,签名URL通过生成的URL提供对对象的有时间限制的读写访问。拥有此URL的任何人都将在指定的特定时间段内访问该对象

因此,我不知道有什么方法可以直接在签名URL中实现ACL来回答您的问题


管理ACL 发件人:

要避免每次创建新对象时设置ACL,可以在bucket上设置默认对象ACL。执行此操作后,添加到该bucket的每个未显式应用ACL的新对象都将应用默认ACL


更改默认对象ACL

以下示例将默认对象ACL添加到bucket中:

Acl acl = storage.createDefaultAcl(bucketName, Acl.of(User.ofAllAuthenticatedUsers(), Role.READER));
boolean deleted = storage.deleteDefaultAcl(bucketName, User.ofAllAuthenticatedUsers());
if (deleted) {
  // the acl entry was deleted
} else {
  // the acl entry was not found
}
以下示例从bucket中删除默认对象ACL:

Acl acl = storage.createDefaultAcl(bucketName, Acl.of(User.ofAllAuthenticatedUsers(), Role.READER));
boolean deleted = storage.deleteDefaultAcl(bucketName, User.ofAllAuthenticatedUsers());
if (deleted) {
  // the acl entry was deleted
} else {
  // the acl entry was not found
}

传播细节 如果更改bucket的默认对象ACL,则此更改可能需要一段时间才能传播,并且在bucket中创建的新对象可能在短时间内仍会获得旧的默认对象ACL。为了确保在bucket中创建的新对象获得更新的默认对象ACL,您应该在更改默认对象ACL和创建新对象之间等待至少30秒