Spring Boot集成AWS Cognito携带有效AccessToken访问接口返回401错误
Spring Boot 接入 Cognito 携带 Token 访问接口返回 401 修复方案
核心问题排查点
返回401基本由以下几个配置/依赖错误导致,按优先级逐一修复即可:
- 依赖缺失+重复依赖:pom.xml中重复引入了2次
spring-boot-starter-security,同时缺少JWT验签必需的spring-security-oauth2-jose依赖,没有这个依赖资源服务器根本无法解析、校验Cognito颁发的JWT签名,所有带Token的请求都会直接被判定为无效。 - issuer-uri配置错误:配置的资源服务器issuer-uri为
https://cognito-idp.eu-west-2.amazonaws.com/eu-west-XXXX,但配置的用户池ID是eu-west-XXX,多打了一个X,导致Spring Security无法拉取到正确的Cognito JWK公钥集,验签必然失败。 - Token类型传错:Cognito登录后会返回
AccessToken、IdToken、RefreshToken三类Token,资源服务器默认校验AccessToken,如果传了IdToken大概率会因为aud、iss claim不匹配被拦截。 - 无效的冗余配置:配置的
spring.security.oauth2.client.*相关配置是OAuth2客户端(即应用作为第三方客户端去请求Cognito)用的,当前场景是做资源服务器校验Token,这部分配置完全没用,反而可能干扰自动配置。
修复步骤
1. 修正Maven依赖
删除重复的security starter,补上缺失的JWT验签依赖,如果使用Spring Boot官方父工程管理依赖,不需要手动指定依赖版本,避免版本冲突:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-oauth2-resource-server</artifactId> </dependency> <!-- 缺失的JWT核心验签依赖,必须添加 --> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-oauth2-jose</artifactId> </dependency> <!-- 如果确实用到Spring Cloud AWS的Cognito集成能力再保留,否则可以删除 --> <dependency> <groupId>io.awspring.cloud</groupId> <artifactId>spring-cloud-starter-aws-security</artifactId> </dependency> </dependencies>
2. 修正配置文件
最稳妥的issuer-uri获取方式是:随便拿一个登录返回的AccessToken,解析后查看payload中的iss字段值,原封不动复制到配置中,不要手动拼接避免出错。修正后的配置参考:
# Cognito基础配置,替换成实际参数 spring.cloud.aws.security.cognito.app-client-id=替换为你的实际App Client ID spring.cloud.aws.security.cognito.region=eu-west-2 spring.cloud.aws.security.cognito.user-pool-id=替换为你的实际用户池ID,比如eu-west-xxxxxx # 资源服务器JWT配置,issuer-uri必须和Token内的iss字段完全一致 spring.security.oauth2.resourceserver.jwt.issuer-uri=替换为你从Token中复制的iss值,格式为https://cognito-idp.区域.amazonaws.com/用户池ID # 删除冗余的OAuth2客户端配置,当前场景不需要 # spring.security.oauth2.client.registration.cognito.client-id=XXX # spring.security.oauth2.client.provider.cognito.issuer-uri=XXX
注意:如果给Cognito用户池配置了自定义域名,这里的issuer-uri必须用自定义域名对应的地址,不能用AWS默认的域名地址。
3. 校验请求格式
访问受保护接口时,确保请求头格式完全符合规范:
Authorization: Bearer 你登录拿到的AccessToken字符串
Bearer和Token之间必须有一个半角空格- 不要传IdToken或者RefreshToken,必须传登录返回的
AccessToken
4. 细节问题排查
如果以上配置改完还是返回401,在配置文件中加一行日志配置,重启应用后发请求看控制台的Security报错日志,能直接定位具体原因:
logging.level.org.springframework.security=DEBUG
常见的日志报错对应原因:
Jwt signature does not match:issuer-uri配置错误,拉取到的公钥和Token签名不匹配Jwt expired:Token已经过了有效期,重新登录获取新TokenInvalid aud claim:Token对应的客户端ID和配置的Cognito App Client不匹配
当前写的SecurityConfig配置本身没有语法问题,以上问题修复后就能正常校验Token通过认证。
内容的提问来源于stack exchange,提问作者WebDev1
相关产品推荐
相关产品推荐

