1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

SpringBoot+SpringSessionでSamesite Cookie対応

Last updated at Posted at 2020-09-02

SpringBoot+SpringSessionでSamesite Cookieを対応したのでメモ。

前提条件

  • chromeがSameSiteのデフォルトをLaxに変えたので、これまでSameSiteを付けていない場合はSameSite=Noneを付ける必要がある
  • SameSite=Noneの場合に不具合が起こるブラウザがある(chrome51~66やSafariの一部) ※ 以降非互換ブラウザと呼ぶ
  • つまUserAgentを見て、非互換ブラウザの場合はSameSiteを付けないようにする必要がある

実装検討過程

  • SpringSessionを使っていたのでCookieの設定はDefaultCookieSerializerで行う
  • Cookieをwriteしているところで、DefaultCookieSerializerをcloneしてSameSiteだけ書き換えようかと思ったが、DefaultCookieSerializerはgetterを持っていないのでcloneが面倒
  • DefaultCookieSerializerをラップして、SameSiteがNone指定の場合にSameSiteを設定しないDefaultCookieSerializerを別に用意しておいて、非互換ブラウザの場合はcookie書き込みの際にそれを使うようにする

実装

import org.springframework.session.web.http.DefaultCookieSerializer;

/**
 * SameSiteがNoneの場合に不具合を起こすクライアントに対してSameSite属性を付与しないDefaultCookieSerializer
 */
public class SameSiteIncompatibleSupportCookieSerialzer extends DefaultCookieSerializer {
	/**
	 * SameSite属性非互換ブラウザ向けのDefaultCookieSerializer
	 */
	private DefaultCookieSerializer sameSiteIncompatibleSupportDefaultCookieSerializer = new DefaultCookieSerializer();

	@Override
	public void writeCookieValue(CookieValue cookieValue) {
		if (非互換ブラウザの場合) {
			sameSiteIncompatibleSupportDefaultCookieSerializer.writeCookieValue(cookieValue);
		} else {
			super.writeCookieValue(cookieValue);
		}
	}

	@Override
	public void setUseSecureCookie(boolean useSecureCookie) {
		super.setUseSecureCookie(useSecureCookie);
		sameSiteIncompatibleSupportDefaultCookieSerializer.setUseSecureCookie(useSecureCookie);
	}

	@Override
	public void setUseHttpOnlyCookie(boolean useHttpOnlyCookie) {
		super.setUseHttpOnlyCookie(useHttpOnlyCookie);
		sameSiteIncompatibleSupportDefaultCookieSerializer.setUseHttpOnlyCookie(useHttpOnlyCookie);
	}

	@Override
	public void setCookiePath(String cookiePath) {
		super.setCookiePath(cookiePath);
		sameSiteIncompatibleSupportDefaultCookieSerializer.setCookiePath(cookiePath);
	}

	@Override
	public void setCookieName(String cookieName) {
		super.setCookieName(cookieName);
		sameSiteIncompatibleSupportDefaultCookieSerializer.setCookieName(cookieName);
	}

	@Override
	public void setCookieMaxAge(int cookieMaxAge) {
		super.setCookieMaxAge(cookieMaxAge);
		sameSiteIncompatibleSupportDefaultCookieSerializer.setCookieMaxAge(cookieMaxAge);
	}

	@Override
	public void setDomainName(String domainName) {
		super.setDomainName(domainName);
		sameSiteIncompatibleSupportDefaultCookieSerializer.setDomainName(domainName);
	}

	@Override
	public void setDomainNamePattern(String domainNamePattern) {
		super.setDomainNamePattern(domainNamePattern);
		sameSiteIncompatibleSupportDefaultCookieSerializer.setDomainNamePattern(domainNamePattern);
	}

	@Override
	public void setJvmRoute(String jvmRoute) {
		super.setJvmRoute(jvmRoute);
		sameSiteIncompatibleSupportDefaultCookieSerializer.setJvmRoute(jvmRoute);
	}

	@Override
	public void setUseBase64Encoding(boolean useBase64Encoding) {
		super.setUseBase64Encoding(useBase64Encoding);
		sameSiteIncompatibleSupportDefaultCookieSerializer.setUseBase64Encoding(useBase64Encoding);
	}

	@Override
	public void setRememberMeRequestAttribute(String rememberMeRequestAttribute) {
		super.setRememberMeRequestAttribute(rememberMeRequestAttribute);
		sameSiteIncompatibleSupportDefaultCookieSerializer.setRememberMeRequestAttribute(rememberMeRequestAttribute);
	}

	@Override
	public void setSameSite(String sameSite) {
		super.setSameSite(sameSite);
		sameSiteIncompatibleSupportDefaultCookieSerializer.setSameSite(sameSite);

		// SameSiteがNoneの場合は非互換ブラウザ向けのDefaultCookieSerializerにSameSiteにnullをセットする
		if ("None".equals(sameSite)) {
			sameSiteIncompatibleSupportDefaultCookieSerializer.setSameSite(null);
		}
	}
}
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?