AWS中基于Cognito角色控制API Gateway访问权限问题求助
针对你遇到的两个问题,我来一步步拆解并给出可行的解决方案:
一、为什么最初给Cognito组关联的IAM角色加策略无效?
你一开始的思路误区在于:Cognito组关联的IAM角色是用来让用户访问其他AWS服务(比如S3、DynamoDB)的,而不是用来控制API Gateway的访问权限的。当你使用Cognito JWT授权器时,API Gateway只是验证JWT的有效性(签名、过期时间等),并不会去关联这个IAM角色来做权限判断。
要通过Cognito组限制API访问,有两种更直接的方式:
方式1:在API Gateway层面配置资源策略
你可以给API Gateway添加资源策略,基于用户的Cognito组来允许/拒绝访问。比如如果要拒绝ROLE_ADMIN组访问某个GET接口,策略可以这么写:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Deny", "Principal": { "Federated": "cognito-idp:ap-south-1:你的AWS账号ID:userpool/你的用户池ID" }, "Action": "execute-api:Invoke", "Resource": "arn:aws:execute-api:ap-south-1:你的AWS账号ID:09bccr0/*/GET/你的资源路径", "Condition": { "StringEquals": { "cognito:groups": "ROLE_ADMIN" } } } ] }
注意替换里面的账号ID、用户池ID、API ID和资源路径,这样就能精准限制指定组的用户访问特定API。
方式2:在Spring Boot代码中用Spring Security校验Cognito组
既然你用的是Spring Boot,更推荐在代码层面做权限控制,灵活性更高。步骤如下:
- 确保你的Spring Security配置能解析Cognito JWT,提取
cognito:groups声明作为用户权限。 - 配置
JwtAuthenticationConverter来转换groups为权限:
@Bean public JwtAuthenticationConverter jwtAuthenticationConverter() { JwtGrantedAuthoritiesConverter grantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter(); grantedAuthoritiesConverter.setAuthoritiesClaimName("cognito:groups"); grantedAuthoritiesConverter.setAuthorityPrefix("ROLE_"); JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter(); jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(grantedAuthoritiesConverter); return jwtAuthenticationConverter; }
- 在需要限制的接口上添加注解:
@PreAuthorize("hasAuthority('ROLE_ADMIN')") // 只允许ROLE_ADMIN组的用户访问 @GetMapping("/admin-only") public ResponseEntity<String> adminOnly() { return ResponseEntity.ok("Admin content"); }
二、转用Identity Pool+IAM授权器后Postman调用返回Forbidden的解决方案
如果你坚持要用IAM授权器,那需要检查以下几个关键点:
1. 确认Identity Pool的角色映射配置
- 打开Identity Pool的控制台,进入身份验证提供者 -> Cognito,确保用户池和客户端ID正确关联。
- 进入角色映射,确认你已经为Cognito的ROLE_ADMIN组配置了对应的IAM角色(比如你的ROLE_ADMIN_IAM),而不是用默认的认证用户角色。
2. 确保IAM角色有API Gateway调用权限
给你的IAM角色(比如ROLE_ADMIN_IAM)附加允许调用API Gateway的策略:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "execute-api:Invoke", "Resource": "arn:aws:execute-api:ap-south-1:你的AWS账号ID:09bccr0/*/*/*" } ] }
3. Postman的AWS Signature配置要完整
很多人在这里踩坑:临时凭证需要三个部分:AccessKey、SecretKey和Session Token,Postman里必须把Session Token填到AWS Session Token字段里!
- 打开Postman的请求,切换到Authorization标签,类型选AWS Signature。
- 填入你的临时AccessKey、SecretKey,Session Token(从Amplify获取的凭证里的
sessionToken字段)。 - 区域选
ap-south-1,服务名称填execute-api。 - 确保请求的方法和路径和IAM策略里的Resource匹配。
4. 检查API Gateway的资源策略
如果API Gateway本身有资源策略,要确保它没有拒绝该IAM角色的访问。比如资源策略里要允许对应的角色调用API。
总结一下:如果是Spring Boot应用,更推荐用Cognito JWT授权器 + Spring Security组校验的方案,既符合Java生态的开发习惯,又不需要额外配置Identity Pool和IAM授权器,效率更高。
内容的提问来源于stack exchange,提问作者user5669842

