From 97fef0f9bd1119cdf3dc83e56b4f17802af9abe6 Mon Sep 17 00:00:00 2001 From: Rob Winch Date: Tue, 6 Sep 2016 21:19:33 -0500 Subject: [PATCH] Polish Base64 DefaultCookieSerializer Support Issue gh-611 --- .../session/web/http/Base64.java | 1 + .../web/http/DefaultCookieSerializer.java | 30 ++++++++++--------- .../http/DefaultCookieSerializerTests.java | 26 +++++++++------- 3 files changed, 33 insertions(+), 24 deletions(-) diff --git a/spring-session/src/main/java/org/springframework/session/web/http/Base64.java b/spring-session/src/main/java/org/springframework/session/web/http/Base64.java index 136647ee..50f48c1a 100644 --- a/spring-session/src/main/java/org/springframework/session/web/http/Base64.java +++ b/spring-session/src/main/java/org/springframework/session/web/http/Base64.java @@ -569,6 +569,7 @@ final class Base64 { * @return decoded data * @throws IllegalArgumentException If bogus characters exist in source data */ + @SuppressWarnings("cast") private static byte[] decode(final byte[] source, final int off, final int len, final int options) { diff --git a/spring-session/src/main/java/org/springframework/session/web/http/DefaultCookieSerializer.java b/spring-session/src/main/java/org/springframework/session/web/http/DefaultCookieSerializer.java index 187e82cc..b8e50b66 100644 --- a/spring-session/src/main/java/org/springframework/session/web/http/DefaultCookieSerializer.java +++ b/spring-session/src/main/java/org/springframework/session/web/http/DefaultCookieSerializer.java @@ -51,7 +51,7 @@ public class DefaultCookieSerializer implements CookieSerializer { private String jvmRoute; - private boolean useBase64Encoding = false; + private boolean useBase64Encoding; /* * (non-Javadoc) @@ -66,7 +66,7 @@ public class DefaultCookieSerializer implements CookieSerializer { for (Cookie cookie : cookies) { if (this.cookieName.equals(cookie.getName())) { String sessionId = this.useBase64Encoding - ? decodeCookieValue(cookie.getValue()) : cookie.getValue(); + ? base64Decode(cookie.getValue()) : cookie.getValue(); if (sessionId == null) { continue; } @@ -96,7 +96,7 @@ public class DefaultCookieSerializer implements CookieSerializer { : requestedCookieValue + this.jvmRoute; Cookie sessionCookie = new Cookie(this.cookieName, this.useBase64Encoding - ? encodeCookieValue(actualCookieValue) : actualCookieValue); + ? base64Encode(actualCookieValue) : actualCookieValue); sessionCookie.setSecure(isSecureCookie(request)); sessionCookie.setPath(getCookiePath(request)); String domainName = getDomainName(request); @@ -119,14 +119,14 @@ public class DefaultCookieSerializer implements CookieSerializer { } /** - * Decode cookie value using Base64. - * @param encodedCookieValue the encoded cookie value - * @return the cookie value + * Decode the value using Base64. + * @param base64Value the Base64 String to decode + * @return the Base64 decoded value * @since 1.2.2 */ - private String decodeCookieValue(String encodedCookieValue) { + private String base64Decode(String base64Value) { try { - byte[] decodedCookieBytes = Base64.decode(encodedCookieValue.getBytes()); + byte[] decodedCookieBytes = Base64.decode(base64Value.getBytes()); return new String(decodedCookieBytes); } catch (Exception e) { @@ -135,13 +135,13 @@ public class DefaultCookieSerializer implements CookieSerializer { } /** - * Encode cookie value using Base64. - * @param cookieValue the cookie value - * @return the encoded cookie value + * Encode the value using Base64. + * @param value the String to Base64 encode + * @return the Base64 encoded value * @since 1.2.2 */ - private String encodeCookieValue(String cookieValue) { - byte[] encodedCookieBytes = Base64.encode(cookieValue.getBytes()); + private String base64Encode(String value) { + byte[] encodedCookieBytes = Base64.encode(value.getBytes()); return new String(encodedCookieBytes); } @@ -281,7 +281,9 @@ public class DefaultCookieSerializer implements CookieSerializer { } /** - * Set if the Base64 encoding of cookie value should be used. + * Set if the Base64 encoding of cookie value should be used. This is valuable in + * order to support RFC 6265 which + * recommends using Base 64 encoding to the cookie value. * * @param useBase64Encoding the flag to indicate whether to use Base64 encoding */ diff --git a/spring-session/src/test/java/org/springframework/session/web/http/DefaultCookieSerializerTests.java b/spring-session/src/test/java/org/springframework/session/web/http/DefaultCookieSerializerTests.java index 99a76b17..bce0a1c3 100644 --- a/spring-session/src/test/java/org/springframework/session/web/http/DefaultCookieSerializerTests.java +++ b/spring-session/src/test/java/org/springframework/session/web/http/DefaultCookieSerializerTests.java @@ -20,7 +20,6 @@ import javax.servlet.http.Cookie; import org.junit.Before; import org.junit.Test; - import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; @@ -28,6 +27,7 @@ import org.junit.runners.Parameterized.Parameters; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.session.web.http.CookieSerializer.CookieValue; +import org.springframework.util.StringUtils; import static org.assertj.core.api.Assertions.assertThat; @@ -40,7 +40,7 @@ import static org.assertj.core.api.Assertions.assertThat; @RunWith(Parameterized.class) public class DefaultCookieSerializerTests { - @Parameters + @Parameters(name = "useBase64Encoding={0}") public static Object[] parameters() { return new Object[] { false, true }; } @@ -86,6 +86,15 @@ public class DefaultCookieSerializerTests { .containsOnly(this.sessionId); } + @Test + public void readCookieSerializerUseBase64EncodingTrueValuesNotBase64() { + this.sessionId = "&^%$*"; + this.serializer.setUseBase64Encoding(true); + this.request.setCookies(new Cookie(this.cookieName, this.sessionId)); + + assertThat(this.serializer.readCookieValues(this.request)).isEmpty(); + } + @Test public void readCookieValuesSingleAndInvalidName() { this.request.setCookies(createCookie(this.cookieName, this.sessionId), @@ -389,7 +398,8 @@ public class DefaultCookieSerializerTests { public void readCookieJvmRoute() { String jvmRoute = "route"; this.serializer.setJvmRoute(jvmRoute); - this.request.setCookies(createCookie(this.cookieName, this.sessionId + "." + jvmRoute)); + this.request.setCookies( + createCookie(this.cookieName, this.sessionId + "." + jvmRoute)); assertThat(this.serializer.readCookieValues(this.request)) .containsOnly(this.sessionId); @@ -420,14 +430,10 @@ public class DefaultCookieSerializerTests { } private Cookie createCookie(String name, String value) { - if (!this.useBase64Encoding) { - return new Cookie(name, value); + if (this.useBase64Encoding && StringUtils.hasLength(value)) { + value = new String(Base64.encode(value.getBytes())); } - String encodedValue = null; - if (value != null) { - encodedValue = new String(Base64.encode(value.getBytes())); - } - return new Cookie(name, encodedValue); + return new Cookie(name, value); } private Cookie getCookie() {