diff --git a/spring-session-core/src/main/java/org/springframework/session/web/http/CookieSerializer.java b/spring-session-core/src/main/java/org/springframework/session/web/http/CookieSerializer.java index d0e2f4ee..f05bb29a 100644 --- a/spring-session-core/src/main/java/org/springframework/session/web/http/CookieSerializer.java +++ b/spring-session-core/src/main/java/org/springframework/session/web/http/CookieSerializer.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -55,13 +55,19 @@ public interface CookieSerializer { * {@link HttpServletResponse}. * * @author Rob Winch + * @author Vedran Pavic * @since 1.1 */ class CookieValue { + private final HttpServletRequest request; + private final HttpServletResponse response; + private final String cookieValue; + private int cookieMaxAge = -1; + /** * Creates a new instance. * @@ -72,11 +78,14 @@ public interface CookieSerializer { * modified by the {@link CookieSerializer} when writing to the actual cookie so * long as the original value is returned when the cookie is read. */ - public CookieValue(HttpServletRequest request, HttpServletResponse response, + CookieValue(HttpServletRequest request, HttpServletResponse response, String cookieValue) { this.request = request; this.response = response; this.cookieValue = cookieValue; + if ("".equals(this.cookieValue)) { + this.cookieMaxAge = 0; + } } /** @@ -105,5 +114,24 @@ public interface CookieSerializer { public String getCookieValue() { return this.cookieValue; } + + /** + * Get the cookie max age. The default is -1 which signals to delete the cookie + * when the browser is closed, or 0 if cookie value is empty. + * @return the cookie max age + */ + public int getCookieMaxAge() { + return this.cookieMaxAge; + } + + /** + * Set the cookie max age. + * @param cookieMaxAge the cookie max age + */ + public void setCookieMaxAge(int cookieMaxAge) { + this.cookieMaxAge = cookieMaxAge; + } + } + } diff --git a/spring-session-core/src/main/java/org/springframework/session/web/http/DefaultCookieSerializer.java b/spring-session-core/src/main/java/org/springframework/session/web/http/DefaultCookieSerializer.java index e8764c83..9aea6c06 100644 --- a/spring-session-core/src/main/java/org/springframework/session/web/http/DefaultCookieSerializer.java +++ b/spring-session-core/src/main/java/org/springframework/session/web/http/DefaultCookieSerializer.java @@ -45,7 +45,7 @@ public class DefaultCookieSerializer implements CookieSerializer { private String cookiePath; - private int cookieMaxAge = -1; + private Integer cookieMaxAge; private String domainName; @@ -112,18 +112,18 @@ public class DefaultCookieSerializer implements CookieSerializer { sessionCookie.setHttpOnly(true); } - if ("".equals(requestedCookieValue)) { - sessionCookie.setMaxAge(0); - } - else if (this.rememberMeRequestAttribute != null - && request.getAttribute(this.rememberMeRequestAttribute) != null) { - // the cookie is only written at time of session creation, so we rely on - // session expiration rather than cookie expiration if remember me is enabled - sessionCookie.setMaxAge(Integer.MAX_VALUE); - } - else { - sessionCookie.setMaxAge(this.cookieMaxAge); + if (cookieValue.getCookieMaxAge() < 0) { + if (this.rememberMeRequestAttribute != null + && request.getAttribute(this.rememberMeRequestAttribute) != null) { + // the cookie is only written at time of session creation, so we rely on + // session expiration rather than cookie expiration if remember me is enabled + cookieValue.setCookieMaxAge(Integer.MAX_VALUE); + } + else if (this.cookieMaxAge != null) { + cookieValue.setCookieMaxAge(this.cookieMaxAge); + } } + sessionCookie.setMaxAge(cookieValue.getCookieMaxAge()); response.addCookie(sessionCookie); } @@ -205,8 +205,8 @@ public class DefaultCookieSerializer implements CookieSerializer { } /** - * Sets the maxAge property of the Cookie. The default is -1 which signals to delete - * the cookie when the browser is closed. + * Sets the maxAge property of the Cookie. The default is to delete the cookie when + * the browser is closed. * * @param cookieMaxAge the maxAge property of the Cookie */ diff --git a/spring-session-core/src/test/java/org/springframework/session/web/http/DefaultCookieSerializerTests.java b/spring-session-core/src/test/java/org/springframework/session/web/http/DefaultCookieSerializerTests.java index f83d3b42..2efabb3d 100644 --- a/spring-session-core/src/test/java/org/springframework/session/web/http/DefaultCookieSerializerTests.java +++ b/spring-session-core/src/test/java/org/springframework/session/web/http/DefaultCookieSerializerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -343,6 +343,16 @@ public class DefaultCookieSerializerTests { assertThat(getCookie().getMaxAge()).isEqualTo(0); } + @Test + public void writeCookieCookieMaxAgeExplicitCookieValue() { + CookieValue cookieValue = cookieValue(this.sessionId); + cookieValue.setCookieMaxAge(100); + + this.serializer.writeCookieValue(cookieValue); + + assertThat(getCookie().getMaxAge()).isEqualTo(100); + } + // --- secure --- @Test @@ -443,6 +453,17 @@ public class DefaultCookieSerializerTests { assertThat(getCookie().getMaxAge()).isEqualTo(Integer.MAX_VALUE); } + @Test + public void writeCookieRememberMeCookieMaxAgeOverride() { + this.request.setAttribute("rememberMe", true); + this.serializer.setRememberMeRequestAttribute("rememberMe"); + CookieValue cookieValue = cookieValue(this.sessionId); + cookieValue.setCookieMaxAge(100); + this.serializer.writeCookieValue(cookieValue); + + assertThat(getCookie().getMaxAge()).isEqualTo(100); + } + public void setCookieName(String cookieName) { this.cookieName = cookieName; this.serializer.setCookieName(cookieName);