Spring Securityのセッション管理を完全理解!SessionManagementConfigurerで並行ログインを制御する方法
Spring Bootを使ったWebアプリケーション開発を、 環境構築から実践まで一通り学びたい方には、 定評のある入門書が参考になります。
Spring Boot 3 プログラミング入門をAmazonで見る※ Amazon広告リンク
生徒
「ログイン中に別のブラウザで同じアカウントを使うと、どうなるんですか?」
先生
「それは並行ログインと呼ばれる状況ですね。Spring Securityでは、セッション管理の設定で制御できますよ。」
生徒
「セッションって具体的にどんな役割なんですか?どうやって制御するんですか?」
先生
「それでは、SessionManagementConfigurerの使い方と、並行ログイン制御の方法を一緒に学んでいきましょう。」
1. セッションとは?Spring Securityでの役割
セッションとは、ユーザーがログインしてからログアウトするまでの間に維持される情報の保存領域です。Spring Securityでは、ログインユーザーの認証情報や状態をセッションで保持します。
セッションがあることで、リクエストごとに再ログインせずに済み、ログイン状態を維持したまま複数の画面を行き来できます。
逆に言えば、セッションが切れた場合は再認証が必要になるため、セキュリティ上の制御点としても重要です。
2. Spring Securityのセッション管理の基本
Spring Securityでは、セッションの数や有効期限、タイムアウトなどをHttpSecurityの中で細かく制御できます。セッション管理を有効にするには、sessionManagement()メソッドを使用します。
このメソッドを使うことで、最大セッション数の設定、ログイン時の挙動、セッションの無効化処理などを行えます。
3. SessionManagementConfigurerの概要
SessionManagementConfigurerは、Spring Securityのセッション管理を行うための設定クラスです。セッション数の上限、並行ログインの許可・制限、セッション固定攻撃対策などを設定できます。
この設定を活用することで、例えば「同じアカウントで複数ブラウザからの同時ログインを禁止する」といったことが実現可能になります。
4. 並行ログイン(Concurrent Session)とは?
並行ログインとは、同じアカウントを使って複数のデバイス・ブラウザ・タブから同時にログインする状況です。セキュリティの観点では、企業システムなどではこれを禁止するケースが多くあります。
Spring Securityでは、この並行ログインを制御する設定がmaximumSessions()です。
5. 最大セッション数を制御する設定例
以下は、同時ログインを1セッションに制限し、別のログインが発生したら前のセッションを無効化する例です。
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.anyRequest().authenticated()
)
.formLogin()
.and()
.sessionManagement(session -> session
.maximumSessions(1)
.maxSessionsPreventsLogin(false)
);
return http.build();
}
}
maximumSessions(1)で同時ログインを1つに制限し、maxSessionsPreventsLogin(false)で新しいログインを許可しつつ、古いセッションを無効化します。
6. 前のセッションを拒否する設定
逆に、新しいログインを拒否して「すでにログイン中です」と表示させたい場合は、maxSessionsPreventsLogin(true)を指定します。
.sessionManagement(session -> session
.maximumSessions(1)
.maxSessionsPreventsLogin(true)
)
この設定を使えば、ログイン済みのユーザーが他の端末やブラウザからログインしようとしたときに、エラー画面にリダイレクトすることができます。
7. セッションの有効期限とタイムアウト設定
セッションのタイムアウト(一定時間アクセスがなければ自動ログアウト)は、application.propertiesまたはapplication.ymlで次のように設定できます。
server.servlet.session.timeout=15m
この設定により、15分間操作がなければセッションが無効化され、ログイン画面にリダイレクトされるようになります。
8. セッション情報を保持するSessionRegistryの活用
セッションを監視・管理したい場合は、SessionRegistryを使って現在ログイン中のユーザー一覧を取得できます。
@Bean
public SessionRegistry sessionRegistry() {
return new SessionRegistryImpl();
}
このBeanを使えば、ログインユーザーの一覧を管理画面に表示したり、不正アクセスを検出するための仕組みに応用することも可能です。
9. セッション管理の注意点とベストプラクティス
- セッションの数を制限することで、不正な同時ログインの抑止になる
- スマートフォン・PC両方から使う場合は制限しすぎるとユーザビリティが落ちる
- セッション固定攻撃対策として
sessionFixation().migrateSession()も併用する - ログアウト時にはセッション削除処理を確実に行うようにする
セッション管理はセキュリティの基本でありながら、柔軟に制御できる部分でもあります。要件に応じて適切な構成を選びましょう。