同時ログイン禁止(後勝ち)
実装
Spring Web Applicationで同時ログイン禁止(後勝ち)を実装するためには、WebSecurityConfigurerAdapterで以下の記述をする。
Spring Security 使い方メモ セッション管理 - Qiita
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests().antMatchers("/", "/home").permitAll().anyRequest().authenticated() .and().formLogin() .loginPage("/login").permitAll() .and() .logout().permitAll() .and() .sessionManagement().maximumSessions(1) .maxSessionsPreventsLogin(false) .expiredSessionStrategy(new MySessionInformationExpiredStrategy()); } } public class MySessionInformationExpiredStrategy implements SessionInformationExpiredStrategy { @Override public void onExpiredSessionDetected(SessionInformationExpiredEvent event) throws IOException, ServletException { DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); redirectStrategy.sendRedirect(event.getRequest(), event.getResponse(), "/login"); } }
動作
- ブラウザAでログイン
- ブラウザBでログイン
- ブラウザAでログイン後ページを更新 ブラウザAはログイン画面に遷移する。
ただし、ブラウザのタブで同時ログインした場合は、同じセッションIDを使い回すので、この方法ではできない。
java – Spring Securityで複数のブラウザタブを管理できますか? - コードログ
また、UsernamePassword認証をカスタマイズしている場合、UsernamePassword認証のFilterの方が先に実施されるため、この方法(セッション管理)は期待通りの動きにならない。
UsernamePassword認証Filterより前に実行されるようにできれば良いのだが...。
以下はMySessionInformationExpiredStrategyが実行されている場合のスタックトレース。