每次将对象上传到Google Cloud Storage后的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();
此后,我像这样签名URL:
URL signedUrl = storage.signUrl(info, 30,
TimeUnit.MINUTES,
Storage.SignUrlOption.httpMethod(com.google.cloud.storage.HttpMethod.valueOf("PUT")),
Storage.SignUrlOption.withContentType());
然后,我正在从Web上载文件,并且工作正常,只有一个问题-没有公开读取的ACL。
当然,我可以在完成上传后更改ACL,如下所示:
storage.createAcl(info.getBlobId(), (Acl.of(Acl.User.ofAllUsers(), Acl.Role.READER)));
但是在成功上传后,有没有一种方法可以直接在已签名的URL中进行设置,而无需网络上的其他触发?
谢谢!
访问控制列表(ACL)和签名的URL(查询字符串认证) 不是相同。
虽然它们都可以控制谁有权访问您的Cloud Storage存储桶和对象,以及他们具有什么访问级别,但是ACL授予用户单个存储桶或对象的读写访问权限。在大多数情况下,Cloud IAM权限用于ACL,因为后者仅在需要对单个对象进行细粒度控制时才使用。
另一方面,签名URL通过生成的URL提供对对象的限时读写访问权限。拥有此URL的任何人都可以在指定的持续时间内访问该对象。
因此,我不知道有任何方法可以直接在Signed URL中实现ACL来回答您的问题。
为了避免每次创建新对象都设置ACL,您可以在存储桶上设置默认对象ACL。执行完此操作后,添加到该存储桶的每个未明确应用ACL的新对象都将应用默认值。
更改默认对象ACL
以下示例将默认对象ACL添加到存储桶:
Acl acl = storage.createDefaultAcl(bucketName, Acl.of(User.ofAllAuthenticatedUsers(), Role.READER));
以下示例从存储桶中删除默认对象ACL:
boolean deleted = storage.deleteDefaultAcl(bucketName, User.ofAllAuthenticatedUsers());
if (deleted) {
// the acl entry was deleted
} else {
// the acl entry was not found
}
如果您更改存储桶的默认对象ACL,则更改可能需要一段时间才能传播,并且在存储桶中创建的新对象可能仍会在短时间内获得旧的默认对象ACL。为了确保在存储桶中创建的新对象获得更新的默认对象ACL,您应该在更改默认对象ACL和创建新对象之间至少等待30秒。