升级Spring Boot 3后Security Filter配置失效问题求助
问题分析与解决方案
错误原因
你的应用Servlet上下文存在两个可映射的Servlet:
org.springframework.web.servlet.DispatcherServlet(映射路径/,处理所有Spring MVC请求)org.h2.server.web.JakartaWebServlet(映射路径/h2-console/*,处理H2控制台请求)
Spring Boot 3.x版本的Spring Security在多Servlet环境下,无法自动推断你配置的requestMatchers路径属于哪个Servlet的处理范围,因此要求你明确指定请求匹配器的类型:
- 如果是Spring MVC端点,使用
MvcRequestMatcher - 如果是非Spring MVC端点(比如H2控制台),使用
AntPathRequestMatcher
解决方案
修改你的WebSecurityConfig配置类,分别为Spring MVC端点和H2控制台端点指定对应的请求匹配器:
1. 注入HandlerMappingIntrospector(用于创建MvcRequestMatcher)
在配置类中注入Spring MVC的HandlerMappingIntrospector bean,它是创建MvcRequestMatcher的必要依赖:
@Bean public HandlerMappingIntrospector handlerMappingIntrospector() { return new HandlerMappingIntrospector(); }
2. 拆分白名单并指定匹配器
将原有的白名单拆分为Spring MVC端点白名单和H2控制台白名单,分别使用对应的匹配器:
@Configuration @EnableMethodSecurity(securedEnabled = true, jsr250Enabled = true) public class WebSecurityConfig { // Spring MVC端点白名单(Swagger、Actuator等) private static final String[] MVC_AUTH_WHITELIST = { // -- Swagger UI v2 "/v2/api-docs", "/swagger-resources", "/swagger-resources/**", "/configuration/ui", "/configuration/security", "/swagger-ui.html", "/webjars/**", // -- Swagger UI v3 "/api/template/v3/api-docs/**", "/v3/api-docs/**", "/api/template/swagger-ui/**", "/swagger-ui/**", // Actuators "/actuator/**", "/health/**" }; // H2控制台白名单 private static final String[] H2_AUTH_WHITELIST = { "/h2-console/**" }; @Bean public HandlerMappingIntrospector handlerMappingIntrospector() { return new HandlerMappingIntrospector(); } @Bean public SecurityFilterChain filterChain(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception { try { // 创建MvcRequestMatcherProvider,用于匹配Spring MVC端点 MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector); http .csrf(csrf -> csrf .ignoringRequestMatchers(H2_AUTH_WHITELIST) // H2控制台需要关闭CSRF ) .authorizeHttpRequests(auth -> auth // 允许Spring MVC白名单路径匿名访问 .requestMatchers(mvcMatcherBuilder.patterns(MVC_AUTH_WHITELIST)).permitAll() // 允许H2控制台路径匿名访问,使用AntPathRequestMatcher .requestMatchers(AntPathRequestMatcher.antMatcher(H2_AUTH_WHITELIST)).permitAll() .anyRequest().authenticated() ) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .httpBasic(AbstractHttpConfigurer::disable) .formLogin(AbstractHttpConfigurer::disable) .headers(headers -> headers .frameOptions(frame -> frame.sameOrigin()) // 允许H2控制台的iframe访问 ) .cors(); return http.build(); } catch (Exception ex) { throw new GenericRuntimeException(buildMessage(ERROR_WEB_SECURITY_FILTER.getText(ex.getMessage())), ex); } } }
关键修改点说明
- 移除了原白名单中重复的路径(比如既有
\/v2\/api-docs又有v2\/api-docs,统一为带斜杠的标准路径) - 为Spring MVC端点使用
MvcRequestMatcher,确保匹配Spring MVC的路由规则 - 为H2控制台端点使用
AntPathRequestMatcher,明确指定由H2的Servlet处理 - 为H2控制台单独关闭CSRF(H2控制台的POST请求需要绕过CSRF校验)
额外注意事项
- 确保你的
application.properties或application.yml中已开启H2控制台的配置(如果需要使用):spring.h2.console.enabled=true spring.h2.console.path=/h2-console - 如果你不需要H2控制台,可以直接移除相关依赖和配置,这样就不会出现多Servlet的问题,也可以简化Security配置
内容的提问来源于stack exchange,提问作者saran3h
相关产品推荐
相关产品推荐

