From e8076228e037a40999bd4b05addd8966835126ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20B=C3=BCtler?= Date: Wed, 4 Dec 2024 13:52:05 +0100 Subject: [PATCH] Set domain on session cookie in session handler --- .../vertx/ext/web/handler/SessionHandler.java | 19 ++++++++++++++++++ .../web/handler/impl/SessionHandlerImpl.java | 10 ++++++++++ .../tests/handler/SessionHandlerTestBase.java | 20 +++++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/vertx-web/src/main/java/io/vertx/ext/web/handler/SessionHandler.java b/vertx-web/src/main/java/io/vertx/ext/web/handler/SessionHandler.java index 57b562c59b..b6f9c0427d 100644 --- a/vertx-web/src/main/java/io/vertx/ext/web/handler/SessionHandler.java +++ b/vertx-web/src/main/java/io/vertx/ext/web/handler/SessionHandler.java @@ -47,6 +47,12 @@ public interface SessionHandler extends PlatformHandler { */ String DEFAULT_SESSION_COOKIE_NAME = "vertx-web.session"; + /** + * Default domain of session cookie i.e. no domain is set. More info: + * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#domaindomain-value + */ + String DEFAULT_SESSION_COOKIE_DOMAIN = null; + /** * Default path of session cookie */ @@ -148,6 +154,19 @@ static SessionHandler create(SessionStore sessionStore) { @Fluent SessionHandler setSessionCookieName(String sessionCookieName); + /** + * Set the session cookie domain. Only the current domain can be set as the + * value, or a domain of a higher order, unless it is a public suffix. Setting + * the domain will make the cookie available to it, as well as to all its + * subdomains. If omitted, this attribute defaults to the host of the current + * document URL, not including subdomains. + * + * @param sessionCookieDomain the session cookie domain + * @return a reference to this, so the API can be used fluently + */ + @Fluent + SessionHandler setSessionCookieDomain(String sessionCookieDomain); + /** * Set the session cookie path * diff --git a/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/SessionHandlerImpl.java b/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/SessionHandlerImpl.java index b3699e339f..668cc76ddb 100644 --- a/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/SessionHandlerImpl.java +++ b/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/SessionHandlerImpl.java @@ -49,6 +49,7 @@ public class SessionHandlerImpl implements SessionHandler { private final SessionStore sessionStore; private String sessionCookieName = DEFAULT_SESSION_COOKIE_NAME; + private String sessionCookieDomain = DEFAULT_SESSION_COOKIE_DOMAIN; private String sessionCookiePath = DEFAULT_SESSION_COOKIE_PATH; private long sessionTimeout = DEFAULT_SESSION_TIMEOUT; private boolean nagHttps = DEFAULT_NAG_HTTPS; @@ -90,6 +91,12 @@ public SessionHandler setCookieHttpOnlyFlag(boolean httpOnly) { return this; } + @Override + public SessionHandler setSessionCookieDomain(String sessionCookieDomain) { + this.sessionCookieDomain = sessionCookieDomain; + return this; + } + @Override public SessionHandler setSessionCookieName(String sessionCookieName) { this.sessionCookieName = sessionCookieName; @@ -150,6 +157,9 @@ public Future flush(RoutingContext context, boolean ignoreStatus) { * @param cookie the cookie to set */ private void setCookieProperties(Cookie cookie, boolean expired) { + if (sessionCookieDomain != null) { + cookie.setDomain(sessionCookieDomain); + } cookie.setPath(sessionCookiePath); cookie.setSecure(sessionCookieSecure); cookie.setHttpOnly(sessionCookieHttpOnly); diff --git a/vertx-web/src/test/java/io/vertx/ext/web/tests/handler/SessionHandlerTestBase.java b/vertx-web/src/test/java/io/vertx/ext/web/tests/handler/SessionHandlerTestBase.java index 2c33cde3a4..c7fdfb57a8 100644 --- a/vertx-web/src/test/java/io/vertx/ext/web/tests/handler/SessionHandlerTestBase.java +++ b/vertx-web/src/test/java/io/vertx/ext/web/tests/handler/SessionHandlerTestBase.java @@ -55,6 +55,26 @@ public void testSessionCookieName() throws Exception { }, 200, "OK", null); } + @Test + public void testSessionCookieDomain() throws Exception { + router.route().handler(SessionHandler.create(store).setSessionCookieDomain("example.com")); + router.route().handler(rc -> rc.response().end()); + testRequest(HttpMethod.GET, "/", null, resp -> { + String setCookie = resp.headers().get("set-cookie"); + assertTrue(setCookie.contains("Domain=example.com")); + }, 200, "OK", null); + } + + @Test + public void testSessionCookieDefaultDomain() throws Exception { + router.route().handler(SessionHandler.create(store)); + router.route().handler(rc -> rc.response().end()); + testRequest(HttpMethod.GET, "/", null, resp -> { + String setCookie = resp.headers().get("set-cookie"); + assertFalse(setCookie.contains("Domain")); + }, 200, "OK", null); + } + @Test public void testSessionCookiePath() throws Exception { router.route().handler(SessionHandler.create(store).setSessionCookiePath("/path"));