Skip to content

Commit

Permalink
Implement changeSessionId()
Browse files Browse the repository at this point in the history
  • Loading branch information
Rob Winch committed Apr 3, 2015
1 parent 3c72828 commit 3d1cd9f
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,28 @@
*/
package org.springframework.session.web.http;

import org.springframework.core.annotation.Order;
import org.springframework.session.ExpiringSession;
import org.springframework.session.Session;
import org.springframework.session.SessionRepository;

import javax.servlet.FilterChain;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.*;

import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;

import javax.servlet.FilterChain;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionContext;

import org.springframework.core.annotation.Order;
import org.springframework.session.ExpiringSession;
import org.springframework.session.Session;
import org.springframework.session.SessionRepository;

/**
* Switches the {@link javax.servlet.http.HttpSession} implementation to be backed by a {@link org.springframework.session.Session}.
*
Expand Down Expand Up @@ -176,6 +182,37 @@ private void commitSession() {
}
}

@SuppressWarnings("unused")
public String changeSessionId() {
HttpSession session = getSession(false);

if(session == null) {
throw new IllegalStateException("Cannot change session ID. There is no session associated with this request.");
}

// eagerly get session attributes in case implementation lazily loads them
Map<String,Object> attrs = new HashMap<String,Object>();
Enumeration<String> iAttrNames = session.getAttributeNames();
while(iAttrNames.hasMoreElements()) {
String attrName = iAttrNames.nextElement();
Object value = session.getAttribute(attrName);

attrs.put(attrName, value);
}

sessionRepository.delete(session.getId());
currentSession = null;

HttpSession newSession = getSession();
newSession.setMaxInactiveInterval(session.getMaxInactiveInterval());
for(Map.Entry<String, Object> attr : attrs.entrySet()) {
String attrName = attr.getKey();
Object attrValue = attr.getValue();
newSession.setAttribute(attrName, attrValue);
}
return newSession.getId();
}

public boolean isRequestedSessionIdValid() {
if(requestedSessionIdValid == null) {
String sessionId = getRequestedSessionId();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,60 @@ public void doFilter(HttpServletRequest wrappedRequest) {
});
}

// gh-152
@Test
public void doFilterChangeSessionId() throws Exception {
final String ATTR = "ATTRIBUTE";
final String VALUE = "VALUE";

doFilter(new DoInFilter() {
@Override
public void doFilter(HttpServletRequest wrappedRequest) {
wrappedRequest.getSession().setAttribute(ATTR, VALUE);
}
});

final String originalSessionId = getSessionCookie().getValue();
nextRequest();

// change the session id
doFilter(new DoInFilter() {
@Override
public void doFilter(HttpServletRequest wrappedRequest) {
ReflectionTestUtils.invokeMethod(wrappedRequest, "changeSessionId");
}
});

// the old session was removed
final String changedSessionId = getSessionCookie().getValue();
assertThat(originalSessionId).isNotEqualTo(changedSessionId);
assertThat(sessionRepository.getSession(originalSessionId)).isNull();

nextRequest();

// The attributes from previous session were migrated
doFilter(new DoInFilter() {
@Override
public void doFilter(HttpServletRequest wrappedRequest) {
assertThat(wrappedRequest.getSession().getAttribute(ATTR)).isEqualTo(VALUE);
}
});
}

@Test
public void doFilterChangeSessionIdNoSession() throws Exception {
// change the session id
doFilter(new DoInFilter() {
@Override
public void doFilter(HttpServletRequest wrappedRequest) {
try {
ReflectionTestUtils.invokeMethod(wrappedRequest, "changeSessionId");
fail("Exected Exception");
} catch(IllegalStateException success) {}
}
});
}

// gh-142, gh-153
@Test
public void doFilterIsRequestedValidSessionFalseInvalidId() throws Exception {
Expand Down

0 comments on commit 3d1cd9f

Please sign in to comment.