1. 概述
本文將探討如何處理由我們的 Spring Security 資源服務器產生的 Spring Security 異常。為此,我們還將使用一個實際示例,其中會詳細解釋所有必要的配置。首先,讓我們簡要介紹一下 Spring Security。
2. Spring Security
Spring Security 是 Spring 項目的一部分,它旨在將 Spring 項目中的所有用户訪問控制功能整合在一起。訪問控制允許限制給定用户或角色的應用程序中可以執行的操作。為此,Spring Security 控制對業務邏輯的調用,或限制 HTTP 請求對某些 URL 的訪問。因此,我們必須通過配置應用程序,告訴 Spring Security 安全層應該如何運行。
在我們的案例中,我們將重點關注異常處理器的配置。Spring Security 提供三種不同的接口來實現這一目的,並控制產生的事件:
- 身份驗證成功處理程序
- 身份驗證失敗處理程序
- 訪問拒絕處理程序
首先,讓我們更詳細地瞭解一下配置。
3. 安全配置
首先,我們有一個配置類,它必須創建一個 SecurityFilterChain Bean。 這將負責管理應用程序的所有安全配置。 因此,這裏是我們必須引入處理器的位置。
一方面,我們將定義所需的配置:
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf(AbstractHttpConfigurer::disable)
.httpBasic(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(auth -> auth
.requestMatchers("/login")
.permitAll()
.requestMatchers("/customError")
.permitAll()
.requestMatchers("/access-denied")
.permitAll()
.requestMatchers("/secured")
.hasRole("ADMIN")
.anyRequest()
.authenticated())
.formLogin(form -> form.failureHandler(authenticationFailureHandler())
.successHandler(authenticationSuccessHandler()))
.exceptionHandling(ex -> ex.accessDeniedHandler(accessDeniedHandler()))
.logout(Customizer.withDefaults());
return http.build();
}
}值得注意的是,重定向 URL,例如 “/login”、“/customError” 和 “/access-denied”,不需要任何訪問限制。因此,我們使用 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. 身份驗證失敗處理程序
我們有身份驗證失敗處理程序(AuthenticationFailureHandler)接口。該接口負責管理用户登錄失敗時產生的異常。該接口為我們提供 onAuthenticationFailure() 方法,用於自定義處理邏輯。Spring Security 在登錄嘗試失敗時會調用此方法。考慮到這一點,我們定義異常處理程序,以便在登錄失敗時將用户重定向到錯誤頁面:
public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception)
throws IOException {
response.sendRedirect("/customError");
}
}5. 訪問拒絕處理程序
當未授權用户嘗試訪問受保護或安全頁面時,Spring Security 會拋出訪問拒絕異常。 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. 結論
在本文中,我們學習瞭如何處理 Spring Security 異常,以及通過創建和自定義類來控制它們. 此外,我們還創建了一個完整的示例,幫助我們理解所解釋的概念。