How to set SameSite cookie attribute with Java?
I want to be able to set SameSite
property of cookie from my java application. However, jakarta.servlet.http.Cookie
from tomcat library doesn't have a setSameSite
method. How can I do this?
Solution
A setSameSite
method hasn't been introduced yet because SameSite
is not included yet in official HTTP specifications, even though it is supported by most web browsers.
In Servlet API version 6.0, there is a method that allows adding any attribute to the cookie, that is setAttribute
. For example, if you want to set SameSite=None
, you can do:
var cookie = new Cookie(cookieName, cookieValue);
cookie.setAttribute("SameSite", "None");
response.addCookie(cookie);
If you're using a version lower than 6.0, then you'll have to create the cookie as a string and add it to the Set-Cookie
header
String cookie = cookieName + "=" + cookieValue + "; SameSite=None";
response.addHeader("Set-Cookie", cookie);
Alternative #1
If you're using Spring Boot or Spring MVC, you can set the SameSite attribute using a CookieSerializer
bean. This is especially useful for session cookies:
@Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer serializer = new DefaultCookieSerializer();
serializer.setSameSite("Strict"); // or "Lax", "None"
serializer.setUseSecureCookie(true); // recommended for SameSite=None
return serializer;
}
This approach is more maintainable and works across different servlet containers.
Alternative #2
If you're using Servlet 4.x or lower and want to set SameSite for all cookies, you can use a Servlet Filter to modify the Set-Cookie header globally:
@WebFilter("/*")
public class SameSiteCookieFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
chain.doFilter(request, response);
if (response instanceof HttpServletResponse) {
Collection<String> headers = ((HttpServletResponse) response).getHeaders("Set-Cookie");
boolean firstHeader = true;
for (String header : headers) {
if (header.contains("SameSite")) continue;
String newHeader = header + "; SameSite=Lax";
if (firstHeader) {
((HttpServletResponse) response).setHeader("Set-Cookie", newHeader);
firstHeader = false;
} else {
((HttpServletResponse) response).addHeader("Set-Cookie", newHeader);
}
}
}
}
}
This ensures all cookies have the SameSite attribute, even if set by third-party libraries.
Alternative #3
If you're using Spring Security, you can set SameSite for session cookies via configuration properties (Spring Boot 2.6+):
server:
servlet:
session:
cookie:
same-site: strict # or lax, none
Or programmatically:
@Configuration
public class SessionConfig {
@Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> cookieCustomizer() {
return factory -> factory.addContextCustomizers(context ->
context.setSessionCookieSameSite("Strict")
);
}
}
This is the most future-proof way if you're using modern Spring Boot and Tomcat.