Skip to content

Spring Security 6.0 JWT配置迁移指南

问题描述

在 Spring Security 6.0 中,大量旧版 API 被废弃并移除,主要涉及两个关键变化:

  1. ☠️ OAuth2ResourceServerConfigurer::jwt 方法已被废弃
  2. ☠️ antMatchers()mvcMatchers()regexMatchers() 等请求匹配方法已被移除

传统配置方式已无法正常工作:

java
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    // 已废弃的方法
    http.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
    
    // 已移除的方法
    http.authorizeHttpRequests(requests -> requests
        .antMatchers("/public/**").permitAll()
        .anyRequest().authenticated()
    );
    
    return http.build();
}

这些问题会导致编译失败或运行时错误,需要进行相应迁移。

迁移时机

Spring 官方建议先升级到 Spring Security 5.8 版本,解决废弃API警告后再升级到6.0,以减少迁移冲击。

解决方案

1. JWT资源配置迁移

使用 Lambda DSL 替代废弃的 OAuth2ResourceServerConfigurer::jwt 方法:

java
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http.authorizeHttpRequests((requests) -> requests
        .anyRequest().authenticated()
    );
    http.sessionManagement((session) -> session
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
    );
    http.oauth2ResourceServer(oauth2 -> oauth2
        .jwt(Customizer.withDefaults()) // 迁移方案
    );
    return http.build();
}

注意事项

Customizer.withDefaults() 仅适用于标准配置。如需自定义设置,需提供 JwtDecoder 实例

完整配置示例(包含JWT解码器):

java
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http.oauth2ResourceServer(oauth2 -> oauth2
        .jwt(jwt -> jwt.decoder(jwtDecoder()) // 自定义解码器
    );
    return http.build();
}

@Bean
public JwtDecoder jwtDecoder() {
    // 从授权服务器获取JWK Set
    return NimbusJwtDecoder.withJwkSetUri("https://auth-server/.well-known/jwks.json").build();
}

2. 请求匹配器迁移

废弃的 antMatchers() 等API已被 requestMatchers() 统一替代:

java
http.authorizeHttpRequests(auth -> auth
    .requestMatchers("/public/**").permitAll()
    .requestMatchers("/admin/**").hasRole("ADMIN")
    .anyRequest().authenticated()
);

匹配器类型对照表

废弃方法替代方案示例
antMatchers("/path")requestMatchers("/path").requestMatchers("/api/public/**")
mvcMatchers("/path")requestMatchers("/path").requestMatchers("/static/**")
regexMatchers(".*")requestMatchers("/regex").requestMatchers(HttpMethod.GET, "/data")

Kotlin DSL 配置示例

kotlin
@Bean
fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
    http.authorizeHttpRequests { auth ->
        auth.requestMatchers("/public/**").permitAll()
            .anyRequest().authenticated()
    }
    http.oauth2ResourceServer { oauth2 -> 
        oauth2.jwt(Customizer.withDefaults()) 
    }
    return http.build()
}

完整安全配置示例

java
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http
        // 会话管理
        .sessionManagement(session -> session
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        )
        // 资源服务器配置
        .oauth2ResourceServer(oauth2 -> oauth2
            .jwt(jwt -> jwt.decoder(jwtDecoder())
        )
        // 请求授权配置
        .authorizeHttpRequests(auth -> auth
            .requestMatchers("/auth/login", "/public/**").permitAll()
            .requestMatchers("/admin/**").hasRole("ADMIN")
            .anyRequest().authenticated()
        )
        // 禁用CSRF(无状态API不需要)
        .csrf(csrf -> csrf.disable());
    
    return http.build();
}

@Value("${jwk.set.uri}")
private String jwkSetUri;

@Bean
public JwtDecoder jwtDecoder() {
    return NimbusJwtDecoder.withJwkSetUri(jwkSetUri).build();
}

迁移注意事项

  1. 版本兼容性

    • 确保使用 Spring Boot 3.x+ 和 Spring Security 6.x+
    • 检查所有安全相关依赖的兼容性
  2. 迁移步骤

  3. 测试要点

    • 验证JWT认证流程
    • 测试不同角色的端点访问控制
    • 检查公共端点是否可无认证访问

HTTP GET还是POST?

在配置安全规则时,明确指定请求方法可避免混淆:

java
.requestMatchers(HttpMethod.GET, "/api/read")
.requestMatchers(HttpMethod.POST, "/api/write")

遵循这些迁移原则和实践,您可以顺利完成 Spring Security 5.x 到 6.0 的平稳升级,充分利用新版本的安全特性和性能优化。