使用CloudFront的AWS S3 Bucket无法删除对象问题排查
问题描述
我尝试在网站中添加删除关联CloudFront的AWS S3 Bucket对象的功能,但执行时提示“Attempting to delete * Error Access Denied”。奇怪的是,我使用类似代码可以正常上传文件,且上传的对象采用SSE-S3加密。
用于删除对象的PHP代码:
require './vendor/autoload.php'; use Aws\S3\S3Client; use Aws\S3\Exception\S3Exception; $bucket = '-'; $keyname = $_POST['-']; $IAM_KEY = '-'; $IAM_SECRET = '-'; try { $s3 = S3Client::factory( array( 'credentials' => array( 'key' => $IAM_KEY, 'secret' => $IAM_SECRET ), 'version' => 'latest', 'region' => 'eu-west-2' ) ); } catch (Exception $e) { die("Error: " . $e->getMessage()); } // 1. Delete the object from the bucket. try { echo 'Attempting to delete ' . $keyname . '...' . PHP_EOL; $result = $s3->deleteObject([ 'Bucket' => $bucket, 'Key' => $keyname ]); if ($result['DeleteMarker']) { echo $keyname . ' was deleted or does not exist.' . PHP_EOL; } else { exit('Error: ' . $keyname . ' was not deleted.' . PHP_EOL); } } catch (S3Exception $e) { exit('Error: ' . $e->getAwsErrorMessage() . PHP_EOL); } // 2. Check to see if the object was deleted. try { echo 'Checking to see if ' . $keyname . ' still exists...' . PHP_EOL; $result = $s3->getObject([ 'Bucket' => $bucket, 'Key' => $keyname ]); echo 'Error: ' . $keyname . ' still exists.'; } catch (S3Exception $e) { exit($e->getAwsErrorMessage()); }
Bucket策略:
{ "Version": "2008-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity -" }, "Action": [ "s3:PutObject", "s3:PutObjectAcl", "s3:GetObject", "s3:GetObjectAcl", "s3:GetObjectVersion", "s3:DeleteObject", "s3:DeleteObjectVersion" ], "Resource": "arn:aws:s3:::-/*" } ] }
CORS配置:
[ { "AllowedHeaders": [ "*" ], "AllowedMethods": [ "GET", "PUT", "DELETE" ], "AllowedOrigins": [ "*" ], "ExposeHeaders": [ "ETag" ] } ]
IAM密钥对应的权限策略:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:ListAllMyBuckets", "s3:PutObject", "s3:GetObject" ], "Resource": [ "arn:aws:s3:::*" ] } ] }
我已提供IAM密钥和密钥,且Bucket策略允许删除操作,为何仍会出现该错误?
解决方案
问题出在两个核心点:
- 代码使用IAM用户凭证直接调用S3接口,但该IAM用户的权限策略中缺少
s3:DeleteObject权限——上传能成功是因为权限里有s3:PutObject,但删除需要单独授权。 - 配置的Bucket策略是给CloudFront Origin Access Identity(OAI)授权的,而代码并没有通过OAI访问S3,所以这个Bucket策略的删除权限对当前代码调用完全无效。
具体修复步骤
- 更新IAM用户的权限策略,添加
s3:DeleteObject动作:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:ListAllMyBuckets", "s3:PutObject", "s3:GetObject", "s3:DeleteObject" // 新增删除权限 ], "Resource": [ "arn:aws:s3:::*" ] } ] }
- 额外检查项:
- 确认
$keyname获取的对象路径正确,避免因路径错误导致的权限报错(部分场景下对象不存在会返回Access Denied而非明确的不存在提示) - SSE-S3加密不会影响删除操作,无需额外配置加密相关权限
- 确认
内容的提问来源于stack exchange,提问作者Sprite
相关产品推荐
相关产品推荐

