每次将对象上传到 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());
然后,我从网络上传文件,效果很好,只有一个问题 - 没有公共(public)读取的 ACL。
当然,我可以在上传完成后更改ACL,如下所示:
storage.createAcl(info.getBlobId(), (Acl.of(Acl.User.ofAllUsers(), Acl.Role.READER)));
但是有没有办法直接在签名的 URL 中设置它,而无需在成功上传后从网络进行额外的触发?
谢谢!
最佳答案
Signed URLs vs ACLs ( aka. Access Control Lists)
访问控制列表 (ACL) 和签名 URL(查询字符串身份验证)不是同一事物。
虽然它们都可以控制谁有权访问您的 Cloud Storage 存储分区和对象以及他们拥有的访问级别,但ACL 会向用户授予对各个存储分区或对象的读取或写入访问权限 。在大多数情况下,Cloud IAM 权限优于 ACL,因为后者仅在需要对单个对象进行细粒度控制时使用。
另一方面,签名 URL 通过生成的 URL 提供对对象的限时读取或写入访问。拥有此 URL 的任何人都可以在指定的特定时间内访问该对象。
因此,我不知道有什么方法可以直接在签名 URL 中实现 ACL 来回答您的问题。
<小时/>管理您的 ACL
来自Documentation :
<小时/>To avoid setting ACLs every time you create a new object, you can set a default object ACL on a bucket. After you do this, every new object that is added to that bucket that does not explicitly have an ACL applied to it will have the default applied to it.
更改默认对象 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 秒。
关于java - 在 Java 上使用目标凭据进行 Google Cloud Storage URL 签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59748720/