SpringBoot集成Spring Security(3)——异常处理
登录异常是需要我们进行处理的,在第一章中我们只是重定向到了一个/login?error界面并没有显示任何的错误信息。
1. 常见的异常
UsernameNotFoundException
(用户不存在)DisabledException
(用户已被禁用)BadCredentialsException
(坏的凭据)LockedException
(账户锁定)AccountExpiredException
(账户过期)CredentialsExpiredException
(证书过期)
这些异常都是AuthenticationException
的子类。
2.源码分析
从AbstractAuthenticationProcessingFilter
中找到关于AuthenticationException
的处理:
(1) 在 doFilter()
中,捕捉了 AuthenticationException
异常,并交给了 unsuccessfulAuthentication()
处理。
(2) .进入unsuccessfulAuthentication()
方法,其转交给SimpleUrlAuthenticationFailureHandler()
类的onAuthenticationFailure()
方法
(3).在onAuthenticationFailure()
中,会对是否设置了defaultFailureUrl()
进行判断:
- 如果没有设置,即为null,直接返回401错误(
HttpStatus.UNAUTHORIZED
的值) - 如果设置了,先执行
saveException()
方法。然后判断forwardToDestination
,即是否是服务器跳转,默认使用重定向即客户端跳转。
(4).在 saveException()
方法中,首先判断forwardToDestination
,如果使用服务器跳转则写入request
,客户端跳转则写入session
。写入名为SPRING_SECURITY_LAST_EXCEPTION
,值为AuthenticationException
。
至此 Spring security 完成了异常处理,总结一下流程:
–> AbstractAuthenticationProcessingFilter.doFilter()
–> AbstractAuthenticationProcessingFilter.unsuccessfulAuthentication()
–> SimpleUrlAuthenticationFailureHandler.onAuthenticationFailure()
–> SimpleUrlAuthenticationFailureHandler.saveException()
3.异常处理
(1).指定显示错误信息的url,WebSecurityConfig
中添加.failureUrl("/login/error")
(2).在Controller中处理异常
//登录失败信息
@RequestMapping("/login/error")
public void loginError(HttpServletResponse response, HttpServletRequest request){
response.setContentType("text/html;charset=utf-8");
AuthenticationException exception= (AuthenticationException) request.getSession().getAttribute("SPRING_SECURITY_LAST_EXCEPTION");
try{
response.getWriter().write(exception.toString());
} catch (IOException e) {
e.printStackTrace();
}
}