Spring Actuator のヘルスチェックリクエストのたびに DB にセッション情報が格納されてしまった件
現在、Spring Boot のアプリケーションでヘルスチェック用のエンドポイントに Spring Actuator を利用しています。 ただヘルスチェックリクエストのたびに DB にセッション情報が格納されてしまう問題がありました、 本記事はこれを解消するため原因調査を行った記録となります。
アプリケーション構成
- JDK
- Amazon Corretto 17
- Spring Boot 3.0
- Spirng Framework 6.0
- Spring Security 6.0
- Spring Session 3.0
- Spring Actuator 3.0
結論
Spring Session が提供するフィルターがセッション情報の永続化を行なっている。
org.springframework.session.web.http.SessionRepositoryFilter
そのため、SessionRepositoryFilter
より前に実行されるフィルター ExcludeSessionRepositoryFilter
を設定し、ヘルスチェックリクエストの場合にリクエスト属性に SessionRepositoryFilter が適用済みであると追加してあげればよい。
httpRequest.setAttribute("org.springframework.session.web.http.SessionRepositoryFilter.FILTERED", Boolean.TRUE);
以下、原因特定までの過程
1. Spring Security の Configuration を見直す
ざっと調べたところ認証周りがあやしかったので、Spring Security の Configuration を見直しましたが未認証の設定になっており特に問題はなかったです。
2. Spring Framework の DEBUG ログを眺めてみる
Spring Framework のログレベルを DEBUG にするとセッション作成時にスタックトレースを出してくれた。めちゃくちゃ便利!!
2023-07-04 23:21:03.113 [DEBUG] [http-nio-8080-exec-3] org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper: A new session was created. To help you troubleshoot where the session was created we provided a StackTrace (this is not an error). You can prevent this from appearing by disabling DEBUG logging for org.springframework.session.web.http.SessionRepositoryFilter.SESSION_LOGGER java.lang.RuntimeException: For debugging purposes only (not an error) at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.getSession(SessionRepositoryFilter.java:313) ~[spring-session-core-3.0.1.jar:3.0.1] ...
スタックトレースを遡ることで、org.springframework.session.web.http.SessionRepositoryFilter
がセッション作成をしていることが分かった。
Spring Security は特に関係なかった。。
3. SessionRepositoryFilter を特定のパスの時だけ無効にする方法を調べる
Is it possible to exclude some url from the SessionRepositoryFilter · Issue #244 · spring-projects/spring-session · GitHub の issue が見つかって解決!