为什么我无法访问 Amazon S3 存储桶中的特定文件夹或文件?

上次更新日期:2020 年 10 月 20 日

我无法访问我的 Amazon Simple Storage Service (Amazon S3) 存储桶中的特定前缀或对象,但我可以访问该存储桶中的其他数据。如何修复此问题?

简短描述

请检查任何拒绝您访问该前缀或对象的设置的以下权限:

  • 前缀或对象的所有权
  • 存储桶策略中的限制
  • 您的 AWS Identity and Access Management (IAM) 用户策略中的限制
  • AWS Key Management Service (AWS KMS) 加密对象的权限

解决方法

前缀或对象的所有权

默认情况下,S3 对象归上传此对象的 AWS 账户所有。即使存储桶由另一个账户拥有,也是如此。如果其他账户向您的存储桶上传对象,请执行以下步骤以获取您无法访问的对象或前缀的权限:

1.    运行此 AWS 命令行界面 (AWS CLI) 命令以获取账户的 Amazon S3 规范 ID:

aws s3api list-buckets --query Owner.ID

注意:如果在运行 AWS CLI 命令时收到错误,请确保您使用的是最新版本的 AWS CLI

2.    运行此命令以获取您无法访问的对象所属账户的 Amazon S3 规范 ID:

aws s3api list-objects --bucket DOC-EXAMPLE-BUCKET --prefix index.html

3.    如果两个规范 ID 不匹配,则您(存储桶拥有者)不拥有该对象。对于单个对象,对象拥有者可以运行 put-object-acl 命令,授予您完全控制权限:

aws s3api put-object-acl --bucket DOC-EXAMPLE-BUCKET --key object-name --acl bucket-owner-full-control

对于前缀中的对象,对象拥有者必须重新复制前缀,并在操作过程中授予您对相关对象的完全控制权限。例如,对象拥有者可以使用 --acl bucket-owner-full-control 参数运行此 cp 命令:

aws s3 cp s3://DOC-EXAMPLE-BUCKET/abc/ s3://DOC-EXAMPLE-BUCKET/abc/ --acl bucket-owner-full-control --recursive --storage-class STANDARD

提示:您可以使用存储桶策略,要求其他账户向您授予对他们上传到您的存储桶的对象的所有权。

存储桶策略中的限制

1.    打开 Amazon S3 控制台

2.    从存储桶列表中打开您要审查其策略的存储桶。

3.    选择权限选项卡。

4.    选择存储桶策略

5.    搜索包含 "Effect": "Deny" 的语句。然后审查提及您无法访问的前缀或对象的语句。

例如,下面的存储桶策略将拒绝所有人访问 DOC-EXAMPLE-BUCKET 中的 abc/* 前缀:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "StatementPrefixDeny",
            "Effect": "Deny",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/abc/*"
        }
    ]
}

6.     修改存储桶策略以编辑或删除任何错误拒绝您访问该前缀或对象的 "Effect": "Deny" 语句。

您的 IAM 用户策略中的限制

1.    打开 IAM 控制台

2.    在控制台中,打开您用来访问该前缀或对象的 IAM 用户或角色。

3.    在您的 IAM 用户或角色的权限选项卡中,展开每个策略以查看其 JSON 策略文档。

4.    在 JSON 策略文档中,搜索与 Amazon S3 访问相关的策略。然后在这些策略中搜索任何阻止您访问该前缀或对象的 "Effect": "Deny" 语句。

例如,以下 IAM 策略含有一个会阻止该 IAM 身份访问 DOC-EXAMPLE-BUCKET 中的前缀 abc/*“Effect”: “Deny” 语句。此外,该策略还含有一个会允许访问 DOC-EXAMPLE-BUCKET"Effect": "Allow" 语句。尽管该允许语句适用于整个存储桶,但显式拒绝语句阻止了该 IAM 身份访问前缀 abc/*

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "StatementPrefixDeny",
            "Effect": "Deny",
            "Action": "s3:GetObject",
            "Resource": [
                "arn:aws:s3:::DOC-EXAMPLE-BUCKET/abc/*"
            ]
        },
        {
            "Sid": "StatementFullPermissionS3",
            "Effect": "Allow",
            "Action": "s3:GetObject",
            "Resource": [
                "arn:aws:s3:::DOC-EXAMPLE-BUCKET",
                "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"
            ]
        }
    ]
}

5.     修改策略以编辑或删除任何错误拒绝您访问该前缀或对象的 "Effect": "Deny" 语句。

AWS KMS 加密对象的权限

如果某个对象使用了 AWS KMS 密钥,则您同时需要该对象和该密钥的权限。请执行以下步骤,检查您无法访问该对象的原因是否是因为您需要 AWS KMS 密钥:

1.    使用 Amazon S3 控制台查看您无法访问的某个对象的属性。查看对象的加密属性。

2.    如果对象使用自定义的 AWS KMS 客户主密钥 (CMK) 加密,则查看 CMK 的策略。确认密钥策略允许您的 IAM 身份执行以下 KMS 操作:

"Action": [
    "kms:Decrypt",
    "kms:ReEncrypt",
    "kms:GenerateDataKey"
],

3.    如果您的 IAM 身份缺少以下任何操作的权限,请修改密钥策略以授予缺失的权限。

重要提示:如果您的 IAM 身份和 KMS 密钥属于不同的账户,则您的 IAM 策略和密钥策略必须同时授予您对所需 KMS 操作的权限。