diff --git a/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Response.java b/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Response.java index 37f946744591..8251fa9a5767 100644 --- a/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Response.java +++ b/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Response.java @@ -76,20 +76,20 @@ public class Response implements HttpServletResponse * String used in the {@code Comment} attribute of {@link Cookie} * to support the {@code HttpOnly} attribute. **/ - private static final String HTTP_ONLY_COMMENT = "__HTTP_ONLY__"; + protected static final String HTTP_ONLY_COMMENT = "__HTTP_ONLY__"; /** * String used in the {@code Comment} attribute of {@link Cookie} * to support the {@code Partitioned} attribute. **/ - private static final String PARTITIONED_COMMENT = "__PARTITIONED__"; + protected static final String PARTITIONED_COMMENT = "__PARTITIONED__"; /** * The strings used in the {@code Comment} attribute of {@link Cookie} * to support the {@code SameSite} attribute. **/ - private static final String SAME_SITE_COMMENT = "__SAME_SITE_"; - private static final String SAME_SITE_NONE_COMMENT = SAME_SITE_COMMENT + "NONE__"; - private static final String SAME_SITE_LAX_COMMENT = SAME_SITE_COMMENT + "LAX__"; - private static final String SAME_SITE_STRICT_COMMENT = SAME_SITE_COMMENT + "STRICT__"; + protected static final String SAME_SITE_COMMENT = "__SAME_SITE_"; + protected static final String SAME_SITE_NONE_COMMENT = SAME_SITE_COMMENT + "NONE__"; + protected static final String SAME_SITE_LAX_COMMENT = SAME_SITE_COMMENT + "LAX__"; + protected static final String SAME_SITE_STRICT_COMMENT = SAME_SITE_COMMENT + "STRICT__"; public enum OutputType { @@ -1494,7 +1494,7 @@ public Supplier> getSupplier() } } - private static class HttpCookieFacade implements HttpCookie + protected static class HttpCookieFacade implements HttpCookie { private final Cookie _cookie; private final String _comment; @@ -1622,12 +1622,12 @@ private static boolean isHttpOnlyInComment(String comment) return comment != null && comment.contains(HTTP_ONLY_COMMENT); } - private static boolean isPartitionedInComment(String comment) + protected static boolean isPartitionedInComment(String comment) { return comment != null && comment.contains(PARTITIONED_COMMENT); } - private static SameSite getSameSiteFromComment(String comment) + protected static SameSite getSameSiteFromComment(String comment) { if (comment == null) return null; @@ -1640,7 +1640,7 @@ private static SameSite getSameSiteFromComment(String comment) return null; } - private static String getCommentWithoutAttributes(String comment) + protected static String getCommentWithoutAttributes(String comment) { if (comment == null) return null; diff --git a/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/SessionHandler.java b/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/SessionHandler.java index aae6b5596b6b..214e2b871ce6 100644 --- a/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/SessionHandler.java +++ b/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/SessionHandler.java @@ -53,6 +53,7 @@ import org.eclipse.jetty.session.SessionIdManager; import org.eclipse.jetty.session.SessionManager; import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.StringUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -613,7 +614,8 @@ public void doHandle(String target, Request baseRequest, HttpServletRequest requ * CookieConfig * * Implementation of the jakarta.servlet.SessionCookieConfig. - * SameSite configuration can be achieved by using setComment + * SameSite configuration can be achieved by using setComment. + * Partitioned configuration can be achieved by using setComment. * * @see HttpCookie */ @@ -671,7 +673,19 @@ private void checkAvailable() public void setComment(String comment) { checkAvailable(); - _sessionManager.setSessionComment(comment); + + if (!StringUtil.isEmpty(comment)) + { + HttpCookie.SameSite sameSite = Response.HttpCookieFacade.getSameSiteFromComment(comment); + if (sameSite != null) + _sessionManager.setSameSite(sameSite); + + boolean partitioned = Response.HttpCookieFacade.isPartitionedInComment(comment); + if (partitioned) + _sessionManager.setPartitioned(partitioned); + + _sessionManager.setSessionComment(Response.HttpCookieFacade.getCommentWithoutAttributes(comment)); + } } @Override diff --git a/jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/SessionHandlerTest.java b/jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/SessionHandlerTest.java index 8053c8315ca0..cf0ed7df1d1d 100644 --- a/jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/SessionHandlerTest.java +++ b/jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/SessionHandlerTest.java @@ -168,7 +168,7 @@ public void afterEach() throws Exception } @Test - public void testSessionCookie() throws Exception + public void testSessionCookieConfig() throws Exception { Server server = new Server(); MockSessionIdManager idMgr = new MockSessionIdManager(server); @@ -190,12 +190,51 @@ public void testSessionCookie() throws Exception sessionCookieConfig.setSecure(false); sessionCookieConfig.setPath("/foo"); sessionCookieConfig.setMaxAge(99); + + //test setting SameSite and Partitioned the old way in the comment + sessionCookieConfig.setComment(Response.PARTITIONED_COMMENT + " " + Response.SAME_SITE_STRICT_COMMENT); - //for < ee10, SameSite cannot be set on the SessionCookieConfig, only on the SessionManager, or - //a default value on the context attribute org.eclipse.jetty.cookie.sameSiteDefault + HttpCookie cookie = mgr.getSessionManager().getSessionCookie(session, false); + assertEquals("SPECIAL", cookie.getName()); + assertEquals("universe", cookie.getDomain()); + assertEquals("/foo", cookie.getPath()); + assertFalse(cookie.isHttpOnly()); + assertFalse(cookie.isSecure()); + assertTrue(cookie.isPartitioned()); + assertEquals(99, cookie.getMaxAge()); + assertEquals(HttpCookie.SameSite.STRICT, cookie.getSameSite()); + + String cookieStr = HttpCookieUtils.getRFC6265SetCookie(cookie); + assertThat(cookieStr, containsString("; Partitioned; SameSite=Strict")); + } + + @Test + public void testSessionCookieViaSetters() throws Exception + { + Server server = new Server(); + MockSessionIdManager idMgr = new MockSessionIdManager(server); + idMgr.setWorkerName("node1"); + SessionHandler mgr = new SessionHandler(); + MockSessionCache cache = new MockSessionCache(mgr.getSessionManager()); + cache.setSessionDataStore(new NullSessionDataStore()); + mgr.setSessionCache(cache); + mgr.setSessionIdManager(idMgr); + + long now = System.currentTimeMillis(); + + ManagedSession session = new ManagedSession(mgr.getSessionManager(), new SessionData("123", "_foo", "0.0.0.0", now, now, now, 30)); + session.setExtendedId("123.node1"); + + //test setting up session cookie via setters on SessionHandler + mgr.setSessionCookie("SPECIAL"); + mgr.setSessionDomain("universe"); + mgr.setHttpOnly(false); + mgr.setSecureCookies(false); + mgr.setSessionPath("/foo"); + mgr.setMaxCookieAge(99); mgr.setSameSite(HttpCookie.SameSite.STRICT); mgr.setPartitioned(true); - + HttpCookie cookie = mgr.getSessionManager().getSessionCookie(session, false); assertEquals("SPECIAL", cookie.getName()); assertEquals("universe", cookie.getDomain());