S3跨账户访问:读取自己存储桶中的对象,由另一个帐户

时间:2017-08-21 21:06:17

标签: java amazon-web-services amazon-s3

背景

我有两个帐户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编写的)。

到目前为止我尝试了什么:

我调查了以下两个问题:

  1. Amazon S3 file 'Access Denied' exception in Cross-Account:其中一条评论要求使用acl执行putObject,但未指定acl
  2. S3: User cannot access object in his own s3 bucket if created by another user:这是关于阻止帐户B将对象放入my-bucket而不授予所有权权限。 只是放置此约束可以帮助我获得完全访问权限吗?
  3. 这是我在将对象放入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

    问题:

    1. 我想知道我该怎么得到这个ID。是不是aws帐户ID,即10-12位数字?
    2. 即使我找到此ID,也会将此ACL与bucket-owner-full- control相同?

1 个答案:

答案 0 :(得分:1)

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

为了帮助其他人,我发布了一些我迄今为止从研究中发现的解决方法。完成这些变通办法后,帐户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

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

修改

可以更优雅地找到铲斗拥有者的规范ID,如下所示:

String s3BucketOwnerId = s3Client.getBucketAcl(S3_BUCKET).getOwner().getId();