Spring Security MockMvc配置默认HTTPS后with(user)返回principal为空如何解决
问题根因
你之前配置defaultRequest(get("/").secure(true))出现principal为null的核心原因是:defaultRequest的属性补全逻辑和Spring Security提供的UserDetailsRequestPostProcessor(也就是你调用user(myCustomUserDetailsUser)生成的处理器)执行顺序存在冲突,默认请求携带的部分属性覆盖了Security上下文的认证信息,最终导致principal丢失。
最优解决方案
直接替换你的自定义MockMvc Bean配置,使用addRequestPostProcessors全局给所有请求强制设置secure=true属性即可,不需要修改任何现有测试用例:
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; @Bean public MockMvc mockMvc(WebApplicationContext context) { return MockMvcBuilders .webAppContextSetup(context) // 必须添加,确保Spring Security过滤器链正确注入到MockMvc .apply(springSecurity()) // 全局为所有请求添加secure=true属性,等效于每个请求手动调用.secure(true) .addRequestPostProcessors(request -> { request.setSecure(true); return request; }) .build(); }
该方案下,全局处理器会先给所有请求设置HTTPS标识,之后你每个测试用例中定义的with(user(myCustomUserDetailsUser))逻辑会正常执行,不会出现属性覆盖、principal丢失的问题。
备选方案(特殊场景适用)
如果你的项目中存在部分请求不需要走HTTPS的场景,可以自定义请求工具类封装常用请求方法,原有测试仅需要替换get/post等方法的引用即可,改动量极小:
// 自定义工具类 public class MockRequestUtils { public static MockHttpServletRequestBuilder secureGet(String url, Object... uriVars) { return get(url, uriVars).secure(true); } public static MockHttpServletRequestBuilder securePost(String url, Object... uriVars) { return post(url, uriVars).secure(true); } // 按需补充put/delete等其他方法 } // 原有测试仅需要修改方法引用即可 mockMvc.perform(secureGet(API_URL) .with(user(myCustomUserDetailsUser))) .andExpect(status().isOk());
内容的提问来源于stack exchange,提问作者Aspir
相关产品推荐
相关产品推荐

