Spring WebFlux で InMemoryWebSessionStore にセッションタイムアウトを設定する
概要
Spring WebFlux を使いながら application.properties で spring.session.timeout を設定した際、設定が効きませんでした。WebFlux の WebSessionStore をカスタマイズして、セッションタイムアウトの間隔を設定する方法を説明します。
目次
確認環境
- Spring Boot 2.0.3.RELEASE
- Kotlin 1.2.50
参考情報
- 『Spring Bootリファレンス・ガイド』より第4部「Spring Boot の重要機能」(1) - M12i.
- EnableConfigurationProperties の使い方
解説
設定方法
以下の示す様に WebSessionManager に設定する WebSessionStore を変更します。
@EnableWebFluxSecurity @EnableConfigurationProperties(SessionProperties::class) @Configuration class ExampleConfig { // ... @Bean fun webSessionManager(properties: SessionProperties): WebSessionManager { return DefaultWebSessionManager().apply { sessionIdResolver = HeaderWebSessionIdResolver().apply { headerName = "X-Sample" // セッションIDのヘッダー名を変更する場合には設定 } sessionStore = CustomizableInMemoryWebSessionStore(properties) } } }
WebSessionManager としては DefaultWebSessionManager を使います。DefaultWebSessionManager では、WebSessionIdResolver と WebSessionStore を指定します。デフォルトは、CookieWebSessionIdResolver と InMemoryWebSessionStore です。
セッションタイムアウトには、WebSessionStore が関係しています。WebSessionStore がセッションの生成と破棄を行っています。デフォルトの InMemoryWebSessionStore では、InMemoryWebSession オブジェクトの maxIdleTime で有効期間の判定を行っています。デフォルトの maxIdleTime は 30 分になっています。
WebSessionStore に application.properties の設定内容を渡すために、EnableConfigurationProperties を使って SessionProperties を Bean として設定しています。これにより、webSessionManager メソッドの引数で SessionProperties Bean を注入できる様になります。SessionProperties は application.properties のうち、spring.session に含まれる設定内容を保持しています。InMemoryWebSessionStore 自体は SessionProperties を受け取らないため、InMemoryWebSessionStore を拡張したクラスのオブジェクトを使います。
本筋からは逸れますが、WebSessionIdResolver はリクエストとレスポンスにおいてセッションIDの取得と設定を行う処理を持ちます。HeaderWebSessionIdResolver を使えば、セッションIDを設定するヘッダーを変更できます。上記の例では、X-Sample
ヘッダーにセッションIDを設定させています。
次に、InMemoryWebSessionStore を拡張した CustomizableInMemoryWebSessionStore です。
class CustomizableInMemoryWebSessionStore( private val properties: SessionProperties ) : InMemoryWebSessionStore() { override fun createWebSession(): Mono<WebSession> = super .createWebSession() .map(this::applySessionProperties) private fun applySessionProperties(session: WebSession) = session.apply { maxIdleTime = properties.timeout } }
WebSession オブジェクトを生成する際に、maxIdleTime を application.properties の spring.session.timeout の値に変更しています。