Spring OAuth2+Azure AD在AWS Lambda上Token验证失败(401)求助
排查Spring OAuth2 + Azure AD在AWS Lambda上返回401的问题
从本地与AWS Lambda的日志对比来看,核心差异是:本地环境中JwtAuthenticationProvider成功完成Token认证,而Lambda环境中直接进入匿名认证流程,未触发JWT认证逻辑。以下是针对性的排查步骤:
1. 确认请求头是否完整传递到Lambda应用
Lambda的API网关或代理层可能过滤或未转发Authorization请求头,导致Spring Security无法获取Bearer Token。
- 在Controller中添加请求头打印逻辑,验证
Authorization: Bearer <token>是否存在:
@GetMapping("/") public String home(HttpServletRequest request) { Enumeration<String> headerNames = request.getHeaderNames(); while (headerNames.hasMoreElements()) { String name = headerNames.nextElement(); System.out.printf("Header: %s = %s%n", name, request.getHeader(name)); } // 原有业务逻辑 return "home"; }
- 如果
Authorization头缺失,检查API网关配置:- 确保集成请求中设置了转发所有请求头,或显式添加
Authorization头的转发规则 - 若使用Serverless/SAM框架,检查模板文件中API Gateway的
requestParameters配置是否允许传递Authorization头
- 确保集成请求中设置了转发所有请求头,或显式添加
2. 调试JWT认证流程
开启更详细的OAuth2日志,观察Token解析过程:
- 在
application.properties中添加日志配置:
logging.level.org.springframework.security.oauth2=DEBUG logging.level.com.nimbusds=DEBUG
- 手动配置
JwtDecoder并添加验证逻辑,排查解析失败原因:
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Value("${spring.cloud.azure.activedirectory.tenant-id}") private String tenantId; @Value("${spring.cloud.azure.activedirectory.client-id}") private String clientId; @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/").permitAll() .anyRequest().authenticated() .and() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .oauth2ResourceServer().jwt().jwtDecoder(jwtDecoder()); } @Bean public JwtDecoder jwtDecoder() { String issuerUri = String.format("https://login.microsoftonline.com/%s/v2.0", tenantId); NimbusJwtDecoder jwtDecoder = (NimbusJwtDecoder) JwtDecoders.fromOidcIssuerLocation(issuerUri); // 添加自定义验证器,打印调试信息 jwtDecoder.setJwtValidator(new DelegatingOAuth2TokenValidator<>( new JwtTimestampValidator(), new JwtIssuerValidator(issuerUri), token -> { System.out.printf("Token audience: %s%n", token.getAudience()); System.out.printf("Token issuer: %s%n", token.getIssuer()); return OAuth2TokenValidResult.success(); } )); return jwtDecoder; } }
3. 检查依赖打包与环境兼容性
AWS日志中显示Jackson版本为unknown,说明依赖打包可能不完整:
- 确保使用
spring-boot-maven-plugin的repackage目标打包,将所有依赖包含在可执行JAR中 - 若使用Lambda层,确认层包含Spring Cloud Azure、Jackson及OAuth2相关依赖,避免版本冲突
4. 验证配置加载与网络权限
- 打印配置项确认是否正确加载:
@Value("${spring.cloud.azure.activedirectory.client-id}") private String clientId; @Value("${spring.cloud.azure.activedirectory.tenant-id}") private String tenantId; @PostConstruct public void verifyConfig() { System.out.printf("Loaded Client ID: %s%n", clientId); System.out.printf("Loaded Tenant ID: %s%n", tenantId); }
- 确认Lambda有网络权限访问Azure的JWKS端点:
- 若Lambda配置了VPC,需确保安全组和网络ACL允许出站访问HTTPS(443端口)
- 可通过Lambda测试代码发起HTTP请求验证连通性
5. 验证Token有效性
- 使用jwt.io解析Token,检查
iss(发行方)、aud(受众)、exp(过期时间)等字段是否与配置匹配 - 确保Token是针对Lambda部署的API资源(
app-id-uri)颁发的,而非本地环境的资源标识符
内容的提问来源于stack exchange,提问作者Abdul Rais
相关产品推荐
相关产品推荐

