AWS S3异常:GetObject正常但GetObjectAttributes返回访问拒绝
问题分析与解决:S3 GetObjectAttributes返回Access Denied但GetObject正常
问题场景
配置了CloudFront的S3存储桶,服务器直接访问S3时:
GetObject接口可正常获取完整对象GetObjectAttributes接口返回Access Denied错误
当前桶配置:
- 开启「Block all public access」
- 桶策略已允许CloudFront服务主体和账户root用户执行
s3:GetObject、s3:GetObjectAttributes操作
桶策略代码:
{ "Version": "2008-10-17", "Id": "PolicyForCloudFrontPrivateContent", "Statement": [ { "Sid": "AllowCloudFrontServicePrincipal", "Effect": "Allow", "Principal": { "Service": "cloudfront.amazonaws.com" }, "Action": [ "s3:GetObject", "s3:GetObjectAttributes" ], "Resource": "arn:aws:s3:::XX/*", "Condition": { "StringEquals": { "AWS:SourceArn": "arn:aws:cloudfront::ACCOUNTID:distribution/DISTRIBUTION" } } }, { "Sid": "AllowServerAccess", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::ACCOUNTID:root" }, "Action": [ "s3:GetObject", "s3:GetObjectAttributes" ], "Resource": "arn:aws:s3:::XX/*" } ] }
正常调用代码(GetObject):
let result = self .aws_s3_client .get_object() .bucket(&*common::properties::AWS_S3_BUCKET_NAME) .key(&path) .send() .await;
失败调用代码(GetObjectAttributes):
let result = self .aws_s3_client .get_object_attributes() .bucket(&*common::properties::AWS_S3_BUCKET_NAME) .key(&path) .send() .await;
核心原因
最常见的问题是服务器使用的IAM身份并非账户root用户,导致桶策略中AllowServerAccess语句的Principal不匹配,权限未生效。
虽然GetObject正常,但可能是该IAM身份通过其他途径(如IAM角色权限、其他桶策略)获得了GetObject权限,而GetObjectAttributes没有对应的授权。
解决方案
1. 修正桶策略的Principal匹配
如果服务器使用的是特定IAM角色/用户(而非root),将桶策略中AllowServerAccess的Principal替换为该IAM实体的ARN:
{ "Sid": "AllowServerAccess", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::ACCOUNTID:role/YourServerExecutionRole" // 替换为实际IAM角色/用户ARN }, "Action": [ "s3:GetObject", "s3:GetObjectAttributes" ], "Resource": "arn:aws:s3:::XX/*" }
2. 为服务器IAM身份添加直接权限
在IAM控制台找到服务器使用的角色/用户,添加一条IAM权限策略,明确授予s3:GetObjectAttributes权限:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:GetObjectAttributes", "Resource": "arn:aws:s3:::XX/*" } ] }
3. 检查API调用参数(可选)
GetObjectAttributes默认需要指定要获取的对象属性(如ETag、Size),虽然参数缺失通常返回InvalidRequest而非Access Denied,但可以补充参数排除问题:
use aws_sdk_s3::types::ObjectAttribute; let result = self .aws_s3_client .get_object_attributes() .bucket(&*common::properties::AWS_S3_BUCKET_NAME) .key(&path) .object_attributes(vec![ObjectAttribute::ETag, ObjectAttribute::Size]) // 指定需要的属性 .send() .await;
4. 排查拒绝策略
检查服务器的IAM实体是否存在任何拒绝s3:GetObjectAttributes的策略,以及账户级别的IAM策略是否有相关限制。
内容的提问来源于stack exchange,提问作者J. Doe
相关产品推荐
相关产品推荐

