AWS S3预签名POST上传报public-read策略校验失败AccessDenied如何解决?
错误根因
该报错说明预签名POST的策略中约定了上传请求必须携带acl: public-read的字段,但实际请求要么未携带该字段、要么S3桶配置不允许设置public-read的ACL、要么对应IAM账号没有设置对象ACL的权限。
排查解决步骤
检查前端上传逻辑
后端返回的预签名POST参数中包含了所有约定的表单字段(含acl、policy、signature等),前端提交上传表单时必须完整带上所有返回的fields,不能漏传或修改acl字段的值,否则会触发策略校验失败。调整S3桶的ACL相关配置
2023年之后新建的S3桶默认禁用ACL、开启公共访问拦截,你需要进入S3桶的「权限」页面调整两项配置:- 关闭「阻止公共访问」设置中与公共ACL拦截相关的两项规则:
阻止新的公共ACL并授予对桶和对象的公共访问权限、阻止对桶和对象的公共ACL访问 - 找到「对象所有权」设置,开启ACL功能,可选「桶所有者首选」或「对象写入者」模式,未开启ACL时设置
public-read的请求会被直接拦截。
- 关闭「阻止公共访问」设置中与公共ACL拦截相关的两项规则:
补全IAM权限
你当前的IAM策略仅配置了对象读写权限,要修改对象ACL还需要新增s3:PutObjectAcl权限,修改后的策略如下:{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:PutObjectAcl" ], "Resource": "arn:aws:s3:::bucket-name/*" } ] }替代方案(无需配置ACL)
如果你不需要通过ACL控制对象权限,可以直接删除预签名生成逻辑中所有和acl相关的配置,同时给S3桶配置桶策略开放对象读权限,即可实现相同的公开访问效果,修改后的预签名代码如下:const params ={ Bucket:'bucket-name', Fields:{ key:'key-name' }, Expires:30*600 }; s3.createPresignedPost(params,(error,data) =>{ console.log(error) res.send(data) })
内容的提问来源于stack exchange,提问作者Shahda
相关产品推荐
相关产品推荐

