SpringBoot 低于 2.6 版本设置 SameSite=None,springboot 1.x set SameSite=none in embedded tomcat
SpringBoot 使用自带的 Tomcat 运行,设置 SameSite。
SpringBoot 过低的版本没有 SameSite 的属性设置,升级到 1.5.22 版本后,虽然 Rfc6265CookieProcessor 有 setSameSiteCookies 方法,但是方法逻辑有 BUG,当不是 None 时才可以设置成功:
SameSiteCookies sameSiteCookiesValue = this.getSameSiteCookies();
if (!sameSiteCookiesValue.equals(SameSiteCookies.NONE)) {
header.append("; SameSite=");
header.append(sameSiteCookiesValue.getValue());
}
但 SameSite 只是一串文本,因此,根据新版本的 tomcat 改写旧版本的 Rfc6265CookieProcessor 可以实现目的。
在 EmbeddedServletContainerFactory 中设置 TomcatContextCustomizers:
// 从配置文件读取值:custom.session.cookie.same-site=None
@Value("${custom.session.cookie.same-site:}")
private String sameSite;
@Bean public EmbeddedServletContainerFactory webServerFactory() { TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory(); // 设置 tomcat 上下文 factory.setTomcatContextCustomizers(Collections.singletonList(sameSiteCookiesConfig())); return factory; } /** * 自定义 tomcat 上下文,设置 SameSite * * @return tomcat 上下文 */ public TomcatContextCustomizer sameSiteCookiesConfig() { return context -> { final Rfc6265CookieProcessor cookieProcessor = new Rfc6265CookieProcessor() { @Override public String generateHeader(Cookie cookie) { String sameSiteAppend = null; if (StringUtils.hasText(sameSite)) { sameSiteAppend = "; SameSite=" + SameSiteCookies.fromString(sameSite).getValue(); } return super.generateHeader(cookie) + sameSiteAppend; } }; context.setCookieProcessor(cookieProcessor); }; } /** * SameSite 枚举 */ enum SameSiteCookies { UNSET("Unset"), NONE("None"), LAX("Lax"), STRICT("Strict"); private final String value; SameSiteCookies(String value) { this.value = value; } public String getValue() { return this.value; } public static SameSiteCookies fromString(String value) { SameSiteCookies[] values = values(); StringBuilder builder = new StringBuilder("["); for (SameSiteCookies sameSiteCookies : values) { if (sameSiteCookies.value.equals(value)) { return sameSiteCookies; } builder.append(sameSiteCookies.getValue()).append(", "); } String substring = builder.substring(0, builder.length() - 2) + "]"; throw new IllegalStateException("invalid sameSite cookies: [" + value + "], valid sameSite value is " + substring); } }
Set-Cookie 似乎只在首次访问时会响应(有时间去查一下),在页面通过 F12 查看请求时需要查看第一个请求才能看到 Set-Cookie 信息。