Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@
* attributes. An example is provided below:
* </p>
*
* <pre><code>
* {@code
* HttpSessionManager sessionManager =
* (HttpSessionManager) req.getAttribute(HttpSessionManager.class.getName());
Expand Down Expand Up @@ -145,7 +146,7 @@
* req.setAttribute("addAccountUrl", sessionManager.encodeURL(contextPath, newSessionAlias));
* req.setAttribute("accounts", accounts);
* }
*
* </code></pre>
*
* @since 1.0
* @author Rob Winch
Expand All @@ -161,6 +162,65 @@ public final class CookieHttpSessionStrategy implements MultiHttpSessionStrategy

private String sessionParam = DEFAULT_SESSION_ALIAS_PARAM_NAME;

private boolean cookieHttpOnly = true;
private Boolean cookieSecure = null;
private Integer cookieMaxAge = null;
private String cookieDomain;

private String cookiePath;

private CookiePathCalculationStrategy cookiePathCalculationStrategy = new DefaultCookiePathCalculationStrategy();

/**
* If set, sets the domain of the {@link Cookie#domain} property to the specified value
*/
public void setCookieDomain(final String cookieDomain) {
this.cookieDomain = cookieDomain;
}

/**
* Override to set the {@link Cookie#isHttpOnly} flag, default value is true
*/
public void setCookieHttpOnly(final boolean cookieHttpOnly) {
this.cookieHttpOnly = cookieHttpOnly;
}

/**
* If set, sets the {@link Cookie#maxAge} property to a fixed value.
*/
public void setCookieMaxAge(final Integer cookieMaxAge) {
this.cookieMaxAge = cookieMaxAge;
}

/**
* If set, overrides the {@link Cookie#path} to a fixed value. (see detailed description!)
*
* By default, the {@link Cookie#path} gets calculated by the default {@link CookiePathCalculationStrategy}
* (which is {@link org.springframework.session.web.http.CookieHttpSessionStrategy.DefaultCookiePathCalculationStrategy})
* You can override the default by using {@link #setCookiePathCalculationStrategy(CookiePathCalculationStrategy)}
* Do <u>NOT</u> use this method if you want to override the default {@link CookiePathCalculationStrategy}, as this
* method overrides the Strategy.
*/
public void setCookiePath(final String cookiePath) {
this.cookiePath = cookiePath;
}

/**
* Allows to override how the {@link Cookie#path} is calculated. (see detailed description!)
* The default is to use {@link org.springframework.session.web.http.CookieHttpSessionStrategy.DefaultCookiePathCalculationStrategy}
* If you override the strategy, be sure to <u>NOT</u> use {@link #setCookiePath(String)}
*/
public void setCookiePathCalculationStrategy(final CookiePathCalculationStrategy cookiePathCalculationStrategy) {
this.cookiePathCalculationStrategy = cookiePathCalculationStrategy;
}

/**
* If set, sets the {@link Cookie#secure} flag of the {@link Cookie}
*/
public void setCookieSecure(final Boolean cookieSecure) {
this.cookieSecure = cookieSecure;
}

