Implement changeSessionId()

Fixes gh-152
This commit is contained in:
Rob Winch
2015-04-03 17:07:21 -05:00
parent 3c72828500
commit 3d1cd9fae4
2 changed files with 101 additions and 10 deletions

View File

@@ -15,21 +15,27 @@
*/
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 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.*;
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 java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.NoSuchElementException;
import java.util.Set;
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}.
@@ -176,6 +182,37 @@ public class SessionRepositoryFilter<S extends ExpiringSession> extends OncePerR
}
}
@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();

View File

@@ -432,6 +432,60 @@ public class SessionRepositoryFilterTests<S extends ExpiringSession> {
});
}
// 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 {