こんにちは、エキサイト株式会社の平石です。
今回は、Spring Securityでログイン後に任意の処理を行なってからログイン前にアクセスしたページにリダイレクトする方法をご紹介します。
はじめに
Spring SecurityはSpringで利用できる、認証とアクセス制御のためのフレームワークです。
IDとパスワードによるフォームログインやOAuth2ログインなど、さまざまな認証・アクセス制御の設定を行うことができます。
通常、ログインが必要なページに非ログイン状態でアクセスした場合、ログイン画面を表示しログインが必要なことをユーザーに伝えます。
そして、ログインが成功した場合には、ユーザーがアクセスしようとしていたページにリダイレクトしてあげるのが親切でしょう。
Spring Securityはそのような挙動をデフォルトで提供してくれており、こちら側で特別に設定する必要はありません。
しかし、ユーザーのログイン成功後に何か別の処理をしたいような場合には、少し工夫が必要です。
例えば、ログインに関する情報をDBに保存する(ログを取るなど)、外部認証後にアプリケーション側で独自に認証処理を入れる、のようなことが考えられます。
今回はそのための方法をご紹介します。
環境
この記事のソースコードは以下の環境で動作確認をしています。
- Java 21
- SpringBoot 3.2.1
- Gradle 8.5
実現方法
今回のソースコードは、OAuth2(Googleを利用)ログインを利用する際の例ですが、formLogin
を利用する場合も同様な設定で実現可能です。
SpringSecuirty6系では、以下のようにすることでOAuth2ログインを設定することが可能です。
@Configuration @EnableWebSecurity @EnableMethodSecurity @RequiredArgsConstructor public class SecurityConfig { /** * Spring Securityの処理フィルタ設定 * * @param http HttpSecurity * @return SecurityFilterChain * @throws Exception 例外 */ @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests( auth -> auth .requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll() .requestMatchers(HttpMethod.GET, "/login/google").permitAll() .requestMatchers(HttpMethod.GET, "/error").permitAll() .anyRequest().authenticated() ) .oauth2Login( login -> login .loginPage("/login/google") .failureUrl("/login/google?error") .permitAll() ) .logout( logout -> logout .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) .clearAuthentication(true) .deleteCookies("SESSION_ID") ); return http.build(); } }
OAuth2認証の詳細な設定と説明は、今回の記事の範囲外であるため省きます。
認証成功時の挙動を変更するためには、successHandler
に任意の処理を実行するように記述したHandler
のインスタンスを渡してあげます。
.oauth2Login( login -> login .loginPage("/login/google") .successHandler(ここにhandlerのインスタンスを渡す) .failureUrl("/login/google?error") .permitAll() )
デフォルトでは、SavedRequestAwareAuthenticationSuccessHandler
というものが利用されており、このHandlerによってログイン前にアクセスしていたページにリダイレクトするようにしているようです。
ログイン成功時に任意の処理を実行してからリダイレクトする場合には、このHandlerを継承した別のHandlerを作成し、これをsuccessHandler
に渡します。
@Component public class CustomAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler { public CustomAuthenticationSuccessHandler() { super.setDefaultTargetUrl("/"); } @Override public void onAuthenticationSuccess( HttpServletRequest request, HttpServletResponse response, Authentication authentication ) throws IOException, ServletException { // ここに任意の処理を記述する super.onAuthenticationSuccess(request, response, authentication); } }
DefaultTargetUrl
は、ログイン画面に直接アクセスした場合などで、元々アクセスしていたページが存在しない場合のデフォルトのリダイレクト先です。
@Configuration @EnableWebSecurity @EnableMethodSecurity @RequiredArgsConstructor public class SecurityConfig { private final CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler; @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http // 〜 略 〜 .oauth2Login( login -> login .loginPage("/login/google") .successHandler(customAuthenticationSuccessHandler) .failureUrl("/login/google?error") .permitAll(true) ) // 〜 略 〜 return http.build(); } }
終わりに
今回は、Spring Securityでログイン後に任意の処理を行なってからログイン前にアクセスしたページにリダイレクトする方法をご紹介しました。
では、また次回。