Thymeleaf中如何在重定向时携带已认证用户信息?
问题分析与解决方案
你自定义登录接口验证用户后,重定向到带有@PreAuthorize注解的/overview端点时预授权失败,核心原因是重定向后的新请求无法获取到之前设置的认证信息,手动设置的SecurityContext会被Spring Security的过滤器重置。
现有代码
登录控制器代码
@PostMapping public String doLogin(@ModelAttribute Nutzer nutzer) { //Verify user in Database if(exists) { return "redirect:/overview"; } return "redirect:Login"; }
Overview端点代码
@PreAuthorize("hasAnyAuthority('User')") @GetMapping("overview") public String getOverview(Model model) { //add Userdetails to model. return "overview"; }
解决步骤
要让重定向后的请求能识别已认证用户,必须将认证信息持久化到HTTP会话中,修改登录控制器代码如下:
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.context.HttpSessionSecurityContextRepository; import javax.servlet.http.HttpSession; import java.util.Collections; @PostMapping public String doLogin(@ModelAttribute Nutzer nutzer, HttpSession session) { // 替换为实际的数据库用户验证逻辑 boolean exists = true; if(exists) { // 构造用户权限列表 var userAuthorities = Collections.singletonList(new SimpleGrantedAuthority("User")); // 创建认证Token:参数为用户标识、密码(可传null)、权限集合 Authentication authToken = new UsernamePasswordAuthenticationToken(nutzer.getUsername(), null, userAuthorities); // 将认证信息设置到当前上下文 SecurityContextHolder.getContext().setAuthentication(authToken); // 把SecurityContext存入会话,保证重定向后的请求能读取到 session.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext()); return "redirect:/overview"; } return "redirect:/Login"; }
额外注意事项
- 确保Spring Security默认的会话管理功能未被禁用(默认是启用状态)
- 生产环境中验证用户密码时,必须使用Spring Security提供的密码编码器(如
BCryptPasswordEncoder),禁止明文比对密码 - 推荐实现
UserDetails接口封装用户信息,替代直接使用Nutzer对象,更贴合Spring Security的认证规范
内容的提问来源于stack exchange,提问作者Ti1991
相关产品推荐
相关产品推荐

