自定義Spring Security的身份驗證失敗處理

程式猿Knight發表於2019-05-30

1.概述

在本快速教程中,我們將演示如何在Spring Boot應用程式中自定義Spring Security的身份驗證失敗處理。目標是使用表單登入方法對使用者進行身份驗證。

2.認證和授權(Authentication and Authorization)

身份驗證和授權通常結合使用,因為它們在授予系統訪問許可權時起著重要且同樣重要的作用

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

  • 身份驗證 - 在授權之前;它是關於驗證收到的憑證;我們驗證使用者名稱和密碼是否與我們的應用程式識別的使用者名稱和密碼相匹配
  • 授權 - 用於驗證成功通過身份驗證的使用者是否有權訪問應用程式的某個功能

我們可以自定義身份驗證和授權失敗處理,但是,在此應用程式中,我們將專注於身份驗證失敗。

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<String, Object> data = new HashMap<>();
        data.put(
          "timestamp", 
          Calendar.getInstance().getTime());
        data.put(
          "exception", 
          exception.getMessage());
 
        response.getOutputStream()
          .println(objectMapper.writeValueAsString(data));
    }
}

預設情況下,Spring使用包含錯誤資訊的請求引數將使用者重定向回登入頁面

在此應用程式中,我們將返回401響應,其中包含有關錯誤的資訊以及錯誤發生的時間戳。

  • DelegatingAuthenticationFailureHandler將AuthenticationException子類委託給不同的AuthenticationFailureHandler,這意味著我們可以為AuthenticationException的不同例項建立不同的行為
  • ExceptionMappingAuthenticationFailureHandler根據AuthenticationException的完整類名將使用者重定向到特定的URL
  • 無論AuthenticationException的型別如何,ForwardAuthenticationFailureHandler都會將使用者轉發到指定的URL
  • SimpleUrlAuthenticationFailureHandler是預設使用的元件,如果指定,它會將使用者重定向到failureUrl;否則,它只會返回401響應

現在我們已經建立了自定義AuthenticationFailureHandler,讓我們配置我們的應用程式並覆蓋Spring的預設處理程式

@Configuration
@EnableWebSecurity
public class SecurityConfiguration 
  extends WebSecurityConfigurerAdapter {
 
    @Override
    protected void configure(AuthenticationManagerBuilder auth) 
      throws Exception {
        auth
          .inMemoryAuthentication()
          .withUser("baeldung")
          .password("baeldung")
          .roles("USER");
    }
 
    @Override
    protected void configure(HttpSecurity http) 
      throws Exception {
        http
          .authorizeRequests()
          .anyRequest()
          .authenticated()
          .and()
          .formLogin()
          .failureHandler(customAuthenticationFailureHandler());
    }
 
    @Bean
    public AuthenticationFailureHandler customAuthenticationFailureHandler() {
        return new CustomAuthenticationFailureHandler();
    }
}

注意failureHandler()呼叫,我們可以告訴Spring使用我們的自定義元件而不是使用預設元件。

4.結論

在此示例中,我們使用Spring的AuthenticationFailureHandler介面自定義了應用程式的身份驗證失敗處理程式

在Github專案中找到此示例的實現

在本地執行時,您可以在localhost:8080上訪問和測試應用程式.

相關文章