【问题标题】:Getting `AccessDenied` when calling any operation in AWS bucket policy在 AWS 存储桶策略中调用任何操作时获取“AccessDenied”
【发布时间】: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


【解决方案1】:

正如 Jarmod 在 cmets 中指出的那样,我得到 access denied 的原因是因为我有 AWS_DEFAULT_ACL = 'public-read',它与存储桶的访问设置冲突。 我可以通过使用 AWS_DEFAULT_ACL = None 来解决它,而不是简单地继承存储桶的访问设置。

【讨论】:

    猜你喜欢
    • 2018-05-22
    • 1970-01-01
    • 1970-01-01
    • 2022-11-14
    • 2020-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多