SpringBootでTomcat使用時においてCookieのセッション(JSESSIONID)にSameSite属性を設定する方法

JavaのSprigBootで組み込みTomcat使用時に、Cookie、特にJSESSIONIDにSameSite属性を設定するときに、予想外に苦労したので、苦労話と設定方法を載せておきます。

JavaのサーブレットAPIの4.0仕様では、SessionにSameSiteを実装していない

驚きなのですが、CORS対応時代であり、この記事を書いている時点で、JavaのサーブレットAPIの仕様では、SessionクラスはSameSiteを持っているように実装されていません。

なので、SessionCookieConfigで簡単に設定する……というわけにはいきませんでした。

webサーバーの設定ファイルでSameSite属性を付けるように変更する方法

webサーバーの設定ファイルでJSESSIONIDを書き換える方法は、下記の記事に書かれていましたが、組み込みTomcatのjar形式でコードを書いていたので、この方法は適用できませんでした。

Apache Tomcat連携サーバで、CookieにSameSite属性を設定する方法 - Qiita
2/17以降にGoogle Chromeを使って、「①あるドメインのURL」→(POST or GET)→「②別ドメインのURL」→(POST)→「③元のドメインのURL」の順でページ遷移し…
Setting the SameSite Attribute on the JSESSIONID cookie for Java based deployments
SameSite is a requirement in latest Chrome starting Feb 2020 Read a very good and easy-to-understand explainer on SameSite Turns out none of  Java-based ecosyst...

SpringBootのTomcatContextCustomizerでCookieProcessorを使ってSameSite属性を設定する

SpringBootのTomcatContextCustomizerというクラスでCookieProcessorを使ってSameSite属性を設定する方法が下記の記事で紹介されていました。

Spring Boot(Spring Web MVC + Tomcat)におけるSameSite Cookie - Qiita
Spring Boot(Spring Web MVC + Tomcat)でSameSite Cookieを使うにはどのようにすればいいか、調べてみました。SameSite Cookieとはなにか…

この方法だと、私の環境下だとなぜか機能しなかったということと、意味はないけれど、JSESSIONIDのように特定のCookieのみにSameSite属性を付けられる方法ではなさそうだったので、諦めました。

SpringSessionならデフォルトでSameSite属性が設定されているので使う

さっきの記事で紹介されているように、SpringSessionならデフォルトでSameSite属性が設定されているので、おとなしく SpringSession を使うのがよい気がします。

spring-session/spring-session-core/src/main/java/org/springframework/session/web/http/DefaultCookieSerializer.java at 2.2.0.RELEASE · spring-projects/spring-session
Spring Session. Contribute to spring-projects/spring-session development by creating an account on GitHub.

Filter処理でSessionを書き換えてSameSite属性を設定する

SpringSession入れたり、クラスカスタマイズするほどじゃない、
少しSessionにSameSite属性とか気軽に設定できればいいんだ、
どうせそのうち対応されるだろうから、もっとバカな方法でいいんだ、
とダメなことを考える人には、Filter処理でSessionを書き換えてSameSite属性を設定する方法を紹介しておきます。

Filter処理(Filterクラスを実装する方法)でServletResponseをリフレッシュしてから、手動でヘッダーにセッションを設定し直すという方法です。

ServletResponseをリフレッシュするのは、setHeaderやaddHeaderはあっても、deleteHeaderやremoveHeaderみたいに、すでにあるヘッダー(ここではセッションのCookie)をどうにかする方法が、これまた不便ですが用意されていないので、コミットされる前の ServletResponse を一度リフレッシュすることで、Sessionのcookieを設定し直すとう方法です。

    HttpSession session = ((HttpServletRequest) request).getSession();
    String sessionId = session.getId();
    response.reset();
    ((HttpServletResponse) response).setHeader(HttpHeaders.SET_COOKIE, "JSESSIONID=" + sessionId + "; SameSite=None;  Httponly; Secure");

一応はこの方法でも、JSESSIONIDにSameSite属性を設定できて、CORSでも問題なくセッション維持ができました。

JavaのSESSION,Cookieの設定で参考にしたページ一覧

Attention Required! | Cloudflare
https://www.thetopsites.net/article/59892503.shtml
JavaでCookieにSameSite属性をつける - Qiita
(20/01/08 19:45追記)概要javax.servlet.http.CookieにはSameSite属性を付与するAPIがありません。そんな時の対応です。ちなみにSameSite属…
SessionCookieConfig (Servlet 3.1 API Documentation - Apache Tomcat 8.0.53)
Attention Required! | Cloudflare
Attention Required! | Cloudflare

タイトルとURLをコピーしました