背景:

我有两个帐户 AB 。账户 A 拥有一个桶 my-bucket 。我已授予帐户 B 访问此存储桶的权限——帐户 B 可以从此存储桶读取对象并将对象写入此存储桶。这按预期工作。

但是,帐户 A 只能读取自己编写的 my-bucket 中的那些对象。尽管它甚至可以列出帐户 B 已写入的那些对象,但它无法读取这些对象。

以下是我尝试使用 AWS CLI 和账户 my-bucket 的 AWS 配置从 A 下载所有对象时看到的内容。

download: s3://my-bucket/PN1492646400000.csv to tp/PN1492646400000.csv
download: s3://my-bucket/PN1491264000000.csv to tp/PN1491264000000.csv
download: s3://my-bucket/PN1493942400000.csv to tp/PN1493942400000.csv
download failed: s3://my-bucket/PN1503346865232.csv to tp/PN1503346865232.csv An error occurred (AccessDenied) when calling the GetObject operation: Access Denied
download: s3://my-bucket/PN1495389670000.csv to tp/PN1495389670000.csv
download: s3://my-bucket/PN1496685403000.csv to tp/PN1496685403000.csv
download: s3://my-bucket/PN1497945130000.csv to tp/PN1497945130000.csv
download: s3://my-bucket/PN1500508800000.csv to tp/PN1500508800000.csv

如您所见,我可以下载所有文件,但 PN1503346865232.csv (这是由帐户 B 使用 java 方法 putObject 编写的)。

到目前为止我尝试过的:

我研究了以下两个问题:
  • Amazon S3 file 'Access Denied' exception in Cross-Account :其中一条评论要求使用 acl 执行 putObject ,但没有指定 acl 是什么。
  • S3: User cannot access object in his own s3 bucket if created by another user :这讨论了阻止帐户 B 在不授予所有权访问权限的情况下将对象放入 my-bucket 中。仅设置此约束是否有助于我获得完全访问权限?

  • 这就是我在将对象放入 java 代码时尝试放置 ACL 的方式。
    AccessControlList acl = new AccessControlList();
    acl.grantPermission(new CanonicalGrantee(S3_BUCKET_OWNER_ID), Permission.FullControl);
    PutObjectRequest putObjectRequest = new PutObjectRequest(S3_BUCKET, remoteCleanedPrismFilename, fileStream, null)
                            .withAccessControlList(acl);
    s3Client.putObject(putObjectRequest);
    

    它抛出异常说:com.amazonaws.services.s3.model.AmazonS3Exception: Invalid id
    问题:
  • 我想知道我应该如何获得这个 ID。它不是 aws 帐户 ID,即 10-12 位数字吗?
  • 即使我找到了这个 ID,也会给这个 ACL 和 bucket-owner-full-control 一样吗?
  • 最佳答案

    这篇文章有很多观点,但没有一个答案!

    为了帮助其他人,我发布了一些我从目前的研究中发现的解决方法。在这些变通办法之后,帐户 A 能够访问帐户 B 创建的对象。

    在帐户 java 中运行的 B 代码中,我在要创建的对象上显式设置了 ACL。

    AccessControlList acl = new AccessControlList();
    acl.grantPermission(new CanonicalGrantee(S3_BUCKET_OWNER_ID), Permission.FullControl);
    PutObjectRequest putObjectRequest = new PutObjectRequest(S3_BUCKET, remoteCleanedPrismFilename, fileStream, null)
                            .withAccessControlList(acl);
    s3Client.putObject(putObjectRequest);
    

    这里 S3_BUCKET_OWNER_ID 是账户 A 的规范 ID。请注意,我们知道的不是 AWS 账户 ID,我不知道比以下更好的方法来找出这一点
    aws s3api get-object-acl --bucket my-bucket --key PN1491264000000.csv --output text --profile accountA
    

    在我看来,这仍然不是一个优雅的解决方案,我相信存在更好的解决方案。一旦我找到更好的东西,我会编辑这个答案。

    编辑:

    可以更优雅地找到bucket owner的Canonical ID如下:
    String s3BucketOwnerId = s3Client.getBucketAcl(S3_BUCKET).getOwner().getId();
    

    关于java - S3跨账户访问: Reading an object in own bucket,由另一个账户写入,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45805514/

    10-12 15:14