Add SameSite cookie support for servlet web servers

Update Tomcat, Jetty and Undertow `ServletWebServerFactory`
implementations so that they can write SameSite cookie attributes.

The session cookie will be customized whenever the
`server.servlet.session.cookie.same-site` property is set.

Other cookies can be customized with the new `CookieSameSiteSupplier`
interface which can be registered using `@Bean` methods.

Closes gh-20971

Co-authored-by Andy Wilkinson <wilkinsona@vmware.com>
This commit is contained in:
Phillip Webb
2021-10-20 22:13:06 -07:00
parent efa04367b1
commit cf9156e497
13 changed files with 781 additions and 13 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,6 +41,7 @@ import org.springframework.boot.web.server.ErrorPageRegistrarBeanPostProcessor;
import org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.WebListenerRegistrar;
import org.springframework.boot.web.servlet.server.CookieSameSiteSupplier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@@ -73,9 +74,11 @@ public class ServletWebServerFactoryAutoConfiguration {
@Bean
public ServletWebServerFactoryCustomizer servletWebServerFactoryCustomizer(ServerProperties serverProperties,
ObjectProvider<WebListenerRegistrar> webListenerRegistrars) {
ObjectProvider<WebListenerRegistrar> webListenerRegistrars,
ObjectProvider<CookieSameSiteSupplier> cookieSameSiteSuppliers) {
return new ServletWebServerFactoryCustomizer(serverProperties,
webListenerRegistrars.orderedStream().collect(Collectors.toList()));
webListenerRegistrars.orderedStream().collect(Collectors.toList()),
cookieSameSiteSuppliers.orderedStream().collect(Collectors.toList()));
}
@Bean

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,11 +24,13 @@ import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.WebListenerRegistrar;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.boot.web.servlet.server.CookieSameSiteSupplier;
import org.springframework.core.Ordered;
import org.springframework.util.CollectionUtils;
/**
* {@link WebServerFactoryCustomizer} to apply {@link ServerProperties} to servlet web
* servers.
* {@link WebServerFactoryCustomizer} to apply {@link ServerProperties} and
* {@link WebListenerRegistrar WebListenerRegistrars} to servlet web servers.
*
* @author Brian Clozel
* @author Stephane Nicoll
@@ -41,7 +43,9 @@ public class ServletWebServerFactoryCustomizer
private final ServerProperties serverProperties;
private final Iterable<WebListenerRegistrar> webListenerRegistrars;
private final List<WebListenerRegistrar> webListenerRegistrars;
private final List<CookieSameSiteSupplier> cookieSameSiteSuppliers;
public ServletWebServerFactoryCustomizer(ServerProperties serverProperties) {
this(serverProperties, Collections.emptyList());
@@ -49,8 +53,14 @@ public class ServletWebServerFactoryCustomizer
public ServletWebServerFactoryCustomizer(ServerProperties serverProperties,
List<WebListenerRegistrar> webListenerRegistrars) {
this(serverProperties, webListenerRegistrars, null);
}
ServletWebServerFactoryCustomizer(ServerProperties serverProperties,
List<WebListenerRegistrar> webListenerRegistrars, List<CookieSameSiteSupplier> cookieSameSiteSuppliers) {
this.serverProperties = serverProperties;
this.webListenerRegistrars = webListenerRegistrars;
this.cookieSameSiteSuppliers = cookieSameSiteSuppliers;
}
@Override
@@ -77,6 +87,9 @@ public class ServletWebServerFactoryCustomizer
for (WebListenerRegistrar registrar : this.webListenerRegistrars) {
registrar.register(factory);
}
if (!CollectionUtils.isEmpty(this.cookieSameSiteSuppliers)) {
factory.setCookieSameSiteSuppliers(this.cookieSameSiteSuppliers);
}
}
}