ログイン成功後にXXXを実行したい
- ログイン成功後、ユーザー情報のログを出力したい
- ログイン成功後、〇〇を満たすユーザーはXXにリダイレクトしたい
こうした要望をSpring Securityを使って実装するための方法を紹介します。
私の調べた限り、AuthenticationSuccessHandler
とAuthenticationSuccessEvent
の2種類の実装方法が存在しました。
versions
- Spring Boot 3.2.3
- Spring Security 6.2.2
AuthenticationSuccessHandler
まずはAuthenticationSuccessHandler
を継承したカスタムのハンドラクラスを作成します。
@Component
public class CustomLoginSuccessHandler implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(final HttpServletRequest request, final HttpServletResponse response,
final Authentication authentication) throws IOException, ServletException {
response.sendRedirect("/");
}
}
そして、Spring SecurityでおなじみのSecurityConfig
のsecurityFilterChain
の中でsuccessHandler
メソッドを使って先ほどのハンドラをセットします。
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
@RequiredArgsConstructor
public class SecurityConfig {
private final CustomLoginSuccessHandler customLoginSuccessHandler;
@Bean
public SecurityFilterChain securityFilterChain(final HttpSecurity http) throws Exception {
http //
.oauth2Login(oauth2Login -> oauth2Login//
.loginPage("/oauth2/authorization") //
.successHandler(customLoginSuccessHandler)//
);
return http.build();
}
}
こうすることで、Spring Securityによる認証が成功した後にsuccessHandler
で指定したcustomLoginSuccessHandler
の処理が呼び出されることになります。
AuthenticationSuccessEvent
AuthenticationSuccessEvent
はアプリケーションでの認証成功を検知し起動するイベントです。
認証失敗を検知するAuthenticationFailureEvent
も存在します。
@Component
@Slf4j
public class AuthenticationEvents {
@EventListener
public void onSuccess(AuthenticationSuccessEvent success) {
log.info("Authentication is succeeded.");
}
}
注意点として、onSuccess
メソッドの中ではSecurityContextHolder.getContext().getAuthentication()
がnullを返します。
これは、SecurityContextHolderに認証オブジェクト(Authentication object)がセットされる前にonSuccess
が呼ばれていることを意味しています。
また、AuthenticationEvents
ではリダイレクトなどのHTTPレスポンスを直接いじるような処理は実装できず、そうした処理はAuthenticationSuccessHandler
で実装するのがbetterです。
参考