Spring Boot Security与Thymeleaf控制器权限测试返回302问题
问题分析与解决方案
问题根源
测试返回302重定向的核心原因:
- 控制器的
admin方法依赖Session中的nome_usuario属性,但@WithMockUser仅模拟了用户角色,未注入该Session属性,导致后续查询用户返回null,触发重定向到/login。 - 未对
UsuarioService进行Mock,实际调用时无法获取有效用户对象,同样触发重定向。 - 自定义的
TokenValidationFilter可能在测试中拦截请求,影响Session初始化。
解决方案
1. 完善测试代码:补充Session属性并Mock服务
修改测试类,注入Session属性并模拟UsuarioService的返回值:
@WebMvcTest(LoginController.class) public class LoginControllerTest{ @Autowired private MockMvc mockMvc; @MockBean private UsuarioService usuarioService; @Test @WithMockUser(roles = "ADMIN") public void testAdminAccessWithAdminRole() throws Exception { // 定义测试用的用户名和模拟用户对象 String testUsername = "admin_test"; Usuario mockUser = new Usuario(); mockUser.setNomeUsuario(testUsername); // 配置Mock服务的返回逻辑 when(usuarioService.buscarPorNomeUsuario(testUsername)).thenReturn(mockUser); // 发起请求时注入Session属性 mockMvc.perform(get("/admin") .sessionAttr("nome_usuario", testUsername)) .andExpect(status().isOk()) .andExpect(view().name("login/home")) .andExpect(model().attribute("usuario", mockUser)); } }
2. 排除自定义过滤器的干扰
如果测试中不需要验证TokenValidationFilter的逻辑,可以禁用所有过滤器,避免其拦截请求:
@WebMvcTest(LoginController.class) @AutoConfigureMockMvc(addFilters = false) // 禁用所有过滤器 public class LoginControllerTest{ // ... 上述测试代码 }
3. 修复控制器的空指针风险
原控制器中直接调用session.getAttribute("nome_usuario").toString()存在空指针隐患,建议先做null校验:
@GetMapping("/admin") public String admin(ModelMap model, HttpSession session) { Object usernameObj = session.getAttribute("nome_usuario"); if (usernameObj == null) { return "redirect:/login"; } String nomeUsuario = usernameObj.toString(); Usuario usuario = usuarioService.buscarPorNomeUsuario(nomeUsuario); if (usuario == null) { return "redirect:/login"; } model.addAttribute("usuario", usuario); return "login/home"; }
内容的提问来源于stack exchange,提问作者Enio Martinelli
相关产品推荐
相关产品推荐

