1. 概述
Spring Security 6 带来了重大变革,包括移除废弃类和方法、引入新特性等。从 Spring Security 5 迁移到 6 可以采用渐进式方式,避免破坏现有代码。此外,我们还能借助 OpenRewrite 这类第三方工具加速迁移过程。
本文将手把手教你如何将 Spring Security 5 应用迁移到 Spring Security 6,重点包括:
- 替换所有废弃方法
- 使用 Lambda DSL 简化配置
- 通过 OpenRewrite 实现自动化迁移
⚠️ 注意:迁移前请确保你的代码库已做好版本兼容性准备。
2. Spring Security 与 Spring Boot 版本关系
Spring Boot 基于 Spring 框架,其版本直接决定了依赖的 Spring 框架版本:
- Spring Boot 2 默认使用 Spring Security 5
- Spring Boot 3 默认使用 Spring Security 6
在 Spring Boot 项目中,我们通常通过 pom.xml
添加 spring-boot-starter-security
依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
但可通过 properties
覆盖默认版本:
<properties>
<spring-security.version>5.8.9</spring-security.version>
</properties>
这里强制指定使用 Spring Security 5.8.9,覆盖了 Spring Boot 的默认版本。
✅ 小技巧:你甚至可以在 Spring Boot 2 中使用 Spring Security 6,只需在 properties
中指定版本即可。
3. Spring Security 6 核心变化
Spring Security 6 引入多项重要改进:
- 最低要求 Java 17
- 使用
jakarta
命名空间 - **彻底移除
WebSecurityConfigurerAdapter
**,改用组件化配置 authorizeRequests()
被authorizeHttpRequests()
替代- **新增
requestMatcher()
和securityMatcher()
**,替代antMatcher()
和mvcMatcher()
cors()
和csrf()
等方法提供函数式风格替代方案
⚠️ 关键变化:requestMatcher()
会自动选择合适的 RequestMatcher
实现,比旧方法更安全可靠。
4. 项目初始化配置
先创建一个基于 Spring Boot 2.7.5 的项目,添加依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>2.7.5</version>
</dependency>
创建安全配置类 WebSecurityConfig
:
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
class WebSecurityConfig extends WebSecurityConfigurerAdapter {
}
这里通过 @EnableWebSecurity
启用 Web 安全配置,@EnableGlobalMethodSecurity
开启方法级授权。
定义内存用户认证:
@Override
void configure(AuthenticationManagerBuilder auth) throws Exception {
UserDetails user = User.withDefaultPasswordEncoder()
.username("Admin")
.password("password")
.roles("ADMIN")
.build();
auth.inMemoryAuthentication().withUser(user);
}
忽略静态资源安全检查:
@Override
void configure(WebSecurity web) {
web.ignoring().antMatchers("/js/**", "/css/**");
}
配置 HTTP 安全规则:
@Override
void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.httpBasic();
}
这是典型的 Spring Security 5 配置,后续我们将把它迁移到 Spring Security 6。
5. 迁移到 Spring Security 6
Spring 官方推荐渐进式迁移策略: 先升级到 Spring Security 5.8.5,适配新特性后再升级到 6.x。IDE 会提示废弃方法,帮助逐步迁移。
为简化演示,我们直接升级到 Spring Boot 3.2.2(内置 Spring Security 6)。修改 pom.xml
:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.2.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>3.2.2</version>
</dependency>
⚠️ 注意:Spring Boot 3 要求 Java 17+。
接下来逐步重构代码:
5.1. @Configuration 注解变化
Spring Security 6 中 @Configuration
不再包含在 @EnableWebSecurity
中,需显式添加:
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
}
关键变化:
- 必须显式添加
@Configuration
@EnableGlobalMethodSecurity
被废弃,替换为@EnableMethodSecurity
- 新注解默认开启
@PreAuthorize
/@PostAuthorize
支持
5.2. 移除 WebSecurityConfigurerAdapter
彻底移除 WebSecurityConfigurerAdapter
,改用组件化配置:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
}
替代方案:
- 注册
WebSecurityCustomizer
Bean 配置 Web 安全 - 注册
SecurityFilterChain
Bean 配置 HTTP 安全 - 注册
InMemoryUserDetailsManager
Bean 管理用户
5.3. WebSecurityCustomizer Bean
将静态资源忽略逻辑改为注册 WebSecurityCustomizer
Bean:
@Bean
WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring().requestMatchers("/js/**", "/css/**");
}
✅ 优势:比旧版 configure(WebSecurity web)
更符合 Spring 6 的函数式风格。
5.4. 认证管理器 Bean
重构内存用户认证,改用 InMemoryUserDetailsManager
Bean:
@Bean
InMemoryUserDetailsManager userDetailsService() {
UserDetails user = User.withDefaultPasswordEncoder()
.username("Admin")
.password("admin")
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
❌ 踩坑点:角色名称从 ADMIN
改为 USER
(示例调整),实际迁移时请保持业务逻辑一致。
5.5. HTTP 安全配置
用 SecurityFilterChain
Bean 替代旧的 configure(HttpSecurity http)
:
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(
request -> request
.requestMatchers("/").permitAll()
.anyRequest().authenticated()
)
.formLogin(Customizer.withDefaults())
.httpBasic(Customizer.withDefaults());
return http.build();
}
核心改进:
authorizeRequests()
→authorizeHttpRequests()
- 使用
AuthorizationManager
API 提升性能 - 延迟认证查询(仅在需要授权时执行)
requestMatchers()
替代antMatcher()
/mvcMatcher()
Customizer.withDefaults()
应用默认配置
5.6. RequestCache 优化
Spring Security 6 对请求缓存机制做了性能优化:
- 旧版:每次请求都检查
HttpSession
中是否有缓存请求 - 新版:仅当请求包含
continue
参数时才检查缓存
这显著减少了不必要的 HttpSession
读取操作,提升整体性能。
6. 使用 OpenRewrite 自动迁移
OpenRewrite 可自动化迁移到 Spring Boot 3(内置 Spring Security 6)。添加插件:
<plugin>
<groupId>org.openrewrite.maven</groupId>
<artifactId>rewrite-maven-plugin</artifactId>
<version>5.23.1</version>
<configuration>
<activeRecipes>
<recipe>org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_0</recipe>
</activeRecipes>
</configuration>
<dependencies>
<dependency>
<groupId>org.openrewrite.recipe</groupId>
<artifactId>rewrite-spring</artifactId>
<version>5.5.0</version>
</dependency>
</dependencies>
</plugin>
执行迁移命令:
$ mvn rewrite:run
⚠️ 注意:当前版本不会自动转换为 Lambda DSL 风格,未来版本可能支持。
7. 总结
我们完整演示了从 Spring Security 5 到 6 的迁移过程,核心步骤包括:
- 升级 Spring Boot 到 3.x
- 移除
WebSecurityConfigurerAdapter
- 采用组件化 Bean 配置
- 使用新的
authorizeHttpRequests()
和requestMatchers()
- 利用 OpenRewrite 自动化基础迁移
迁移后代码更简洁、性能更优,且符合 Spring 6 的最佳实践。完整示例代码见 GitHub。