Spring Security中mvcMatchers失效,antMatchers正常的问题求助
我之前也踩过类似的坑,Spring Security的mvcMatchers()和antMatchers()核心区别在于:前者完全依赖Spring MVC的请求映射机制,后者是直接匹配原始URL路径。你切换后出现全局404,大概率是Spring Security无法正确识别Spring MVC的路由配置,导致mvc匹配规则失效,甚至请求根本没流转到Spring MVC的DispatcherServlet。
可能的原因及对应解决方案
1. 未启用Spring MVC核心配置(缺少@EnableWebMvc)
mvcMatchers()需要读取Spring MVC的请求映射元数据(比如控制器的@RequestMapping、@GetMapping注解信息),如果你的MvcWebConfig没加@EnableWebMvc,Spring Security就无法解析这些元数据,匹配规则直接失效,请求自然找不到对应处理逻辑。
解决方案:
给MvcWebConfig加上@EnableWebMvc注解:
@Configuration @EnableWebMvc // 必须添加这个注解,开启Spring MVC核心配置 @ComponentScan(basePackages = "com.your.package") public class MvcWebConfig implements WebMvcConfigurer { // 你的视图解析器、静态资源配置等代码 }
2. DispatcherServlet映射路径配置错误
如果MvcWebApplicationInitializer里配置的DispatcherServlet映射路径不是"/"(比如"/app/*"),那mvcMatchers()的路径要对应控制器的相对路径,而不是完整URL。比如DispatcherServlet映射到"/app/*",控制器的@GetMapping("/home")实际对应URL是"/app/home",此时用mvcMatchers("/home")才是正确的,写mvcMatchers("/app/home")就会匹配失败。
检查并修正:
打开MvcWebApplicationInitializer确认映射路径:
public class MvcWebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return new Class[]{SecurityConfig.class}; } @Override protected Class<?>[] getServletConfigClasses() { return new Class[]{MvcWebConfig.class}; } @Override protected String[] getServletMappings() { // 推荐配置为 "/",让DispatcherServlet处理所有请求 return new String[]{"/"}; } }
3. SecurityConfig中mvcMatchers路径写法错误
mvcMatchers()的路径是相对于Spring MVC请求映射的,不需要包含上下文路径,也不能重复DispatcherServlet的映射路径。比如你的控制器代码是:
@Controller public class MyController { @GetMapping("/index") public String index() { return "index"; } }
那SecurityConfig里就该用mvcMatchers("/index"),而不是mvcMatchers("/")或其他错误路径。另外如果有静态资源需要放行,也要用mvcMatchers,前提是Spring MVC已经配置了静态资源映射。
修正后的SecurityConfig示例:
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() // 匹配控制器的请求路径 .mvcMatchers("/index").permitAll() // 放行静态资源(需配合Spring MVC的静态资源配置) .mvcMatchers("/css/**", "/js/**").permitAll() .anyRequest().authenticated() .and() .formLogin() .permitAll(); } }
4. 视图解析器配置错误
就算请求到达了控制器,如果MvcWebConfig里的视图解析器前缀/后缀配置错误,也会找不到index.html导致404。比如用Thymeleaf的话,要确保视图文件的存放路径和解析器配置一致。
Thymeleaf视图解析器配置示例:
@Configuration @EnableWebMvc @ComponentScan(basePackages = "com.your.package") public class MvcWebConfig implements WebMvcConfigurer { @Bean public SpringResourceTemplateResolver templateResolver() { SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver(); resolver.setPrefix("/WEB-INF/views/"); // 视图文件存放路径 resolver.setSuffix(".html"); resolver.setTemplateMode(TemplateMode.HTML); resolver.setCharacterEncoding("UTF-8"); return resolver; } @Bean public SpringTemplateEngine templateEngine() { SpringTemplateEngine engine = new SpringTemplateEngine(); engine.setTemplateResolver(templateResolver()); return engine; } @Override public void configureViewResolvers(ViewResolverRegistry registry) { ThymeleafViewResolver resolver = new ThymeleafViewResolver(); resolver.setTemplateEngine(templateEngine()); resolver.setCharacterEncoding("UTF-8"); registry.viewResolver(resolver); } // 静态资源映射配置 @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/css/**") .addResourceLocations("/WEB-INF/css/"); } }
排查顺序建议
先按以下顺序排查,基本能解决问题:
- 确认
MvcWebConfig添加了@EnableWebMvc - 检查DispatcherServlet映射路径是否为
"/"(或对应正确路径) - 修正
mvcMatchers()的路径,确保和控制器的请求路径一致 - 验证视图解析器和静态资源配置是否正确
内容的提问来源于stack exchange,提问作者gmpf

