Skip to content

Commit c399b13

Browse files
committed
jakartaee#175 Add support for SameSite cookies
Signed-off-by: Peter Major <peter.major@forgerock.com>
1 parent 6212615 commit c399b13

File tree

2 files changed

+134
-0
lines changed

2 files changed

+134
-0
lines changed

api/src/main/java/jakarta/servlet/SessionCookieConfig.java

+36
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
package jakarta.servlet;
1919

20+
import jakarta.servlet.http.Cookie.SameSite;
21+
2022
/**
2123
* Class that may be used to configure various properties of cookies used for session tracking purposes.
2224
*
@@ -236,4 +238,38 @@ public interface SessionCookieConfig {
236238
* @see jakarta.servlet.http.Cookie#getMaxAge
237239
*/
238240
public int getMaxAge();
241+
242+
/**
243+
* Sets the SameSite attribute for the session tracking cookies created on behalf of the application represented
244+
* by the <tt>ServletContext</tt> from which this <tt>SessionCookieConfig</tt> was acquired.
245+
*
246+
* @param sameSite the <i>SameSite</i> attribute of the session tracking cookies created on behalf of the
247+
* application represented by the <tt>ServletContext</tt> from which this
248+
* <tt>SessionCookieConfig</tt> was acquired. May be null to imply that the SameSite attribute
249+
* should not be set.
250+
*
251+
* @throws IllegalStateException if the <tt>ServletContext</tt> from which this <tt>SessionCookieConfig</tt> was
252+
* acquired has already been initialized
253+
*
254+
* @see jakarta.servlet.http.Cookie#setSameSite(SameSite)
255+
*
256+
* @since Servlet 5.0
257+
*/
258+
void setSameSite(SameSite sameSite);
259+
260+
/**
261+
* Gets the SameSite attribute of the session tracking cookies created on behalf of the application represented
262+
* by the <tt>ServletContext</tt> from which this <tt>SessionCookieConfig</tt> was acquired.
263+
*
264+
* <p>
265+
* By default, null is returned implying that the SameSite attribute should not be set.
266+
*
267+
* @return the SameSite attribute of the session tracking cookies created on behalf of the application represented
268+
* by the <tt>ServletContext</tt> from which this <tt>SessionCookieConfig</tt> was acquired.
269+
*
270+
* @see jakarta.servlet.http.Cookie#getSameSite
271+
*
272+
* @since Servlet 5.0
273+
*/
274+
SameSite getSameSite();
239275
}

api/src/main/java/jakarta/servlet/http/Cookie.java

+98
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ public class Cookie implements Cloneable, Serializable {
9292
private boolean secure; // ;Secure ... e.g. use SSL
9393
private int version = 0; // ;Version=1 ... means RFC 2109++ style
9494
private boolean isHttpOnly = false;
95+
private SameSite sameSite = null;
9596

9697
/**
9798
* Constructs a cookie with the specified name and value.
@@ -422,4 +423,101 @@ public void setHttpOnly(boolean isHttpOnly) {
422423
public boolean isHttpOnly() {
423424
return isHttpOnly;
424425
}
426+
427+
/**
428+
* Sets the <i>SameSite</i> attribute for this cookie with the provided value.
429+
*
430+
* <p>
431+
* When <code>sameSite</code> is not <code>null</code>, this cookie will have its <code>SameSite</code>
432+
* attribute set with the provided value.
433+
*
434+
* @param sameSite the <i>SameSite</i> attribute's value; may be null if the attribute should not be set
435+
*
436+
* @since Servlet 5.0
437+
*/
438+
public void setSameSite(SameSite sameSite) {
439+
this.sameSite = sameSite;
440+
}
441+
442+
/**
443+
* Returns the <i>SameSite</i> attribute associated with this cookie.
444+
*
445+
* @return the <i>SameSite</i> attribute associated with this cookie; may be null to indicate that the attribute
446+
* should not be set
447+
*
448+
* @since Servlet 5.0
449+
*/
450+
public SameSite getSameSite() {
451+
return sameSite;
452+
}
453+
454+
/**
455+
* The available values that can be used with the cookie's <i>SameSite</i> attribute.
456+
*/
457+
public enum SameSite {
458+
459+
/**
460+
* This mode effectively disables the protection provided by SameSite cookies.
461+
*
462+
* <p>
463+
* When SameSiteMode is {@literal None}, applications should have additional measures to protect cookies
464+
* from CSRF attacks.
465+
*
466+
* <p>
467+
* Browsers may default to {@link SameSite#LAX} or {@link SameSite#STRICT} when the flag is not
468+
* explicitly set by applications in the Set-Cookie header. Setting the {@literal SameSite} attribute to
469+
* {@literal None} ensures that this default behavior is disabled in browsers.
470+
*
471+
* <p>
472+
* Note that this mode is browser dependent, and browsers may require cookies to have the {@literal Secure}
473+
* attribute to be set at the same time.
474+
*/
475+
NONE("None"),
476+
/**
477+
* This mode allows sending cookies along for cross-site top level navigation requests.
478+
*
479+
* <p>
480+
* When SameSite is set to {@literal Lax}, the browser is allowed to send the cookie value along with top level
481+
* navigation requests when making requests cross-site.
482+
*/
483+
LAX("Lax"),
484+
/**
485+
* This mode prevents browsers from sending cookies along with any kind of cross-site requests.
486+
*
487+
* <p>
488+
* When SameSite is set to {@literal Strict}, the browser is not allowed to send the cookie value along with
489+
* cross-site requests.
490+
*
491+
* <p>
492+
* This behaviour could prevent applications seeing the end-user's session when a cross-site navigation
493+
* takes place. To overcome this, applications should consider utilising multiple cookies to keep track of
494+
* sessions.
495+
*/
496+
STRICT("Strict");
497+
498+
private final String value;
499+
500+
SameSite(String value) {
501+
this.value = value;
502+
}
503+
504+
/**
505+
* Retrieves the {@link SameSite} instance from its String representation.
506+
*
507+
* @param value the String to be converted
508+
* @return the corresponding {@link SameSite} enum
509+
*/
510+
public static SameSite fromString(String value) {
511+
return valueOf(value.toUpperCase(Locale.ENGLISH));
512+
}
513+
514+
/**
515+
* Gets the literal representation of the same site mode that can be included in Set-Cookie headers.
516+
*
517+
* @return the literal representation of the same site mode
518+
*/
519+
public String toLiteral() {
520+
return value;
521+
}
522+
}
425523
}

0 commit comments

Comments
 (0)