如何解决 Amazon S3 的“403 访问被拒绝”错误?

上次更新时间:2019 年 5 月 10 日

我的用户尝试访问我的 Amazon Simple Storage Service (Amazon S3) 存储桶中的对象,但 Amazon S3 返回“403 访问被拒绝”错误。我如何解决此错误? 

简短描述

要解决 Amazon S3 中的“访问被拒绝”错误,请检查以下各项:

  • 跨 AWS 账户存储桶权限和对象拥有者
  • 存储桶策略或 AWS Identity and Access Management (IAM) 用户策略中的问题
  • 用于访问 Amazon S3 的凭证
  • VPC 终端节点策略
  • 阻止公共访问设置
  • 对象缺失
  • 对象经 AWS Key Management Service (AWS KMS) 加密
  • 存储桶上启用了 Requester Pays
  • AWS Organizations 服务控制策略

解决方法

跨 AWS 账户存储桶权限和对象拥有者

默认情况下,S3 对象由上传它的 AWS 账户所拥有。即使存储桶由另一个账户拥有,也是如此。如果其他账户可以将对象上传到您的存储桶,则查看您的用户无法访问的对象是属于哪个账户:

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

aws s3api list-buckets --query Owner.ID 

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

aws s3api list-objects --bucket awsexamplebucket --prefix exampleprefix 

提示:您可以使用 list-objects 命令查看多个对象。

3.    如果两个规范 ID 不匹配,则您(存储桶拥有者)不拥有该对象。对象拥有者可以通过运行此命令授予您对该对象的完全控制权:

aws s3api put-object-acl --bucket awsexamplebucket --key exampleobject.jpg --acl bucket-owner-full-control 

对于持续的跨账户权限,您可以在账户中创建具有存储桶权限的 IAM 角色。然后,您可以授予另一个 AWS 账户接管该 IAM 角色的权限。有关更多信息,请参阅教程:使用 IAM 角色委派跨 AWS 账户的访问权限。 

存储桶策略或 IAM 用户策略中的问题

查看存储桶策略或关联的 IAM 用户策略中可能错误地拒绝访问的任何语句。检查策略中是否存在任何不正确的拒绝语句、动作缺失或不正确的空格。

检查拒绝语句中是否存在任何根据多重身份验证 (MFA)、加密密钥、特定 IP 地址或特定 VPC 终端节点阻止访问的条件。验证对存储桶的请求满足存储桶策略或 IAM 策略中的任何条件。否则,预期访问会被拒绝。

注意:如果您要求进行 MFA,且用户通过 AWS CLI 发送请求,请确保用户配置 AWS CLI 以使用 MFA

例如,在下面的存储桶策略中,语句 1 允许公共访问从 awsexamplebucket 下载对象 (s3:GetObject)。然而,语句 2 明确地拒绝任何人从 awsexamplebucket 下载对象,除非请求来自 VPC 终端节点 vpce-1a2b3c4d。在这种情况下,拒绝语句优先。这意味着尝试从 vpce-1a2b3c4d 以外下载对象的用户将被拒绝访问。

