如何配置S3桶允许外部AWS账户访问且无需修改对方权限
问题描述
我有一个第三方系统,能指定它把文件上传到我选的S3桶。这个系统的上传代码是固定的:
s3 = boto3.resource('s3') bucket = s3.Bucket(bucket_name) bucket.put_object(Body=data_log,Key='log.txt')
该系统用的AWS凭证所属账户我完全管不了,而且既改不了凭证,也改不了上传代码。
我试过用这些命令配置自己的S3桶:
aws s3api create-bucket --bucket <MYBUCKET> --region eu-central-1 --create-bucket-configuration LocationConstraint="eu-central-1" aws s3api delete-public-access-block --bucket <MYBUCKET> aws s3api put-bucket-ownership-controls --bucket <MYBUCKET> --ownership-controls 'Rules=[{ObjectOwnership="BucketOwnerPreferred"}]' aws s3api put-bucket-acl --bucket <MYBUCKET> --acl public-read-write
但执行上传时还是报错:
An error occurred (AccessDenied) when calling the PutObject operation: Access Denied
核心需求:怎么配置我的S3桶,让其他AWS账户的用户能上传文件,而且不用改对方账户的任何策略或配置。
补充信息:
- 我试过把代码改成匿名上传能成功,但生产环境改不了代码:
s3 = boto3.resource('s3', config=Config(signature_version=UNSIGNED)) bucket = s3.Bucket(bucket_name) bucket.put_object(Body=data_log,Key='log.txt') - 我还试过给桶加开放策略,同时给我自己另一个AWS账户的用户加权限也能成功,但生产环境没法改对方的用户策略:
桶策略:
对方账户用户策略(我无法修改):{ "Version": "2012-10-17", "Statement": [ { "Sid": "PolicyForAllowUploadWithACL", "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": "s3:PutObject", "Resource": "arn:aws:s3:::<MYBUCKET>/*" } ] }{ "Version": "2012-10-17", "Statement": [ { "Sid": "PolicyForAllowUploadWithACL", "Effect": "Allow", "Action": [ "s3:PutObject" ], "Resource": [ "arn:aws:s3:::<MYBUCKET>/*" ] } ] }
解决方案
要让第三方AWS账户的用户顺利上传到你的桶,且不用改对方配置,得同时配置桶策略和桶所有权控制,确保权限链完整:
1. 确认桶所有权控制配置
先把桶的所有权设置为BucketOwnerPreferred,这能保证上传的对象归你(桶所有者)所有,同时允许上传者附带ACL:
aws s3api put-bucket-ownership-controls --bucket <MYBUCKET> --ownership-controls 'Rules=[{ObjectOwnership="BucketOwnerPreferred"}]'
2. 配置桶策略允许特定账户上传
别用Principal: "*"(太开放不安全),直接指定第三方账户的ARN。如果不知道对方账户ARN,暂时用"*"测试,生产环境一定要换成具体账户ID:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowCrossAccountPutObject", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::第三方账户ID:root" }, "Action": [ "s3:PutObject", "s3:PutObjectAcl" ], "Resource": "arn:aws:s3:::<MYBUCKET>/*" } ] }
3. 补充桶ACL设置(可选)
如果之前的public-read-write ACL不够,可以设置针对性的ACL,不过主要权限还是靠桶策略控制:
aws s3api put-bucket-acl --bucket <MYBUCKET> --grant-write uri="http://acs.amazonaws.com/groups/global/AuthenticatedUsers"
这个命令允许所有AWS认证用户写入,但结合桶策略的账户限制,只会放行指定账户的上传请求。
4. 验证配置
配置完让第三方系统重新执行上传代码,应该就能成功。如果还是报错,检查这几点:
- 第三方账户的凭证是否有
sts:GetCallerIdentity权限(默认都有) - 桶策略里的账户ID是否正确
- 所有权控制确实设置成了
BucketOwnerPreferred
内容的提问来源于stack exchange,提问作者TomSie
相关产品推荐
相关产品推荐

