wanna be noble

貴族になりたいITエンジニアの雑記

Spring Actuator のヘルスチェックリクエストのたびに DB にセッション情報が格納されてしまった件

現在、Spring Boot のアプリケーションでヘルスチェック用のエンドポイントに Spring Actuator を利用しています。 ただヘルスチェックリクエストのたびに DB にセッション情報が格納されてしまう問題がありました、 本記事はこれを解消するため原因調査を行った記録となります。

アプリケーション構成

  • JDK
  • 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);

github.com

以下、原因特定までの過程

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 が見つかって解決!