javacookiesservlets

How to specify SameSite value for javax.servlet.http.Cookie


Having for example:

import javax.servlet.http.Cookie;

// some code ....


        Cookie cookie = new Cookie(name, value);
        
        cookie.setMaxAge(someValue);

How do I set SameSite value for it ?


Solution

  • Servlet 6.0+

    It's only possible since Servlet API version 6.0 (part of Jakarta EE 10) which introduced a new Cookie#setAttribute() method.

    Cookie cookie = new Cookie(name, value);
    cookie.setMaxAge(maxAge);
    cookie.setAttribute("SameSite", "None");
    response.addCookie(cookie);
    

    Note that there's no Cookie#setSameSite() method for the very simple reason that the proposal for the SameSite attribute, which was posted at 7 August 2017, is to the day of today still not part of the official HTTP cookie spec. This was also the reason why it took so long before it was possible to manipulate the SameSite attribute via the Servlet API. The Servlet API guys basically waited for it to end up in the official spec. But in the end it didn't seem to make it into the final spec as quick as expected but yet Google Chrome is already using it to full extent without backwards compatibility. So ultimately a more generic method was introduced and the rest of Cookie API was slightly adjusted (initiated by yours truly).

    Servlet 5.0-

    If you can't upgrade your servletcontainer to a version implementing a minimum of Servlet API version 6.0 (e.g. Tomcat 10.1+, Jetty 12+, WildFly 27+, GlassFish 7+, etc), then you'll have to create the cookie as a plain vanilla String following the syntax of the Set-Cookie header and add it to the response using HttpServletResponse#addHeader().

    String cookie = name + "=" + value + "; Max-Age=" + maxAge + "; SameSite=None";
    response.addHeader("Set-Cookie", cookie);
    

    JSESSIONID cookie

    If you actually wanted to manipulate the SameSite attribute of the servletcontainer's built-in JSESSIONID cookie, then you have to adjust the configuration of the server itself and/or the proxy in front of it. Consult its documentation for detail.

    In case of for example Tomcat 8.5.48+/9.0.28+ you can configure it from the webapp on via META-INF/context.xml as follows:

    <?xml version="1.0" encoding="UTF-8"?>
    <Context>
       <CookieProcessor sameSiteCookies="none" />
    </Context>
    

    And in case of Jetty 9.4.23+ you can configure it from the webapp on via WEB-INF/web.xml with one of __SAME_SITE_*__ constants defined in org.eclipse.jetty.http.HttpCookie as a cookie config comment as follows:

    <session-config>
        <cookie-config>
            <comment>__SAME_SITE_NONE__</comment>
        </cookie-config>
    </session-config>