Java授权Lambda生成S3访问策略遇403拒绝,请求协助排查
让我帮你梳理几个大概率导致这个授权失败的配置遗漏点,结合你给出的策略内容来看:
1. 策略中Statement的格式错误
这是最常见的坑!API Gateway要求授权策略里的Statement必须是数组类型,但你的策略里把它写成了单个对象。比如你当前的写法是:
{ "Version": "2012-10-17", "Statement": { "Action": "s3:*", "Resource": [ "arn:aws:s3:::{mybucket}/" ], "Effect": "Allow", "Sid": "statement1" } }
正确的格式应该把Statement改成数组:
{ "Version": "2012-10-17", "Statement": [ { "Action": "s3:*", "Resource": [ "arn:aws:s3:::{mybucket}/*" ], "Effect": "Allow", "Sid": "statement1" } ] }
API Gateway会因为格式不规范直接拒绝授权,哪怕策略内容本身是对的。
2. S3资源ARN的范围不对
你的策略里的资源是arn:aws:s3:::{mybucket}/,这个格式只匹配桶本身(而且末尾的斜杠其实是多余的,桶的标准ARN是arn:aws:s3:::{mybucket})。但你要授权的是上传/获取文件,也就是S3对象级别的操作,所以需要把资源范围扩展到桶内的对象,应该写成arn:aws:s3:::{mybucket}/*。如果只授权桶本身,那只能执行桶级操作(比如创建、删除桶),完全覆盖不了文件的上传下载。
3. 占位符未正确替换
要确认你的Java代码里是否把{mybucket}替换成了真实的S3桶名。如果Lambda返回的策略里还是保留着{mybucket}这个占位符,AWS会认为这个资源不存在,自然会判定客户端未授权。
4. Lambda授权器的触发权限配置
虽然概率稍低,但也要检查:
- API Gateway的授权器配置是否正确关联了你的Lambda函数
- Lambda函数的资源策略是否允许API Gateway服务调用它(可以在Lambda控制台的「配置」→「权限」→「资源策略」里查看)
5. API Gateway集成的角色权限(如果是直接集成S3)
如果你是通过API Gateway直接集成S3来处理上传/下载,那API Gateway的执行角色需要有对应的S3操作权限(比如s3:PutObject、s3:GetObject)。不过你的错误提示是客户端未授权,所以前面几个点的优先级更高,可以先排查前面的问题。
先从Statement的数组格式和资源ARN这两点入手修改,应该能解决大部分问题。
内容的提问来源于stack exchange,提问作者Afsi

