Spring控制器CSRF单元测试报错:无法实例化CsrfToken接口
解决Spring MVC测试中CsrfToken参数绑定报错问题
问题根源
你在测试类中通过excludeAutoConfiguration = {SecurityAutoConfiguration.class}排除了Spring Security的自动配置,这会导致CsrfTokenArgumentResolver这个关键组件未被注册。该组件的作用是将请求属性中已存在的CsrfToken实例绑定到控制器方法的参数上。缺少它时,Spring MVC会尝试直接实例化CsrfToken接口,自然抛出"找不到唯一构造方法"的异常。
可行解决方案
方案1:保留Security自动配置,关闭过滤器(最简便)
如果测试无需验证CSRF安全逻辑,仅需让控制器正常解析CsrfToken参数,可去掉excludeAutoConfiguration,同时用@AutoConfigureMockMvc(addFilters = false)关闭Security过滤器链,避免触发CSRF校验:
@WebMvcTest(controllers = Controller.class) @ContextConfiguration(classes = {Controller.class, TestConfiguration.class}) @AutoConfigureMockMvc(addFilters = false) // 关闭Security过滤器,跳过CSRF校验 class ControllerTest { @Autowired private MockMvc mockMvc; @Test void test() throws Exception { mockMvc.perform(get("/.../data?param=2.0") .contextPath("/CONTEXT").servletPath("/.../data") .contentType(MediaType.APPLICATION_JSON) .with(csrf()) // 可选,过滤器关闭后CSRF校验不会触发 ) .andExpectAll( status().isOk() // 其他断言逻辑 ) .andReturn(); } }
方案2:手动注册CsrfToken参数解析器(适合必须排除Security自动配置的场景)
若因业务限制必须排除SecurityAutoConfiguration,可在TestConfiguration中手动注册CsrfTokenArgumentResolver:
@WebAppConfiguration @EnableWebMvc public class TestConfiguration implements WebMvcConfigurer { @Bean ReactjsControllerExceptionHandler reactjsControllerExceptionHandler() { return new ControllerExceptionHandler(); } // 手动添加CsrfToken参数解析器 @Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) { resolvers.add(new CsrfTokenArgumentResolver()); } }
完成后,你之前尝试的设置请求属性或使用with(csrf())的方式就能正常工作,因为Spring MVC现在能识别并绑定CsrfToken参数了。
为什么之前的尝试无效
你设置请求属性、模拟CsrfToken的操作本身无问题,但缺少CsrfTokenArgumentResolver时,Spring MVC无法识别控制器方法中的CsrfToken参数,不会从请求属性中获取实例,而是直接尝试实例化接口,因此依然报错。
内容的提问来源于stack exchange,提问作者rMonteiro
相关产品推荐
相关产品推荐

