1. 概要

このクイックチュートリアルでは、Spring BootアプリケーションでのSpringSecurityの認証の失敗処理をカスタマイズする方法を説明します。 目標は、フォームログインアプローチを使用してユーザーを認証することです。

SpringSecurityおよびFormLogin in Spring Boot の概要については、thisおよびthisの記事を参照してください。 、 それぞれ。

2. 認証と承認

認証承認は、システムへのアクセスを許可する際に不可欠であり、同様に重要な役割を果たすため、組み合わせて使用されることがよくあります。

ただし、それらには異なる意味があり、要求を検証するときに異なる制約を適用します。

  • 認証承認の前;受信したクレデンシャルの検証に関するものです。 ここで、ユーザー名とパスワードの両方が、アプリケーションが認識するものと一致することを確認します
  • 承認これは、正常に認証されたユーザーがアプリケーションの特定の機能にアクセスするためのアクセス許可を持っているかどうかを確認することです。

認証承認の両方の障害処理をカスタマイズできますが、このアプリケーションでは、認証の失敗に焦点を当てます。

3. SpringSecurityの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応答を返します。

デフォルトのコンポーネントに加えて、 Spring には、実行したいことに応じて活用できるコンポーネントをすぐに使用できる他のコンポーネントがあります。

  • DelegatingAuthenticationFailureHandler は、AuthenticationExceptionサブクラスをさまざまなAuthenticationFailureHandlersに委任します。つまり、AuthenticationExceptionのさまざまなインスタンスに対してさまざまな動作を作成できます。
  • ExceptionMappingAuthenticationFailureHandler は、 AuthenticationExceptionのフルクラス名に応じて、ユーザーを特定のURLにリダイレクトします
  • ForwardAuthenticationFailureHandler は、 AuthenticationException のタイプに関係なく、指定されたURLにユーザーを転送します。
  • SimpleUrlAuthenticationFailureHandler はデフォルトで使用されるコンポーネントであり、指定されている場合は failureUrl、にユーザーをリダイレクトします。 それ以外の場合は、単に401応答を返します

カスタムAuthenticationFailureHandlerを作成したので、アプリケーションを構成して、Springのデフォルトハンドラーをオーバーライドします。

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) 
      throws Exception {
        auth.inMemoryAuthentication()
          .withUser("user1").password(passwordEncoder.encode("user1Pass")).roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http) 
      throws Exception {
        http
          .authorizeRequests()
          .anyRequest()
          .authenticated()
          .and()
          .formLogin()
          .failureHandler(authenticationFailureHandler());
    }

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

failureHandler()呼び出しに注意してください。ここで、 Spring に、デフォルトのコンポーネントを使用する代わりにカスタムコンポーネントを使用するように指示できます。

4. 結論

この例では、SpringのAuthenticationFailureHandlerインターフェイスを利用して、アプリケーションの認証失敗ハンドラーをカスタマイズしました。

この例の実装は、Githubプロジェクトにあります。

ローカルで実行している場合は、 localhost:8080でアプリケーションにアクセスしてテストできます。