Spring Security 异常
- Spring Security 中的异常主要分为两大类:
- 认证异常:AuthenticationException
- 授权异常:AccessDeniedException
- AuthenticationException认证异常
- 在用户认证的时候出现错误时抛出的异常,常见子类:
- UsernameNotFoundException 用户找不到
- BadCredentialsException 坏的凭据
- AccountStatusException 用户状态异常,它包含如下子类:
- AccountExpiredException 账户过期
- LockedException 账户锁定
- DisabledException 账户不可用
- CredentialsExpiredException 证书过期
- AccessDeniedException授权异常
- 主要是在用户在访问受保护资源时被拒绝而抛出的异常,常见子类:
- CsrfException
- AuthorizationServiceException
- MissingCsrfTokenException
Http 状态对认证授权的规定
- 401 未授权状态
- HTTP 401 错误 - 未授权(Unauthorized) 一般来说该错误消息表明您首先需要登录(输入有效的用户名和密码)。 如果你刚刚输入这些信息,立刻就看到一个 401 错误,就意味着,无论出于何种原因您的用户名和密码其中之一或两者都无效(输入有误,用户名暂时停用,账户被锁定,凭证失效等) 。总之就是认证失败了。其实正好对应我们上面的 AuthenticationException
- 403 被拒绝状态
- HTTP 403 错误 - 被禁止(Forbidden) 出现该错误表明您在访问受限资源时没有得到许可。服务器理解了本次请求但是拒绝执行该任务,该请求不该重发给服务器。并且服务器想让客户端知道为什么没有权限访问特定的资源,服务器应该在返回的信息中描述拒绝的理由。一般实践中我们会比较模糊的表明原因。 该错误对应了我们上面的 AccessDeniedException
Spring Security 的异常处理类
- HttpSecurity http 提供的 exceptionHandling() 方法用来提供异常处理。该方法构造出 ExceptionHandlingConfigurer 异常处理配置类。该配置类提供了两个实用接口:
- AuthenticationEntryPoint 该类用来统一处理 AuthenticationException 异常
- AccessDeniedHandler 该类用来统一处理 AccessDeniedException 异常
自定义异常案例
- 自定义AuthenticationEntryPoint
/**
- 自定义认证异常处理类
*/
public class SimpleAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
response.getWriter().println("<h1>匿名认证失败,请登录再试</h1>");
}
}
- 自定义AccessDeniedHandler
/**
- 自定义授权异常处理类
*/
public class SimpleAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
response.getWriter().println("<h1>无此权限</h1>");
}
}
- 配置自定义异常
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
//http.csrf().disable();//页面表单是Post请求时
http.authorizeRequests().antMatchers("/loginHome").access("permitAll");
http.authorizeRequests().antMatchers("/loginFail").access("permitAll");
http.authorizeRequests().antMatchers("/home").hasRole("USER");
http.authorizeRequests().antMatchers("/admin").hasRole("ADMIN");
http.authorizeRequests().anyRequest().authenticated();
//配置自定义认证和授权处理类
http.exceptionHandling().authenticationEntryPoint(new SimpleAuthenticationEntryPoint());
http.exceptionHandling().accessDeniedHandler(new SimpleAccessDeniedHandler());
http.formLogin();
http.logout();
}
}