You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 18:27:18