Spring Security测试@WithMockUser时非GET请求403问题求助
排查@WithMockUser测试非GET请求返回403的问题
1. 优先检查CSRF防护配置
Spring Security默认对非GET(POST/PUT/DELETE等)请求启用CSRF校验,而@WithMockUser注解不会自动生成并携带CSRF Token,这是导致403最常见的原因。
解决方案:
- 测试环境临时关闭CSRF:在测试专属的Security配置中添加
csrf().disable(); - 手动携带CSRF Token测试:通过
mockMvc先获取CSRF Token,再添加到请求头中,示例代码:
@Test void testPostEndpoint() throws Exception { // 获取CSRF Token MvcResult csrfResult = mockMvc.perform(MockMvcRequestBuilders.get("/csrf")).andReturn(); String csrfToken = csrfResult.getResponse().getCookie("XSRF-TOKEN").getValue(); // 发送POST请求时携带Token mockMvc.perform(MockMvcRequestBuilders.post("/your-api") .header("X-XSRF-TOKEN", csrfToken) .contentType(MediaType.APPLICATION_JSON) .content("{\"name\":\"test\"}")) .andExpect(status().isOk()); }
2. 排查JwtAuthenticationFilter的测试兼容性
如果你的自定义JwtAuthenticationFilter对所有请求强制校验JWT Token,而@WithMockUser是模拟用户身份、不会生成真实JWT,就会导致非GET请求被过滤器拦截返回403。
解决方案:
- 在测试环境的Security配置中移除
JwtAuthenticationFilter,示例:
@Configuration @Profile("test") public class TestSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest().authenticated() .and() .formLogin().disable() .httpBasic().disable(); // 不添加JwtAuthenticationFilter } }
- 或者在过滤器逻辑中添加判断,测试环境下跳过JWT校验。
3. 验证权限规则与@WithMockUser的匹配度
检查Security配置中,POST/PUT/DELETE等请求的权限要求是否和@WithMockUser的角色/权限一致:
- 比如配置了
.antMatchers(HttpMethod.POST, "/**").hasRole("ADMIN"),但@WithMockUser只指定了roles="USER",就会触发403; - 调整
@WithMockUser参数匹配权限要求,示例:
@WithMockUser(username = "admin", roles = {"ADMIN"}) @Test void testPostRequest() throws Exception { // 测试逻辑 }
4. 检查控制器方法的权限注解
如果控制器方法使用了@PreAuthorize/@PostAuthorize,确认@WithMockUser的用户满足注解中的权限条件:
- 比如方法有
@PreAuthorize("hasAuthority('DATA_CREATE')"),则@WithMockUser需要指定对应权限:
@WithMockUser(authorities = {"DATA_CREATE"}) @Test void testCreateData() throws Exception { // 测试逻辑 }
内容的提问来源于stack exchange,提问作者Emiljano Molla
相关产品推荐
相关产品推荐

