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

上次更新时间:2020 年 10 月 19 日

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

简短描述

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

  • 存储桶和对象所有权
  • 存储桶策略或 AWS Identity and Access Management (IAM) 用户策略
  • IAM 权限边界
  • Amazon S3 阻止公有访问设置
  • 用于访问 Amazon S3 的凭证
  • 临时安全凭证
  • Amazon Virtual Private Cloud (Amazon VPC) 终端节点策略
  • Amazon S3 访问点策略
  • 缺失的对象
  • AWS Key Management Service (AWS KMS) 加密
  • 存储桶上启用了申请方付款
  • AWS Organizations 服务控制策略

注意:您还可以在 AWS Systems Manager 上使用 AWSSupport-TroubleshootS3PublicRead 自动化文档。此自动化文档可帮助您诊断关于从您指定的公共 S3 存储桶读取对象的问题。

解决方法

存储桶和对象所有权

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

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

aws s3api list-buckets --query Owner.ID

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

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

aws s3api list-objects --bucket DOC-EXAMPLE-BUCKET --prefix exampleprefix

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

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

aws s3api put-object-acl --bucket DOC-EXAMPLE-BUCKET --key exampleobject.jpg --acl bucket-owner-full-control

4.    在对象拥有者将对象的 ACL 更改为 bucket-owner-full-control 后,存储桶拥有者可以访问该对象。但是,仅更改 ACL 不会更改对象的所有权。要将对象拥有者更改为存储桶的账户,请从存储桶账户运行 cp 命令,将对象复制到其自身上。

要确保从另一账户复制到存储桶的所有新对象都归存储桶账户所有,请设置一个存储桶策略,该策略要求使用 bucket-owner-full-control ACL 上传对象。然后,启用 S3 对象所有权,当使用 bucket-owner-full-control ACL 上传该对象时,会自动将该对象的拥有者更改为存储桶拥有者

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

存储桶策略或 IAM 用户策略

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

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

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

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

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

2.    检查存储桶策略或 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:::DOC-EXAMPLE-BUCKET/*",
      "Principal": {
        "AWS": [
          "arn:aws:iam::111122223333:user/Dave"
        ]
      }
    }
  ]
}

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

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

IAM 权限边界

查看在尝试访问存储桶的 IAM 身份上设置的 IAM 权限边界。确认 IAM 权限边界允许访问 Amazon S3。

Amazon S3 阻止公有访问设置

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

用于访问 Amazon S3 的凭证

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

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

aws configure list

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

aws sts get-caller-identity

临时安全凭证

如果用户收到使用 AWS Security Token Service (AWS STS) 授予的临时安全凭证发出的访问被拒绝错误,请查看与临时凭证关联的策略。

当管理员使用 AssumeRole API 调用或 assume-role 命令创建临时安全凭证时,他们可以选择传递特定于会话的策略。

要查找与来自 Amazon S3 的访问被拒绝错误相关联的会话策略,请在 AWS CloudTrail 事件历史记录中查找 AssumeRole 事件。请确保在与访问 Amazon S3 的失败请求相同的时间范围内查找 AssumeRole 事件。然后,查看相关 CloudTrail 日志中 requestParameters 字段中的任何 policypolicyArns 参数。确认关联的策略或策略 ARN 授予了必要的 Amazon S3 权限。

例如,下面的 CloudTrail 日志代码段显示临时凭证包含一个内联会话策略,该策略将 s3:GetObject 权限授予 DOC-EXAMPLE-BUCKET

"requestParameters": {
        "roleArn": "arn:aws:iam::123412341234:role/S3AdminAccess",
        "roleSessionName": "s3rolesession",
        "policy": "{\n    \"Version\": \"2012-10-17\",\n    \"Statement\": [\n  {\n  \"Effect\": \"Allow\",\n           
         \"Action\": [\n   \"s3:GetObject\"\n ],\n    \"Resource\": [\n \"arn:aws:s3:::DOC-EXAMPLE-BUCKET/*\"\n  ]\n   }  }\n    ]\n}\n"
    }

Amazon VPC 终端节点策略

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

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

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

Amazon S3 访问点策略

如果您使用 Amazon S3 访问点来管理对存储桶的访问,请查看访问点的 IAM 策略。确认策略授予了正确的权限。

缺失的对象

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

aws s3api head-object --bucket DOC-EXAMPLE-BUCKET --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"
]

如果 IAM 用户所属的账户与 AWS KMS 密钥不同,则还必须在 IAM 策略上授予这些权限。

存储桶上启用了申请方付款

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

以下 AWS CLI 命令示例包含访问启用了“申请方付款”的存储桶的正确参数:

aws s3 cp exampleobject.jpg s3://DOC-EXAMPLE-BUCKET/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 功能的更多信息,请参阅启用组织中的所有功能


这篇文章对您有帮助吗?


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