Skip to content

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.x5.8.xJava 8+
3.0.x6.0.xJava 17+
3.1.x6.1.xJava 17+
3.2.x6.2.xJava 17+

面试追问方向

问题考察点延伸阅读
WebSecurityConfigurerAdapter 为什么被移除?版本理解本篇
5.x 到 6.x 有哪些 breaking changes?迁移能力本篇
Lambda DSL 相比之前有什么优势?语法理解本篇
如何从 5.x 迁移到 6.x?迁移能力本篇

总结

Spring Security 6.x 的核心变化:

  1. 移除 WebSecurityConfigurerAdapter:全面转向 @Bean + Lambda DSL
  2. 方法名规范化antMatchers()requestMatchers()
  3. Lambda DSL 成为主流:配置更简洁、可读性更好
  4. 更严格的默认安全策略:CORS/CSRF 需要显式配置
  5. 需要 Java 17+:与 Spring Boot 3.x 同步

建议:新项目直接使用 6.x,老项目按迁移指南逐步升级。


下一步

基于 VitePress 构建