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
public AuthenticationFailureHandler authenticationFailureHandler() {
return new CustomAuthenticationFailureHandler();
}
@Bean
public AuthenticationSuccessHandler authenticationSuccessHandler() {
return new CustomAuthenticationSuccessHandler();
}
@Bean
public AccessDeniedHandler accessDeniedHandler() {
return new CustomAccessDeniedHandler();
}
由於 AuthenticationSuccessHandler 處理了成功的路徑,我們將定義剩餘的兩個 Bean 用於異常情況。 這兩個處理程序是我們現在需要適應和實現到我們自身需求。 讓我們繼續進行每個 Bean 的實現。
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 默認提供一個訪問拒絕頁面,我們可以自定義它。 這由 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 異常以及如何通過創建和自定義類來控制它們。此外,我們還創建了一個完全可運行的示例,幫助我們理解所解釋的概念。