You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 08:54:06