Skip to content

Spring Boot 3 中 Spring Security 配置迁移

核心问题:Spring Boot 3 移除了 WebSecurityConfigurerAdapter,新的安全配置方式导致特定 URL 无法正确放行(如 OpenAPI 端点)。

问题背景

迁移 Spring Boot 2.7 → 3.x 的安全配置时,经典的 antMatchers() 方法已被废弃。即使按官方推荐替换为 requestMatchers() 后,部分 URL 仍被意外保护。典型场景:

java
@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
    @Bean
    public SecurityFilterChain configure(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(requests -> requests
                .requestMatchers("/openapi/openapi.yml").permitAll() // ❌ 仍被拦截
                .anyRequest().authenticated()
            )
            .httpBasic();
        return http.build();
    }
}

解决方案

方法 1:使用 AntPathRequestMatcher(推荐)

根本原因:直接字符串匹配对某些路径模式不敏感,显式指定匹配器可解决:

java
@Bean
public SecurityFilterChain configure(HttpSecurity http) throws Exception {
    http.authorizeHttpRequests(requests -> requests
            .requestMatchers(new AntPathRequestMatcher("/openapi/openapi.yml")).permitAll()
            .anyRequest().authenticated()
        )
        .httpBasic();
    return http.build();
}

关键说明

  • AntPathRequestMatcher 提供精确的 ANT 风格路径匹配
  • 避免在 Spring Boot RC 版本测试,使用 GA 稳定版(如 3.0.0+)

方法 2:多安全过滤链(复杂场景)

当有大量开放式端点时,可拆分多条过滤链:

java
@Bean
@Order(1) // 低序号优先执行
public SecurityFilterChain publicEndpoints(HttpSecurity http) throws Exception {
    http.securityMatcher("/openapi/**", "/swagger-ui/**")
        .authorizeHttpRequests(requests -> requests
            .anyRequest().permitAll()
        );
    return http.build();
}

@Bean
@Order(2)
public SecurityFilterChain securedEndpoints(HttpSecurity http) throws Exception {
    http.securityMatcher("/**")
        .authorizeHttpRequests(requests -> requests
            .anyRequest().authenticated()
        )
        .httpBasic();
    return http.build();
}

方法 3:Swagger/OpenAPI 最佳配置

需放行常见文档接口时,推荐配置白名单:

java
private static final String[] AUTH_WHITELIST = {
    "/v3/api-docs/**",
    "/swagger-ui/**",
    "/swagger-ui.html",
    "/openapi/**"
};

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http.csrf(AbstractHttpConfigurer::disable)
        .authorizeHttpRequests(auth -> auth
            .requestMatchers(AUTH_WHITELIST).permitAll()
            .anyRequest().authenticated()
        )
        .httpBasic();
    return http.build();
}

完整配置示例

java
@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
    
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .csrf(csrf -> csrf.disable()) // 禁用CSRF
            .authorizeHttpRequests(requests -> requests
                .requestMatchers(
                    new AntPathRequestMatcher("/openapi/openapi.yml"),
                    new AntPathRequestMatcher("/swagger-ui/**")
                ).permitAll()
                .anyRequest().authenticated()
            )
            .httpBasic(withDefaults()); // 启用基础认证
        
        return http.build();
    }
}

迁移注意事项

  1. 弃用变化

    • ❌ 移除 WebSecurityConfigurerAdapter
    • antMatchers() → ✅ requestMatchers()
    • 配置从 @Override 改为 @Bean 方式
  2. 操作指南

常见错误排查

陷阱提醒

  • 使用 requestMatchers("/openapi/**") 时,末尾 ** 表示多级路径
  • 测试时清除浏览器缓存或使用隐身模式(401 可能被缓存)
  • HttpSecurity 配置顺序敏感:先定义 permitAll,再 authenticated

官方资源

最终建议:对于生产环境,始终使用 Spring Boot GA 版本(非 RC),并优先采用显式路径匹配器解决端点放行问题。