我想使用django中的FileField将文件上传到s3,但我希望该文件是私有的。我尝试创建一个像
这样的新字段class S3PrivateFileField(models.FileField):
def __init__(self, verbose_name=None, name=None, upload_to='', storage=None, **kwargs):
super(S3PrivateFileField, self).__init__(verbose_name=verbose_name,
name=name, upload_to=upload_to, storage=storage, **kwargs)
self.storage.default_acl = 'private'
当我检查我的s3控制台时,它显示该文件是私有的。但我仍然可以从管理员下载文件,这很好。我想保持文件与世界其他地方不同。有什么建议?感谢
我的水桶政策。
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "PublicReadForGetBucketObjects",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "---------------------"
}
]
}
答案 0 :(得分:0)
在S3(和IAM)政策/权限评估中,行动......
...默认情况下被隐式拒绝,并将被拒绝
...除非明确允许,否则允许
...除非明确拒绝,否则将永久拒绝。
考虑到这些规则,private
固定ACL不是明确的拒绝。"事实上,私人固定ACL只是一个明确的"允许"为业主。
您的存储桶策略授予匿名用户对存储桶中所有对象执行s3:GetObject
的权限。这是使存储桶中的所有内容都可读的一种方法,但只有在您确实希望所有对象都可读时才有用。
使对象可读的另一种方法是将ACL分别设置为固定ACL public-read
。这实现了与策略声明相同的目的,如果对象都是这样设置的,那么这样的策略声明应该是不必要的,因为它是多余的。
要将私人内容和公共内容存储在同一个存储桶中,意味着您无法使用这样的一揽子政策,因为 - 正如您所观察到的那样 - 它使所有内容都可读。
您需要在公共对象上将ACL设置为public-read
以使其在对象级别可读并删除此策略声明,以便其他对象不会隐式公开 - 或创建更复杂的存储桶策略以仅授予对特定前缀的公共访问权限。而不是资源arn:aws:s3:::bucket/*
,如果你的对象是如此组织的,你可以使用(例如)arn:aws:s3:::bucket/asset/*
,它只匹配前缀为asset/
的对象,只做一个子集该桶的对象可公开访问。