有权向我的 Amazon S3 存储桶添加对象的用户收到 Access Denied 错误。为什么?
AWS Identity and Access Management (IAM) 用户有权对我的 Amazon Simple Storage Service (Amazon S3) 存储桶执行 s3:PutObject 操作。但是,当他们尝试上传对象时,他们会收到 HTTP 403: Access Denied 错误。
简短描述
如果 IAM 用户拥有上传到存储桶的正确权限,请查看以下策略中是否存在阻止上传的设置:
- IAM 用户对 s3:PutObjectAcl 的权限
- 存储桶策略中的条件
- Amazon Virtual Private Cloud (Amazon VPC) 端点策略允许的访问权限
- AWS KMS 加密
解决方法
IAM 用户对 s3:PutObjectAcl 的权限
如果 IAM 用户必须在上传期间更新对象的访问控制列表 (ACL),则该用户还必须在其 IAM 策略中拥有 s3:PutObjectAcl 的权限。有关如何更新用户的 IAM 策略的说明,请参阅更改 IAM 用户的权限。
存储桶策略中的条件
查看您的存储桶策略,了解以下限制上传到存储桶的示例条件。如果存储桶策略有条件且条件有效,则 IAM 用户必须满足条件才能进行上传。
重要事项:查看条件时,请务必验证该条件是否与 Allow 语句 ("Effect": "Allow") 或 Deny 语句 ("Effect": "Deny") 相关联。要使上传生效,用户必须遵守 Allow 语句的条件,或者避免 Deny 语句的条件。
检查是否存在仅允许从特定 IP 地址上传的条件,类似于以下内容:
"Condition": { "IpAddress": { "aws:SourceIp": "54.240.143.0/24" } }
如果您的存储桶策略有此条件,IAM 用户必须从允许的 IP 地址访问您的存储桶。
检查是否存在仅当对象为特定存储类别时才允许上传的条件,类似于以下内容:
"Condition": { "StringEquals": { "s3:x-amz-storage-class": [ "STANDARD_IA" ] }
如果您的策略有此条件,则用户必须上传具有允许存储类别的对象。例如,前面的条件语句需要 STANDARD_IA 存储类别。这意味着用户必须使用类似于以下内容的 AWS 命令行界面 (AWS CLI) 命令上传对象:
aws s3api put-object --bucket DOC-EXAMPLE-BUCKET --key examplefile.jpg --body c:\examplefile.jpg --storage-class STANDARD_IA
**注意:**如果在运行 AWS CLI 命令时收到错误,请确保您使用的是最新版本的 AWS CLI。
检查是否存在仅在为对象分配特定访问控制列表 (ACL) 时才允许上传的条件,类似于以下内容:
"Condition": { "StringEquals": { "s3:x-amz-acl":["public-read"] } }
如果您的策略有此条件,则用户必须上传具有允许的 ACL 的对象。例如,前面的条件需要 public-read ACL,因此用户必须使用类似于以下内容的命令上传对象:
aws s3api put-object --bucket DOC-EXAMPLE-BUCKET --key examplefile.jpg --body c:\examplefile.jpg --acl public-read
检查是否存在要求上传将对象的完全控制权授予存储桶所有者(规范用户 ID)的条件,类似于以下内容:
"Condition": { "StringEquals": { "s3:x-amz-grant-full-control": "id=AccountA-CanonicalUserID" } }
如果您的策略有此条件,则用户必须使用类似于以下内容的命令上传对象:
aws s3api put-object --bucket DOC-EXAMPLE-BUCKET --key examplefile.jpg --body c:\examplefile.jpg --grant-full-control id=CanonicalUserID
检查是否存在仅当对象由 AWS Key Management System (AWS KMS) 密钥加密时才允许上传的条件,类似于以下内容:
"Condition": { "StringEquals": { "s3:x-amz-server-side-encryption-aws-kms-key-id": "arn:aws:kms:us-east-1:111122223333:key/abcdabcd-abcd-abcd-abcd-abcdabcdabcd" } }
如果您的策略有此条件,则用户必须使用类似于以下内容的命令上传对象:
aws s3api put-object --bucket DOC-EXAMPLE-BUCKET --key examplefile.jpg --body c:\examplefile.jpg --server-side-encryption aws:kms --ssekms-key-id arn:aws:kms:us-east-1:111122223333:key/abcdabcd-abcd-abcd-abcd-abcdabcdabcd
检查是否存在仅当对象使用特定类型的服务器端加密时才允许上传的条件,类似于以下内容:
"Condition": { "StringEquals": { "s3:x-amz-server-side-encryption": "AES256" } }
如果您的策略有此条件,则用户必须使用类似于以下内容的命令上传对象:
aws s3api put-object --bucket DOC-EXAMPLE-BUCKET --key examplefile.jpg --body c:\examplefile.jpg --server-side-encryption "AES256"
VPC 端点策略允许的访问权限
如果 IAM 用户使用 Amazon Elastic Compute Cloud (Amazon EC2) 实例将对象上传到 Amazon S3,并且该实例通过 VPC 端点路由到 Amazon S3,则必须检查 VPC 端点策略。确保端点策略允许上传到您的存储桶。
例如,以下 VPC 端点策略仅允许访问 DOC-EXAMPLE-BUCKET。如果您的存储桶未被列为允许的资源,则用户无法使用 VPC 中的实例上传到您的存储桶。
{ "Statement": [{ "Sid": "Access-to-specific-bucket-only", "Principal": "*", "Action": [ "s3:PutObject" ], "Effect": "Allow", "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*" }] }
此外,如果用户上传带有 ACL 的对象,则 VPC 端点策略还必须授予对 s3:PutObjectAcl 操作的访问权限,类似于以下内容:
{ "Statement": [{ "Sid": "Access-to-specific-bucket-only", "Principal": "*", "Action": [ "s3:PutObject", "s3:PutObjectAcl", ], "Effect": "Allow", "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*" }] }
AWS KMS 加密
根据您收到的错误消息,更新您的 IAM 用户或角色的 AWS KMS 权限。要解决这些 Access Denied 错误,请参阅当我将文件上传到使用 AWS KMS 默认加密的 Amazon S3 存储桶时,为什么会收到“Access Denied”错误消息?
**重要事项:**如果 AWS KMS 密钥和 IAM 角色属于不同的 AWS 账户,则必须更新 IAM 策略和 KMS 密钥策略。确保将 KMS 权限添加到 IAM 策略和 KMS 密钥策略中。此外,如果跨账户 IAM 主体正在上传对象,则别名为“aws/s3”的 AWS KMS 密钥不能用于默认存储桶加密。任何配置为使用适用于 SSE-KMS 的 S3 存储桶密钥的对象上传、复制或存储桶都必须具有对 kms:Decrypt 的访问权限。有关 AWS KMS 密钥和策略管理的详细信息,请参阅使用具有 AWS KMS 密钥的服务器端加密 (SSE-KMS)。