{
  "Id": "Policy1234567890123",
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Statement1",
      "Action": [
        "s3:GetObject"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::awsexamplebucket/*",
      "Principal": "*"
    },
    {
      "Sid": "Statement2",
      "Action": [
        "s3:GetObject"
      ],
      "Effect": "Deny",
      "Resource": "arn:aws:s3:::awsexamplebucket/*",
      "Condition": {
        "StringNotEquals": {
          "aws:SourceVpce": "vpce-1a2b3c4d"
        }
      },
      "Principal": "*"
    }
  ]
}

检查存储桶策略或 IAM 策略是否允许用户需要采取的 Amazon S3 操作。例如,以下存储桶策略不包含 s3:PutObjectAcl 操作的权限。如果 IAM 用户尝试修改对象的访问控制列表 (ACL),则用户会遇到“访问被拒绝”错误。 

{
  "Id": "Policy1234567890123",
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1234567890123",
      "Action": [
        "s3:PutObject"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::awsexamplebucket/*",
      "Principal": {
        "AWS": [
          "arn:aws:iam::111122223333:user/Dave"
        ]
      }
    }
  ]
}

确认存储桶策略或 IAM 用户策略中没有任何多余的空格。例如,以下 IAM 策略的 Amazon 资源名称 (ARN) arn:aws:s3::: awsexamplebucket/* 中存在一个多余的空格。由于这个空格的存在,ARN 会被错误地计算为 arn:aws:s3:::%20awsexamplebucket/*。这意味着该 IAM 用户没有权限使用正确的对象。 

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1234567890123",
      "Action": [
        "s3:GetObject"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3::: awsexamplebucket/*"
    }
  ]
}

阻止公共访问设置

如果您的用户因应该被允许的公共请求遇到“访问被拒绝”错误,请检查存储桶的阻止公共访问设置。这些设置会替代允许公共访问的权限。阻止公共访问可以应用于各个存储桶或 AWS 账户。

用于访问 Amazon S3 的凭证

查看用户已配置用于访问 Amazon S3 的凭证。必须将 AWS 开发工具包和 AWS CLI 配置为使用可访问您的存储桶的 IAM 用户或角色的凭证。

对于 AWS CLI,运行此命令以检查配置的凭证: 

aws configure list

如果用户通过 Amazon Elastic Compute Cloud (Amazon EC2) 实例访问您的存储桶,则验证实例是否使用了正确的角色。连接到实例,然后运行此命令: 

aws sts get-caller-identity

VPC 终端节点策略

如果用户使用通过 VPC 终端节点路由的 EC2 实例访问您的存储桶,则检查 VPC 终端节点策略。确保 VPC 终端节点策略包含访问 S3 存储桶和对象的正确权限。

例如,以下 VPC 终端节点策略仅允许访问 awsexamplebucket。通过此 VPC 终端节点发送请求的用户无法访问任何其他存储桶。

{
  "Id": "Policy1234567890123",
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1234567890123",
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::awsexamplebucket",
        "arn:aws:s3:::awsexamplebucket/*"
      ],
      "Principal": "*"
    }
  ]
}

对象缺失

检查存储桶中是否存在请求的对象。如果用户没有 s3:ListBucket 权限,则用户会因对象缺失遇到“访问被拒绝”错误,而不是“404 未找到”错误。运行此 AWS CLI 命令以检查存储桶中是否存在某对象: 

aws s3api head-object --bucket awsexamplebucket --key exampleobject.jpg 

如果存储桶中存在该对象,则“访问被拒绝”错误不会屏蔽“404 未找到”错误。验证其他配置要求以解决“访问被拒绝”错误。

如果存储桶中不存在该对象,则“访问被拒绝”错误将屏蔽“404 未找到”错误。解决与对象缺失相关的问题。

对象经 AWS KMS 加密

如果 IAM 用户无法访问用户具有完全权限的对象,则检查该对象是否经 AWS KMS 加密。您可以使用 Amazon S3 控制台查看对象的属性,其中包括对象的加密信息。

如果对象经 KMS 加密,请确保 KMS 密钥策略和 IAM 用户策略皆允许以下操作: 

"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
]

存储桶上启用了 Requester Pays

如果您的存储桶启用了 Requester Pays,则其他账户的用户在向您的存储桶发送请求时必须指定 request-payer 参数。否则,这些用户会遇到“访问被拒绝”错误。要检查 Requester Pays 是否已启用,您可以使用 Amazon S3 控制台查看存储桶属性

以下 AWS CLI 命令示例包含访问启用了 Requester Pays 的存储桶的正确参数: 

aws s3 cp exampleobject.jpg s3://awsexamplebucket/exampleobject.jpg --request-payer requester

AWS Organizations 服务控制策略

如果您使用的是 AWS Organizations,则检查服务控制策略以确保允许访问 Amazon S3。例如,以下策略明确拒绝访问 Amazon S3 并导致“访问被拒绝”错误。 

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Action": "s3:*",
            "Resource": "*"
        }
    ]
}

有关 AWS Organizations 功能的更多信息,请参阅启用组织中的所有功能。 


这篇文章对您有帮助吗?


您是否需要账单或技术支持?