Spring Boot + Spring Security使用時のCSRFとSessionTimeoutの問題

2016/06/25

Spring Boot + Spring Security使用時のSessionTimeout対応の最後に、「CSRF対策が有効の場合、POST時にSessionTimeoutしているとHTTP Status:403 Forbiddenが発生してしまう問題がある。」と記載した。

今回はこの問題の対応方法を記載し、Spring SecurityのJavaConfigの完成形を作る。

まずこの問題が起こる原因は、CSRF対策の仕組みが、リクエストパラメータで送られるCSRF TokenとSessionに保存されたCSRF Tokenを比較するというロジックであり、Sessionに依存しているから。
SessionがTimeoutによって消滅しているときにCSRF Tokenをリクエストパラメータで送っても、Sessionは既に存在していないから必ずTokenが違うということになる。

対策したソースを記載する。

前回との差分は1点。

  • exceptionHandling().accessDeniedHandler()にAccessDeniedExceptionが発生したときの処理を書いた無名クラスを設定した。

発生したExceptionが、CSRF Tokenがない場合に発生するMissingCsrfTokenExceptionだった場合、SessionTimeoutであると判断してSessionExpiredDetectingLoginUrlAuthenticationEntryPointを実行する。
SessionExpiredDetectingLoginUrlAuthenticationEntryPointではSessionが当然Invalidであると判断するので、/login?timeoutにリダイレクトしてくれる。

-Java
-