Spring Securityのカスタム認証失敗ハンドラー

Spring SecurityのカスタムAuthenticationFailureHandler

1. 概要

このクイックチュートリアルでは、SpringBootアプリケーションでのSpringSecurityの authentication障害処理をカスタマイズする方法を説明します。 目標は、form loginアプローチ.を使用してユーザーを認証することです

Spring SecurityForm Login inSpring Bootの概要については、それぞれthisthisの記事を参照してください。

2. 認証と承認

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

ただし、リクエストの検証には異なる意味があり、異なる制約が適用されます。

  • AuthenticationAuthorization;の前に、受信した認証情報を検証します。ここで、ユーザー名とパスワードの両方が、アプリケーションが認識するものと一致することを確認します

  • Authorizationitは、正常に認証されたユーザーがアプリケーションの特定の機能にアクセスする権限を持っているかどうかを確認することについてです

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

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));
    }
}

デフォルトでは、Springredirectsは、エラーに関する情報を含むrequest parameterを使用してログインページに戻ります。

このアプリケーションでは、エラーに関する情報とその発生のタイムスタンプを含む401応答を返します。

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

  • DelegatingAuthenticationFailureHandlerは、AuthenticationExceptionサブクラスを異なるAuthenticationFailureHandlersに委任します。つまり、AuthenticationExceptionのインスタンスごとに異なる動作を作成できます。

  • ExceptionMappingAuthenticationFailureHandlerは、AuthenticationException’s fullクラス名に応じてユーザーを特定のURLにリダイレクトします

  • ForwardAuthenticationFailureHandlerは、AuthenticationExceptionのタイプに関係なく、指定されたURLにユーザーを転送します

  • SimpleUrlAuthenticationFailureHandlerはデフォルトで使用されるコンポーネントであり、指定されたfailureUrl, ifにユーザーをリダイレクトします。それ以外の場合は、単に401応答を返します

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

@Configuration
@EnableWebSecurity
public class SecurityConfiguration
  extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth)
      throws Exception {
        auth
          .inMemoryAuthentication()
          .withUser("example")
          .password("example")
          .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()callに注意してください。ここで、デフォルトのコンポーネントを使用する代わりに、カスタムコンポーネントを使用するようにSpringに指示できます。

4. 結論

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

この例の実装はthe Github projectにあります。

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