Spring Security 6.x 新特性与重大变更
Spring Security 6.x 是近年来变化最大的版本,移除了一些长期存在的 API,引入了新的配置方式。
如果你还在用 5.x 的配置方式,可能在新版本中会遇到不少 breaking changes。
今天,我们就来全面了解 Spring Security 6.x 的新特性和重大变更。
版本演进概览
┌──────────────────────────────────────────────────────────────────────────┐
│ Spring Security 版本演进 │
├──────────────────────────────────────────────────────────────────────────┤
│ │
│ Spring Security 5.x │
│ ├── 2017 年发布 │
│ ├── WebSecurityConfigurerAdapter 时代 │
│ ├── antMatchers() 命名风格 │
│ └── OAuth2 客户端支持 │
│ │
│ ──────────────────────────────────────────────────────────────────── │
│ │
│ Spring Security 6.0(2022 年 11 月) │
│ ├── ⚠️ 移除 WebSecurityConfigurerAdapter │
│ ├── ⚠️ antMatchers() → requestMatchers() │
│ ├── ⚠️ authorizeRequests() → authorizeHttpRequests() │
│ ├── Lambda DSL 配置成为主流 │
│ └── SessionCreationPolicy 配置方式变更 │
│ │
│ ──────────────────────────────────────────────────────────────────── │
│ │
│ Spring Security 6.1+ │
│ ├── 默认 CORS 配置简化 │
│ ├── 默认 CSRF 配置变更 │
│ └── 持续的性能优化 │
│ │
└──────────────────────────────────────────────────────────────────────────┘重大变更详解
1. 移除 WebSecurityConfigurerAdapter
这是 6.x 最大的 breaking change。
java
// Spring Security 5.x(已废弃)
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated();
}
}
// Spring Security 6.x
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
);
return http.build();
}
}2. 方法名变更
| 5.x 方法 | 6.x 方法 | 说明 |
|---|---|---|
antMatchers() | requestMatchers() | 路径匹配 |
authorizeRequests() | authorizeHttpRequests() | 授权配置 |
csrf().ignoringAntMatchers() | csrf().ignoringRequestMatchers() | CSRF 忽略路径 |
java
// 5.x
.antMatchers("/api/**").permitAll()
.authorizeRequests().antMatchers("/admin/**").hasRole("ADMIN")
// 6.x
.requestMatchers("/api/**").permitAll()
.authorizeHttpRequests().requestMatchers("/admin/**").hasRole("ADMIN")3. SessionCreationPolicy 配置变更
java
// 5.x
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
// 6.x
.sessionManagement(session -> session
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
)Lambda DSL 配置详解
Spring Security 6.x 全面拥抱 Lambda 表达式,配置更加简洁。
基本配置
java
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// 授权配置
.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**").permitAll()
.requestMatchers("/admin/**").hasRole("ADMIN")
.requestMatchers("/api/**").hasAnyRole("USER", "ADMIN")
.anyRequest().authenticated()
)
// 表单登录
.formLogin(form -> form
.loginPage("/login")
.defaultSuccessUrl("/home", true)
.failureUrl("/login?error")
.permitAll()
)
// 登出
.logout(logout -> logout
.logoutUrl("/logout")
.logoutSuccessUrl("/login?logout")
.deleteCookies("JSESSIONID")
)
// Session 管理
.sessionManagement(session -> session
.maximumSessions(1)
.maxSessionsPreventsLogin(true)
)
// CSRF
.csrf(csrf -> csrf.disable());
return http.build();
}
}配置顺序的重要性
Lambda DSL 中,配置顺序会影响匹配结果:
java
http.authorizeHttpRequests(auth -> auth
// 顺序很重要!更具体的路径要放在前面
.requestMatchers("/admin/user/**").hasRole("ADMIN") // 先匹配
.requestMatchers("/admin/**").hasRole("MANAGER") // 后匹配
.requestMatchers("/**").authenticated()
);and() 方法的使用
java
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
)
.formLogin(form -> form
.loginPage("/login")
.permitAll()
)
.logout(logout -> logout.permitAll())
// 使用 and() 连接不同配置块
.and()
.csrf(csrf -> csrf.disable());方法级安全配置变更
@EnableMethodSecurity
java
// 5.x
@EnableGlobalMethodSecurity(
prePostEnabled = true,
securedEnabled = true,
jsr250Enabled = true
)
// 6.x
@EnableMethodSecurity(
prePostEnabled = true,
securedEnabled = true,
jsr250Enabled = true
)方法名变更
java
// 5.x
@PreAuthorize("hasAuthority('ADMIN')")
@Secured({"ADMIN", "USER"})
// 6.x
// 保持不变OAuth2 / OAuth2 Client 变更
OAuth2 Login 配置
java
// 5.x
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.oauth2Login()
.userInfoEndpoint()
.userService(oauth2UserService);
}
}
// 6.x
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.oauth2Login(oauth2 -> oauth2
.userInfoEndpoint(userInfo -> userInfo
.userService(oauth2UserService)
)
.successHandler(oauth2AuthSuccessHandler)
.failureHandler(oauth2AuthFailureHandler)
);
return http.build();
}
}默认安全策略变更
CORS 默认配置
6.x 对 CORS 有更严格的默认配置:
java
// 如果不配置 CORS,默认不允许任何来源
// 必须显式配置 allowedOrigins
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://localhost:3000"));
// ...
}CSRF 默认配置
java
// 6.x 中,CSRF 默认启用
// API 场景需要显式禁用
.csrf(csrf -> csrf.disable())
// 或者配置忽略特定路径
.csrf(csrf -> csrf
.ignoringRequestMatchers("/api/**")
)新增功能
1. 改进的异常处理
java
// 6.x 提供了更细粒度的异常处理
http
.exceptionHandling(ex -> ex
.authenticationEntryPoint((request, response, authException) -> {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
})
.accessDeniedHandler((request, response, accessDeniedException) -> {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
})
);2. 更好的 Lambda 支持
java
// 使用 Customizer 实现更简洁的配置
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**").permitAll()
.anyRequest().authenticated()
)
.formLogin(Customizer.withDefaults())
.logout(Customizer.withDefaults());迁移指南
从 5.x 迁移到 6.x
步骤 1:移除 WebSecurityConfigurerAdapter
java
// Before
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// ...
}
// After
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// 配置移到这里
return http.build();
}
}步骤 2:迁移方法名
java
// Before
.antMatchers() → .requestMatchers()
.authorizeRequests() → .authorizeHttpRequests()
// After
.requestMatchers()
.authorizeHttpRequests()步骤 3:使用 Lambda DSL
java
// Before
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
// After
.sessionManagement(session -> session
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
);步骤 4:更新依赖版本
xml
<!-- 确保使用兼容的 Spring Boot 版本 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.x</version> <!-- 支持 Spring Security 6.x -->
</parent>兼容性矩阵
| Spring Boot 版本 | Spring Security 版本 | Java 版本 |
|---|---|---|
| 2.7.x | 5.8.x | Java 8+ |
| 3.0.x | 6.0.x | Java 17+ |
| 3.1.x | 6.1.x | Java 17+ |
| 3.2.x | 6.2.x | Java 17+ |
面试追问方向
| 问题 | 考察点 | 延伸阅读 |
|---|---|---|
| WebSecurityConfigurerAdapter 为什么被移除? | 版本理解 | 本篇 |
| 5.x 到 6.x 有哪些 breaking changes? | 迁移能力 | 本篇 |
| Lambda DSL 相比之前有什么优势? | 语法理解 | 本篇 |
| 如何从 5.x 迁移到 6.x? | 迁移能力 | 本篇 |
总结
Spring Security 6.x 的核心变化:
- 移除 WebSecurityConfigurerAdapter:全面转向
@Bean+ Lambda DSL - 方法名规范化:
antMatchers()→requestMatchers() - Lambda DSL 成为主流:配置更简洁、可读性更好
- 更严格的默认安全策略:CORS/CSRF 需要显式配置
- 需要 Java 17+:与 Spring Boot 3.x 同步
建议:新项目直接使用 6.x,老项目按迁移指南逐步升级。
下一步
- 想了解完整配置?→ WebSecurityConfigurerAdapter 配置演进
- 想了解更多配置方式?→ 认证与授权核心流程
- 想准备面试?→ Spring Security 面试高频问题汇总
