【发布时间】:2022-02-12 00:18:43
【问题描述】:
我有一个私人 s3 存储桶,我在设置中选择了 Block *all* public access。
当我尝试收集静态信息时,我收到拒绝访问错误:
botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the PutObject operation: Access Denied
此外,当尝试访问我手动上传的静态文件(即 js 和 css)时,我会收到 403 代码
我已经根据this post 制定了存储桶策略:
{
"Version": "2012-10-17",
"Id": "Policy16144340382381",
"Statement": [
{
"Sid": "Stmt16144340315031",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::634515378440:user/myapp-user"
},
"Action": [
"s3:PutObject",
"s3:AbortMultipartUpload",
"s3:DeleteObject",
"s3:GetObject",
"s3:ListBucketMultipartUploads",
"s3:ListMultipartUploadParts"
],
"Resource": [
"arn:aws:s3:::myapp-bucket",
"arn:aws:s3:::myapp-bucket/*"
]
},
{
"Sid": "Stmt1614408230409",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::634515378440:user/myapp-user"
},
"Action": "*",
"Resource": "arn:aws:s3:::myapp-bucket/*"
}
]
}
我将 IAM 用户添加到具有此权限策略的组中:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObjectAcl",
"s3:GetObject",
"s3:ListBucketMultipartUploads",
"s3:AbortMultipartUpload",
"s3:PutObjectVersionAcl",
"s3:ListBucket",
"s3:DeleteObject",
"s3:GetBucketLocation",
"s3:PutObjectAcl",
"s3:ListMultipartUploadParts"
],
"Resource": [
"arn:aws:s3:::myapp-bucket/*",
"arn:aws:s3:::myapp-bucket"
]
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "s3:ListAllMyBuckets",
"Resource": "*"
}
]
}
另外,这是我用来配置应用程序的settings.py 代码中的代码
INSTALLED_APPS = [
...
'storages',
...
]
# S3 BUCKETS CONFIG
AWS_ACCESS_KEY_ID = os.environ['AWS_ACCESS_KEY_ID']
AWS_SECRET_ACCESS_KEY = os.environ['AWS_SECRET_ACCESS_KEY']
AWS_STORAGE_BUCKET_NAME = os.environ['AWS_STORAGE_BUCKET_NAME']
AWS_S3_CUSTOM_DOMAIN = f'{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com'
AWS_S3_OBJECT_PARAMETERS = {'CacheControl': 'max-age=86400'}
AWS_LOCATION = 'static'
AWS_DEFAULT_ACL = 'public-read'
AWS_S3_FILE_OVERWRITE = True
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
DEFAULT_FILE_STORAGE = 'myapp.storages.MediaStorage'
这里是storages.py
from storages.backends.s3boto3 import S3Boto3Storage
import os
class MediaStorage(S3Boto3Storage):
location = 'media'
file_overwrite = True
bucket_name = os.environ['AWS_STORAGE_BUCKET_NAME']
我什至尝试创建新用户和存储桶并将它们添加到策略中,以防凭据错误,但仍然没有结果。有没有办法可以验证连接是否成功,并可能列出用户通过 boto3 客户端拥有的权限?
更新:
我使用 myapp-user 的凭证配置了我的 AWS CLI 配置文件,它让我可以列出存储桶 aws s3 ls --profile myapp-user,我还能够运行 aws s3 cp 命令在我的本地电脑和存储桶之间复制文件美好的。
所以我知道凭证很好;但在这一点上,我不知道我还能做什么。我已确保我在 AWS CLI 配置中使用的凭证与我的 env 变量中的凭证相同,但我仍然收到 AccessDenied 错误。
【问题讨论】:
-
您通常不会将 IAM 用户添加到 S3 存储桶策略。您只需通过 IAM 策略(或 IAM 组成员资格)授予 IAM 用户必要的 S3 权限。我会打印传递给存储的访问密钥和秘密密钥,并确保它们是正确的 - 使用 awscli 测试它们(你可以使用这些凭据访问存储桶吗?)
-
@jarmod 感谢您的评论,当我尝试从存储桶策略中删除用户时,我收到此错误:
Missing required field Principal。我还尝试使用 AWS CLI 验证,它显示凭证是正确的(请参阅上面的更新)。 -
S3 存储桶策略(如果存在)需要委托人。我是说您通常会通过 IAM 策略而不是 S3 存储桶策略授予 myapp-user S3 权限。您将完全删除存储桶策略。
-
哦,好吧,我明白你的意思了;我刚刚试了一下,但仍然得到 AccessDenied。
-
哪个操作因 AccessDenied 而失败?为什么您将 AWS_DEFAULT_ACL 设置为公开读取您所说的具有阻止公共访问权限的存储桶?
标签: amazon-web-services amazon-s3 boto3