public String getRequestedSessionId(HttpServletRequest request) {
Map<String,String> sessionIds = getSessionIds(request);
String sessionAlias = getCurrentSessionAlias(request);
Expand Down Expand Up @@ -212,13 +272,28 @@ public void onNewSession(Session session, HttpServletRequest request, HttpServle
response.addCookie(sessionCookie);
}

private Cookie createSessionCookie(HttpServletRequest request,
/*
Package scoped for testing
*/
Cookie createSessionCookie(HttpServletRequest request,
Map<String, String> sessionIds) {
Cookie sessionCookie = new Cookie(cookieName,"");
sessionCookie.setHttpOnly(true);
sessionCookie.setSecure(request.isSecure());
sessionCookie.setPath(cookiePath(request));
// TODO set domain?

sessionCookie.setHttpOnly(cookieHttpOnly);
sessionCookie.setSecure(cookieSecure == null ? request.isSecure() : cookieSecure);
if(cookieMaxAge != null){
sessionCookie.setMaxAge(cookieMaxAge);
}

if (cookiePath != null) {
sessionCookie.setPath(cookiePath);
} else {
sessionCookie.setPath(cookiePathCalculationStrategy.calculateCookiePath(request));
}

if(cookieDomain != null){
sessionCookie.setDomain(cookieDomain);
}

if(sessionIds.isEmpty()) {
sessionCookie.setMaxAge(0);
Expand Down Expand Up @@ -302,10 +377,6 @@ private static Cookie getCookie(HttpServletRequest request, String name) {
return null;
}

private static String cookiePath(HttpServletRequest request) {
return request.getContextPath() + "/";
}

public Map<String,String> getSessionIds(HttpServletRequest request) {
Cookie session = getCookie(request, cookieName);
String sessionCookieValue = session == null ? "" : session.getValue();
Expand Down Expand Up @@ -387,4 +458,12 @@ private String urlEncode(String value) {
throw new RuntimeException(e);
}
}

public class DefaultCookiePathCalculationStrategy implements CookiePathCalculationStrategy {

@Override
public String calculateCookiePath(final HttpServletRequest request) {
return request.getContextPath() + "/";
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.springframework.session.web.http;

import javax.servlet.http.HttpServletRequest;

/**
* Interface which needs to be implemented to override the way
* the Cookie Path in {@link CookieHttpSessionStrategy} is calculated
*/
public interface CookiePathCalculationStrategy {

/**
* Implement this method to override the path that should be set
* for the Session-Cookie.
*
* <p>Make sure that the path always ends with a &quot;/&quot;</p>
* @param request the {@link HttpServletRequest} which is used to calculate the path
* @return a non-empty String ending with a &quot;/&quot;
*/
String calculateCookiePath(HttpServletRequest request);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import org.springframework.session.Session;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

public class CookieHttpSessionStrategyTests {
Expand Down Expand Up @@ -382,6 +384,74 @@ public void createSessionCookieValue() {
assertThat(createSessionCookieValue(17)).isEqualToIgnoringCase("0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 a 10 b 11 c 12 d 13 e 14 f 15 10 16");
}

@Test
public void testCreateSessionCookieWithCustomDomain() throws Exception {
strategy.setCookieDomain("test.com");
Cookie c = strategy.createSessionCookie(request, getSampleSessionIds());
assertThat(c.getDomain()).isEqualTo("test.com");
}

@Test
public void testCreateSessionCookieWithCustomMaxAge() throws Exception {
strategy.setCookieMaxAge(5000);
Cookie c = strategy.createSessionCookie(request, getSampleSessionIds());
assertThat(c.getMaxAge()).isEqualTo(5000);
}

@Test
public void testCreateSessionCookieWithSecureFlagTrue() throws Exception {
strategy.setCookieSecure(true);
Cookie c = strategy.createSessionCookie(request, getSampleSessionIds());
assertThat(c.getSecure()).isEqualTo(true);
}

@Test
public void testCreateSessionCookieWithSecureFlagFromRequest() throws Exception {
request.setSecure(true);
Cookie c = strategy.createSessionCookie(request, getSampleSessionIds());
assertThat(c.getSecure()).isEqualTo(true);
}

@Test
public void testCreateSessionCookieWithHttpOnlyTrue() throws Exception {
strategy.setCookieHttpOnly(true);
Cookie c = strategy.createSessionCookie(request, getSampleSessionIds());
assertThat(c.isHttpOnly()).isEqualTo(true);
}

@Test
public void testCreateSessionCookieWithHttpOnlyFalse() throws Exception {
strategy.setCookieHttpOnly(false);
Cookie c = strategy.createSessionCookie(request, getSampleSessionIds());
assertThat(c.isHttpOnly()).isEqualTo(false);
}

@Test
public void testCreateSessionCookieWithDefaultPath() throws Exception {
request.setContextPath("/abc");
Cookie c = strategy.createSessionCookie(request, getSampleSessionIds());
assertThat(c.getPath()).isEqualTo("/abc/");
}

@Test
public void testCreateSessionCookieOverridePath() throws Exception {
strategy.setCookiePath("/bcd/");
Cookie c = strategy.createSessionCookie(request, getSampleSessionIds());
assertThat(c.getPath()).isEqualTo("/bcd/");
}

@Test
public void testCreateSessionCookieOverridePathWithStrategy() throws Exception {
strategy.setCookiePathCalculationStrategy(new CookiePathCalculationStrategy() {
@Override
public String calculateCookiePath(final HttpServletRequest request) {
return "/ccc/";
}
});
Cookie c = strategy.createSessionCookie(request, getSampleSessionIds());
assertThat(c.getPath()).isEqualTo("/ccc/");
}

private void setCookieWithNSessions(long size) {
setSessionCookie(createSessionCookieValue(size));
}
Expand Down Expand Up @@ -414,4 +484,11 @@ public void setSessionCookie(String value) {
public String getSessionId() {
return response.getCookie(cookieName).getValue();
}

public Map<String,String> getSampleSessionIds(){
Map<String,String> sessionIds = new HashMap<String, String>();
sessionIds.put("0", "aaa");
sessionIds.put("1", "bbb");
return sessionIds;
}
}