Reputation: 1309
I'm unable to set SameSite cookie value to None.
Following is how i'm generating ResponseCookie object.
ResponseCookie cookie = ResponseCookie.from("Hb", cookieUserId)
.maxAge(!isEmpty(cookieUserId) ? MAX_COOKIE_DURATION : 0)
.domain("test.com")
.sameSite("None")
.secure(true)
.path("/")
.build();
response.addCookie(cookie)
Curl request to endpoint
curl -X POST "localhost:8080/v1/user/v" --data "{}" -v -H 'Content-Type: application/json'
Response:
< set-cookie: Hb=00b7be31-fc6d-4891-a07c-46b5ef2b423c; Max-Age=7776000; Expires=Fri, 8 Nov 2019 17:23:52 GMT; Path=/; Domain=test.com; Secure
As you can see SameSite attribute is missing from the cookie.
Spring Boot (version: 2.1.3.RELEASE) dependency
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
Upvotes: 10
Views: 24474
Reputation: 3050
I think the issue is that the underlying javax.servlet.http.Cookie
does not support the SameSite
attribute, let alone the new None
value.
Instead you can set this directly as a header, assuming your response is an instance of javax.servlet.http.HttpServletResponse
:
ResponseCookie cookie = ResponseCookie.from("Hb", cookieUserId)
.maxAge(!isEmpty(cookieUserId) ? MAX_COOKIE_DURATION : 0)
.domain("test.com")
.sameSite("None")
.secure(true)
.path("/")
.build();
response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());
Upvotes: 9
Reputation: 141
You can configure SameSite via TomcatContextCustomizer
:
@Configuration
public class MvcConfiguration implements WebMvcConfigurer {
@Bean
public TomcatContextCustomizer sameSiteCookiesConfig() {
return context -> {
final Rfc6265CookieProcessor cookieProcessor = new Rfc6265CookieProcessor();
cookieProcessor.setSameSiteCookies(SameSiteCookies.NONE.getValue());
context.setCookieProcessor(cookieProcessor);
};
}
Cookies for cross-site usage must specify SameSite=None; Secure
to enable inclusion in third party context (https://web.dev/samesite-cookie-recipes/).
Upvotes: 3
Reputation: 1
LukeSolar's answer was correct.The DefaultCookieSerializer is in the spring-session
jar.So you need to add spring-session
dependencies. You can refer to the official documentation https://spring.io/projects/spring-session
Upvotes: -1
Reputation: 3865
Here is a solution using your own CookieSerializer
bean. You can simply add this to your BootApplication Class:
@Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
cookieSerializer.setSameSite("None");
return cookieSerializer;
}
However this will override the default spring session attributes like the session same server.servlet.session.cookie.name
and maxAge server.servlet.session.cookie.max-age
. So a more complete solution looks like this:
...
@Autowired
private CookieConfiguration cookieConfiguration;
@Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
cookieSerializer.setSameSite("None");
cookieSerializer.setCookieName(cookieConfiguration.getName());
cookieSerializer.setDomainName(cookieConfiguration.getDomain());
cookieSerializer.setCookiePath(cookieConfiguration.getPath());
cookieSerializer.setUseHttpOnlyCookie(cookieConfiguration.isHttpOnly());
cookieSerializer.setUseSecureCookie(cookieConfiguration.isSecure());
cookieSerializer.setCookieMaxAge((Long.valueOf(cookieConfiguration.getMaxAge().toSeconds())).intValue());
// TODO check if rememberMeServices need additional configuration here
return cookieSerializer;
}
And the Configuration Class.
@ConfigurationProperties(prefix = "server.servlet.session.cookie")
@Configuration("cookieProperties")
@Getter
@Setter
public class CookieConfiguration {
private String comment;
private String domain;
private boolean httpOnly;
private Duration maxAge;
private String name;
private String path;
private boolean secure;
}
I'm not sure if there is a better solution to apply the configuration properties and only override the samesite
attribute. I can imagine in a future spring boot version this option/property will be included. Also as you see in the TODO code comment I did not test this solution with active remember-me services. The solution was tested in spring boot version 2.1.6.RELEASE
and inspire from the code found in org/springframework/boot/autoconfigure/session/SessionAutoConfiguration.class
.
Upvotes: 3