Spring Boot启动报错:无法判断请求匹配模式类型(Spring Security 6)
解决Spring Boot 3 + Spring Security 6启动异常:无法判断请求匹配模式类型
运行Spring Boot应用时启动失败,抛出异常:
此方法无法判断这些模式是否为Spring MVC模式。如果该端点是Spring MVC端点,请使用requestMatchers(MvcRequestMatcher);否则,请使用requestMatchers(AntPathRequestMatcher)。
环境:Spring Boot 3 + Spring Security 6
相关代码
Spring Security配置类
package com.ronit.SpringSecurityTutorial.configuration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.ProviderManager; import org.springframework.security.authentication.dao.DaoAuthenticationProvider; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; @EnableWebSecurity @Configuration public class SecurityConfiguration { @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean AuthenticationManager authManager(UserDetailsService detailsService) { DaoAuthenticationProvider daoProvider = new DaoAuthenticationProvider(); daoProvider.setUserDetailsService(detailsService); return new ProviderManager(daoProvider); } @SuppressWarnings("removal") @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { return http.csrf(csrf -> csrf.disable()).authorizeHttpRequests(auth -> { auth.anyRequest().authenticated(); auth.requestMatchers("/auth/**").permitAll(); auth.anyRequest().authenticated(); }).httpBasic().and().build(); } }
Spring Boot启动类
package com.ronit.SpringSecurityTutorial; import java.util.HashSet; import java.util.Set; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.security.crypto.password.PasswordEncoder; import com.ronit.SpringSecurityTutorial.models.ApplicationUser; import com.ronit.SpringSecurityTutorial.models.Role; import com.ronit.SpringSecurityTutorial.repository.RoleRepository; import com.ronit.SpringSecurityTutorial.repository.UserRepository; @SpringBootApplication public class SpringSecurityTutorialApplication { public static void main(String[] args) { SpringApplication.run(SpringSecurityTutorialApplication.class,args); } @Bean CommandLineRunner run(RoleRepository roleRepository, UserRepository userRepository, PasswordEncoder passwordEncoder) { return args -> { if (roleRepository.findByAuthority("ADMIN").isPresent()) return; Role adminRole = roleRepository.save(new Role("ADMIN")); roleRepository.save(new Role("USER")); Set<Role> roles = new HashSet<>(); roles.add(adminRole); ApplicationUser admin = new ApplicationUser(1, "Admin", passwordEncoder.encode("Password"), roles); userRepository.save(admin); }; } }
pom.xml依赖
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
问题原因及修复方案
核心问题
- 请求匹配器类型不明确:Spring Security 6对请求匹配的校验更严格,直接用字符串路径调用
requestMatchers时,框架无法自动识别是Spring MVC端点还是普通路径,必须明确指定匹配器类型。 - 授权规则顺序错误:原配置先设置
auth.anyRequest().authenticated(),后续的permitAll规则永远不会被匹配到,因为anyRequest会匹配所有请求。
修改后的Spring Security配置类
package com.ronit.SpringSecurityTutorial.configuration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.ProviderManager; import org.springframework.security.authentication.dao.DaoAuthenticationProvider; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher; import org.springframework.web.servlet.handler.HandlerMappingIntrospector; @EnableWebSecurity @Configuration public class SecurityConfiguration { @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean AuthenticationManager authManager(UserDetailsService detailsService) { DaoAuthenticationProvider daoProvider = new DaoAuthenticationProvider(); daoProvider.setUserDetailsService(detailsService); daoProvider.setPasswordEncoder(passwordEncoder()); // 补充密码编码器,避免后续认证失败 return new ProviderManager(daoProvider); } @Bean MvcRequestMatcher.Builder mvc(HandlerMappingIntrospector introspector) { return new MvcRequestMatcher.Builder(introspector); } @Bean public SecurityFilterChain filterChain(HttpSecurity http, MvcRequestMatcher.Builder mvc) throws Exception { return http.csrf(csrf -> csrf.disable()) .authorizeHttpRequests(auth -> { // 先配置无需认证的路径 auth.requestMatchers(mvc.pattern("/auth/**")).permitAll(); // 其余所有请求需要认证 auth.anyRequest().authenticated(); }) .httpBasic() .and() .build(); } }
修改说明
- 明确指定MvcRequestMatcher:注入
HandlerMappingIntrospector并创建MvcRequestMatcher.Builder,告诉框架使用Spring MVC的请求匹配规则,解决模式类型无法判断的问题。 - 调整授权规则顺序:先设置
permitAll的路径,再配置anyRequest().authenticated(),确保规则按从上到下的顺序匹配。 - 补充密码编码器设置:原
DaoAuthenticationProvider未绑定密码编码器,会导致用户登录时认证失败,这里补上该配置。
额外说明
- 启动类和pom.xml无需修改,保持原代码即可。
- 若需使用非Spring MVC的路径匹配(如静态资源),可替换为
AntPathRequestMatcher,示例:requestMatchers(new AntPathRequestMatcher("/auth/**")).permitAll(),但Spring MVC接口优先使用MvcRequestMatcher。
内容的提问来源于stack exchange,提问作者Ronit Pandey
相关产品推荐
相关产品推荐

