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

测试Spring Security时@AuthenticationPrincipal始终为null如何解决

问题根因

@WithMockUser 注解默认生成的身份凭证中,principal 字段是字符串类型的用户名,和你控制器中需要注入的自定义 User 类型不匹配,Spring MVC 参数解析器无法完成类型转换,因此最终注入的参数为 null。

可行解决方案

方案1:使用SecurityMockMvcRequestPostProcessors传入自定义User对象

该方案最直接,不需要额外加类注解,直接在构造请求时传入你自己实例化的User对象即可:

@Test
public void test() throws Exception {
    // 提前构造你需要的User实例,按需填充属性
    User mockUser = new User();
    mockUser.setUsername("test");
    mockUser.setId(1L);

    this.mockMvc.perform(get("/account")
                .with(SecurityMockMvcRequestPostProcessors.user(mockUser)))
            .andDo(print());
}

方案2:手动设置SecurityContext

在测试方法执行前,手动构造身份凭证存入安全上下文,适合需要复用身份信息的多请求测试场景:

@Test
public void test() throws Exception {
    User mockUser = new User();
    // 填充自定义属性
    mockUser.setUsername("test");
    
    UsernamePasswordAuthenticationToken auth = 
        new UsernamePasswordAuthenticationToken(mockUser, null, AuthorityUtils.createAuthorityList("ROLE_USER"));
    SecurityContextHolder.getContext().setAuthentication(auth);

    this.mockMvc.perform(get("/account")).andDo(print());
}

方案3:配合@WithUserDetails使用

如果你的项目中已经实现了UserDetailsService接口,且该接口返回的就是自定义User类型,可采用该方案:

@WebMvcTest
public class GazerControllerTest {

@MockBean
UserService userService;
@MockBean
ClientService clientService;
// 新增Mock UserDetailsService
@MockBean
UserDetailsService userDetailsService;

@Autowired
MockMvc mockMvc;


@Test
@WithUserDetails("testUser")
public void test() throws Exception {
    User mockUser = new User();
    mockUser.setUsername("testUser");
    // Mock查询逻辑返回自定义User对象
    when(userDetailsService.loadUserByUsername(eq("testUser"))).thenReturn(mockUser);

    this.mockMvc.perform(get("/account")).andDo(print());
}

}

注意:请确认你的自定义User类实现了Spring Security的UserDetails接口,否则需要自行扩展AuthenticationPrincipalArgumentResolver完成自定义类型的解析,大多数场景下实现UserDetails接口是成本最低的方案。

内容的提问来源于stack exchange,提问作者Randall1820

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 05:06:04