如何在Spring MVC的@Controller中获取用户认证错误信息并传递至Thymeleaf
获取Spring Security认证错误类型并在Thymeleaf展示
嘿,我来帮你搞定这个问题!你现在已经配置了登录失败跳转到/login/error,但想拿到具体的认证错误类型对吧?其实Spring Security已经帮我们把认证失败的异常存在请求里了,有两种简单的方式可以获取:
方法一:从HttpServletRequest中获取异常
Spring Security会把认证失败的AuthenticationException对象存储在请求属性中,key是固定的SPRING_SECURITY_LAST_EXCEPTION。你只需要在控制器方法中注入HttpServletRequest,就能取出这个异常,然后根据异常类型判断具体错误:
import org.springframework.security.authentication.*; import org.springframework.security.core.AuthenticationException; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; @Controller public class LoginController { @RequestMapping("/login/error") public String loginError(HttpServletRequest request, Model model) { // 取出Spring Security存储的认证异常 AuthenticationException authException = (AuthenticationException) request.getAttribute("SPRING_SECURITY_LAST_EXCEPTION"); String errorMessage = null; // 根据异常类型判断具体错误 if (authException instanceof BadCredentialsException) { errorMessage = "用户名或密码错误,请重试"; } else if (authException instanceof DisabledException) { errorMessage = "该账户已被禁用,请联系管理员"; } else if (authException instanceof LockedException) { errorMessage = "该账户已被锁定,请稍后再试"; } else if (authException instanceof AccountExpiredException) { errorMessage = "该账户已过期,请联系管理员"; } else if (authException instanceof CredentialsExpiredException) { errorMessage = "您的密码已过期,请重置密码"; } else { errorMessage = "登录失败,请检查您的账户信息"; } model.addAttribute("loginError", true); model.addAttribute("errorMessage", errorMessage); return "login"; } }
方法二:直接注入AuthenticationException(Spring 5.3+/Spring Security 5.6+)
如果你的项目使用的是较新的Spring版本,Spring会自动将请求中的认证异常注入到方法参数中,代码会更简洁:
@RequestMapping("/login/error") public String loginError(AuthenticationException authException, Model model) { String errorMessage = null; // 同样的异常判断逻辑 if (authException instanceof BadCredentialsException) { errorMessage = "用户名或密码错误,请重试"; } else if (authException instanceof DisabledException) { errorMessage = "该账户已被禁用,请联系管理员"; } // ...其他异常类型的判断 model.addAttribute("loginError", true); model.addAttribute("errorMessage", errorMessage); return "login"; }
在Thymeleaf模板中展示错误信息
最后在你的login.html模板中,通过模型属性展示错误信息即可:
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>登录页面</title> </head> <body> <form th:action="@{/login}" method="post"> <!-- 用户名、密码输入框 --> <div> <label>用户名:</label> <input type="text" name="username"/> </div> <div> <label>密码:</label> <input type="password" name="password"/> </div> <!-- 展示错误信息 --> <div th:if="${loginError}" class="alert alert-danger" role="alert"> <span th:text="${errorMessage}"></span> </div> <button type="submit">登录</button> </form> </body> </html>
这样就能根据不同的认证失败原因,给用户展示对应的友好提示啦!
内容的提问来源于stack exchange,提问作者Vadym Borys
相关产品推荐
相关产品推荐

