AWS S3添加aws:Referer语句后ListObjects报403 Forbidden问题
解决AWS S3添加aws:Referer策略后ListObjects接口403的问题
这个问题的核心原因很明确:当你使用AWS SDK调用ListObjects这类API时,SDK默认不会在HTTP请求中携带Referer头,而你添加的存储桶策略要求请求必须匹配指定的aws:Referer条件,因此请求被拒绝,返回403 Forbidden。
下面给你几个可行的解决思路:
1. 给SDK请求手动添加Referer头
既然策略要求必须有符合条件的Referer,那我们可以在调用SDK的时候主动添加这个请求头。以你提供的PHP代码为例,只需在listObjects的参数中加入@http配置来指定请求头:
try { $result = $this->s3->listObjects([ 'Bucket' => $this->bucket, '@http' => [ 'headers' => [ 'Referer' => 'http://myLocalSite.vagrant' ] ] ]); echo "Keys retrieved!" . PHP_EOL; foreach ($result['Contents'] as $object) { echo $object['Key'] . PHP_EOL; } } catch (S3Exception $e) { echo $e->getMessage() . PHP_EOL; }
这样请求就会携带符合策略要求的Referer头,就能通过权限校验了。
2. 调整存储桶策略,区分浏览器和SDK请求
如果你的Referer限制只是为了防止浏览器直接访问存储桶内容,但SDK需要不受限制地执行List/操作,那可以把策略拆分成两个独立的Statement:
- 一个Statement专门针对浏览器的
Get*操作,保留Referer限制; - 另一个Statement针对SDK使用的IAM用户/角色,开放所有需要的操作,且不设置Referer条件。
示例策略如下:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowBrowserGetWithReferer", "Effect": "Allow", "Principal": "*", "Action": ["s3:Get*"], "Resource": ["arn:aws:s3:::MyBucketName/*"], "Condition": { "StringLike": { "aws:Referer": [ "http://myLocalSite.vagrant", "http://myLocalSite.vagrant/*" ] } } }, { "Sid": "AllowSDKOperations", "Effect": "Allow", "Principal": {"AWS": "arn:aws:iam::123456789012:user/YourSDKServiceUser"}, "Action": [ "s3:CreateBucket", "s3:DeleteObject", "s3:Put*", "s3:Get*", "s3:List*" ], "Resource": [ "arn:aws:s3:::MyBucketName", "arn:aws:s3:::MyBucketName/*" ] } ] }
注意替换YourSDKServiceUser为你实际使用的IAM用户ARN,这样SDK用这个用户身份调用API时,就不受Referer限制了。
3. 检查IAM权限与桶策略的组合逻辑
别忘了,AWS的权限是IAM权限和桶策略的逻辑与——两者都必须允许操作才能成功。所以要确保你SDK使用的IAM用户/角色本身已经被授予了s3:ListBucket等相关权限,避免因为IAM权限不足导致的403(虽然你的问题是加了Referer才出现,但这个点也值得确认)。
内容的提问来源于stack exchange,提问作者badcrocodile
相关产品推荐
相关产品推荐

