Spring Security 自定義認證失敗處理器

Spring Security
Remote
0
01:56 AM · Nov 30 ,2025

1. 概述

在本快速教程中,我們將演示如何自定義 Spring Security 的身份驗證失敗處理方式,在 Spring Boot 應用程序中。目標是使用

有關

2. 身份驗證與授權

身份驗證授權經常一起使用,因為它們在授予系統訪問權限時起着至關重要且同樣重要的作用。

然而,它們具有不同的含義並在驗證請求時應用不同的約束:

  • 身份驗證 – 授權;它涉及驗證收到的憑據;即,我們驗證用户名和密碼是否與我們的應用程序所認識的匹配。
  • 授權– 它涉及驗證已成功身份驗證的用户是否具有訪問應用程序特定功能的權限。

我們可以自定義身份驗證授權失敗處理,但是,在本項目中,我們將重點關注身份驗證失敗。

3. Spring Security 的 AuthenticationFailureHandler

Spring Security 提供了一個組件,用於默認情況下處理身份驗證失敗。

然而,我們經常會遇到默認行為不足以滿足要求的場景。

如果是這樣的話,我們可以創建自己的組件並提供我們想要的行為,通過實現 AuthenticationFailureHandler 接口:

public class CustomAuthenticationFailureHandler
  implements AuthenticationFailureHandler {

    private ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void onAuthenticationFailure(
      HttpServletRequest request,
      HttpServletResponse response,
      AuthenticationException exception)
      throws IOException, ServletException {

        response.setStatus(HttpStatus.UNAUTHORIZED.value());
        Map data = new HashMap<>();
        data.put(
          "timestamp",
          Calendar.getInstance().getTime());
        data.put(
          "exception",
          exception.getMessage());

        response.getOutputStream()
          .println(objectMapper.writeValueAsString(data));
    }
}

默認情況下,Spring 會將用户重定向回登錄頁面,帶有包含錯誤信息的 request 參數

在我們的應用程序中,我們將返回一個 401 響應,其中包含有關錯誤的詳細信息以及其發生的日期戳。

除了默認組件,Spring 還提供了其他可用的組件,我們可以根據需要使用它們:

  • DelegatingAuthenticationFailureHandler 委託 AuthenticationException 子類到不同的 AuthenticationFailureHandlers,這意味着我們可以為 AuthenticationException 的不同實例創建不同的行為
  • ExceptionMappingAuthenticationFailureHandler 根據 AuthenticationException 的 全類名將用户重定向到特定的 URL
  • ForwardAuthenticationFailureHandler 將用户轉發到指定的 URL,無論 AuthenticationException 的 類型如何
  • SimpleUrlAuthenticationFailureHandler 是用於默認情況下使用的組件,它會將用户重定向到指定的 failureUrl;否則,它將簡單地返回一個 401 響應

現在我們已經創建了自定義 AuthenticationFailureHandler,讓我們配置我們的應用程序並覆蓋 Spring 的 默認處理程序:

@Configuration
@EnableWebSecurity
public class SecurityConfiguration {

    @Bean
    public InMemoryUserDetailsManager userDetailsService() {
        UserDetails user1 = User.withUsername("user1")
            .password(passwordEncoder().encode("user1Pass"))
            .roles("USER")
            .build();
        return new InMemoryUserDetailsManager(user1);
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .anyRequest()
            .authenticated()
            .and()
            .formLogin()
            .failureHandler(authenticationFailureHandler())
        return http.build();
    }

    @Bean
    public AuthenticationFailureHandler authenticationFailureHandler() {
        return new CustomAuthenticationFailureHandler();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

請注意 failureHandler() 的 調用 – 它是我們告訴 Spring 使用我們的自定義組件而不是使用默認組件的地方。

4. 結論

在本示例中,我們通過利用Spring 的 AuthenticationFailureHandler 接口,自定義了應用程序的身份驗證失敗處理程序。

在本地運行時,您可以通過訪問 localhost:8080 進行訪問和測試應用程序。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.