1、概览 {#1概览}
本文通过一个示例来带你了解如何处理 Spring Security Resource Server 产生的 Spring Security 异常。
2、Spring Security {#2spring-security}
Spring Security 是 Spring 的一个子项目。它试图将 Spring 项目中的所有用户访问控制功能进行整合。访问控制允许限制特定用户或角色在应用中可以执行的选项。
在本例中,我们重点关注 Exception Handler 的配置。Spring Security 提供了三种不同的接口来实现这一目的并控制产生的事件:
- Authentication Success(认证成功)Handler
- Authentication Failure(认证失败)Handler
- Access Denied(拒绝访问)Handler
3、Security Configuration {#3security-configuration}
首先,配置类必须创建一个 SecurityFilterChain
Bean。它将负责管理应用的所有安全配置。因此,我们必须在这里引入 Handler。
定义所需的配置:
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf()
.disable()
.httpBasic()
.disable()
.authorizeRequests()
.antMatchers("/login")
.permitAll()
.antMatchers("/customError")
.permitAll()
.antMatchers("/access-denied")
.permitAll()
.antMatchers("/secured")
.hasRole("ADMIN")
.anyRequest()
.authenticated()
.and()
.formLogin()
.failureHandler(authenticationFailureHandler())
.successHandler(authenticationSuccessHandler())
.and()
.exceptionHandling()
.accessDeniedHandler(accessDeniedHandler())
.and()
.logout();
return http.build();
}
/login
、/customError
和 /access-denied
等重定向 URL 在访问时不需要任何类型的限制。因此,将它们标注为 permitAll()
。
另外,还必须定义一些 Bean,这些 Bean 定义了我们可以处理的异常类型:
@Bean
public AuthenticationFailureHandler authenticationFailureHandler() {
return new CustomAuthenticationFailureHandler();
}
@Bean
public AuthenticationSuccessHandler authenticationSuccessHandler() {
return new CustomAuthenticationSuccessHandler();
}
@Bean
public AccessDeniedHandler accessDeniedHandler() {
return new CustomAccessDeniedHandler();
}
AuthenticationSuccessHandler
处理了正常的情况,我们定义的另外两个 Bean 用于异常情况。这两个 Handler 是我们现在需要根据我们的需求进行调整和实现的部分。。
4、认证失败 Handler {#4认证失败-handler}
AuthenticationFailureHandler
接口负责管理用户登录失败时产生的异常。该接口提供了 onAuthenticationFailure()
方法,用于自定义处理逻辑。Spring Security 将在登录尝试失败时调用该方法。
定义异常 Exception Handler,在登录失败时重定向到错误页面:
public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception)
throws IOException {
response.sendRedirect("/customError");
}
}
5、拒绝访问 Handler {#5拒绝访问-handler}
当未经授权的用户试图访问受保护的页面时,Spring Security 会抛出拒绝访问异常(access denied exception)。Spring Security 有一个默认的 403 拒绝访问页面,我们可以对其进行自定义。该页面由 AccessDeniedHandler
接口管理。此外,它还提供了 handle()
方法,用于在将用户重定向到 403 页面之前自定义逻辑:
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException exc) throws IOException {
response.sendRedirect("/access-denied");
}
}
6、总结 {#6总结}
本文介绍了如何通过创建自定义 Handler 来处理 Spring Security 中的认证失败(Authentication Failure)和拒绝访问(Access Denied)异常。
参考:https://www.baeldung.com/spring-security-exceptions