Spring Security 6.0 JWT配置迁移指南
问题描述
在 Spring Security 6.0 中,大量旧版 API 被废弃并移除,主要涉及两个关键变化:
- ☠️
OAuth2ResourceServerConfigurer::jwt
方法已被废弃 - ☠️
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();
}
迁移注意事项
版本兼容性:
- 确保使用 Spring Boot 3.x+ 和 Spring Security 6.x+
- 检查所有安全相关依赖的兼容性
迁移步骤:
测试要点:
- 验证JWT认证流程
- 测试不同角色的端点访问控制
- 检查公共端点是否可无认证访问
HTTP GET还是POST?
在配置安全规则时,明确指定请求方法可避免混淆:
java
.requestMatchers(HttpMethod.GET, "/api/read")
.requestMatchers(HttpMethod.POST, "/api/write")
遵循这些迁移原则和实践,您可以顺利完成 Spring Security 5.x 到 6.0 的平稳升级,充分利用新版本的安全特性和性能优化。