我正在使用Python中的Amazonboto3库将文件上传到另一个用户桶中。应用于其他用户bucket的bucket策略配置如下
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DelegateS3BucketList",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::uuu"
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::bbb"
},
{
"Sid": "DelegateS3ObjectUpload",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::uuu"
},
"Action": [
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": [
"arn:aws:s3:::bbb",
"arn:aws:s3:::bbb/*"
]
}
]
}
其中CCD_ 1是我的用户id,而CCD_我的用户和其他用户是属于不同组织的IAM帐户。(我知道这个策略可以写得更简单,但其目的是在上传时添加一个检查,以阻止没有创建适当权限的对象(。
然后,我可以使用以下代码列出bucket中的所有对象,并将新对象上传到bucket。这是有效的,但是由于Amazons默认将对象设为对象创建者的私有对象,bucket的所有者无法访问该对象
import base64
import hashlib
from boto3.session import Session
access_key = "value generated by Amazon"
secret_key = "value generated by Amazon"
bucketname = "bbb"
content_bytes = b"hello world!"
content_md5 = base64.b64encode(hashlib.md5(content_bytes).digest()).decode("utf-8")
filename = "foo.txt"
sess = Session(aws_access_key_id=access_key, aws_secret_access_key=secret_key)
bucket = sess.resource("s3").Bucket(bucketname)
for o in bucket.objects.all():
print(o)
s3 = sess.client("s3")
s3.put_object(
Bucket=bucketname,
Key=filename,
Body=content_bytes,
ContentMD5=content_md5,
# ACL="bucket-owner-full-control" # Uncomment this line to generate error
)
一旦我取消注释ACL选项,代码就会生成一条Access Denied错误消息。如果我将其重定向到我自己组织内的一个bucket,ACL选项将成功,并且bucket的所有者将获得对该对象的完全权限。
我现在无法弄清楚这一点,尤其是亚马逊自己的建议似乎是按照我所展示的方式来做。
https://aws.amazon.com/premiumsupport/knowledge-center/s3-bucket-owner-access/
https://aws.amazon.com/premiumsupport/knowledge-center/s3-require-object-ownership/
仅在bucket策略中拥有权限是不够的。
检查您的用户(或角色(是否缺少IAM中的s3:PutObjectAcl
权限。
在boto3中使用resource
方法时,可能会进行多个不同的API调用,但并不总是很明显正在进行哪些调用。
相比之下,当在boto3中使用client
方法时,boto3中进行的API调用与AWS接收的API调用之间存在1对1映射。
因此,resource.put_object()
方法可能正在调用附加的API,例如PutObjectAcl
。您可以通过查看AWS CloudTrail并查看正在从您的应用程序进行哪些API调用来确认这一点。
在这种情况下,您将需要额外的s3:PutObjectAcl
权限。如果上传过程首先创建对象,然后更新对象的访问控制列表,则需要这样做。
当使用client
方法上载文件时,还可以指定ACL,我认为它可以直接应用,而不需要第二个API调用。因此,使用uuu
0方法创建对象可能会而不需要此额外权限。