SEC-1346: Added missing 'return' statements after redirects.
ConcurrentSessionFilter and SessionManagementFilter now return immediately after redirecting to the expired URL and invalid session URLs respectively. Extra tests added to check.
This commit is contained in:
@@ -15,79 +15,70 @@
|
||||
|
||||
package org.springframework.security.web.concurrent;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.springframework.mock.web.MockFilterConfig;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.mock.web.MockHttpSession;
|
||||
import org.springframework.security.core.session.SessionRegistry;
|
||||
import org.springframework.security.core.session.SessionRegistryImpl;
|
||||
import org.springframework.security.web.DefaultRedirectStrategy;
|
||||
import org.springframework.security.web.authentication.logout.LogoutHandler;
|
||||
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
|
||||
import org.springframework.security.web.session.ConcurrentSessionFilter;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link ConcurrentSessionFilter}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
* @author Luke Taylor
|
||||
*/
|
||||
public class ConcurrentSessionFilterTests extends TestCase {
|
||||
public class ConcurrentSessionFilterTests {
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
private void executeFilterInContainerSimulator(FilterConfig filterConfig, Filter filter, ServletRequest request,
|
||||
ServletResponse response, FilterChain filterChain)
|
||||
throws ServletException, IOException {
|
||||
filter.init(filterConfig);
|
||||
filter.doFilter(request, response, filterChain);
|
||||
filter.destroy();
|
||||
}
|
||||
|
||||
public void testDetectsExpiredSessions() throws Exception {
|
||||
@Test
|
||||
public void detectsExpiredSessions() throws Exception {
|
||||
// Setup our HTTP request
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
MockHttpSession session = new MockHttpSession();
|
||||
request.setSession(session);
|
||||
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
MockFilterConfig config = new MockFilterConfig(null, null);
|
||||
|
||||
// Setup our expectation that the filter chain will not be invoked, as we redirect to expiredUrl
|
||||
MockFilterChain chain = new MockFilterChain(false);
|
||||
|
||||
// Setup our test fixture and registry to want this session to be expired
|
||||
ConcurrentSessionFilter filter = new ConcurrentSessionFilter();
|
||||
filter.setRedirectStrategy(new DefaultRedirectStrategy());
|
||||
filter.setLogoutHandlers(new LogoutHandler[] {new SecurityContextLogoutHandler()});
|
||||
|
||||
SessionRegistry registry = new SessionRegistryImpl();
|
||||
registry.registerNewSession(session.getId(), "principal");
|
||||
registry.getSessionInformation(session.getId()).expireNow();
|
||||
filter.setSessionRegistry(registry);
|
||||
filter.setExpiredUrl("/expired.jsp");
|
||||
filter.afterPropertiesSet();
|
||||
|
||||
// Test
|
||||
executeFilterInContainerSimulator(config, filter, request, response, chain);
|
||||
FilterChain fc = mock(FilterChain.class);
|
||||
filter.doFilter(request, response, fc);
|
||||
// Expect that the filter chain will not be invoked, as we redirect to expiredUrl
|
||||
verifyZeroInteractions(fc);
|
||||
|
||||
assertEquals("/expired.jsp", response.getRedirectedUrl());
|
||||
}
|
||||
|
||||
// As above, but with no expiredUrl set.
|
||||
public void testReturnsExpectedMessageWhenNoExpiredUrlSet() throws Exception {
|
||||
@Test
|
||||
public void returnsExpectedMessageWhenNoExpiredUrlSet() throws Exception {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
MockHttpSession session = new MockHttpSession();
|
||||
request.setSession(session);
|
||||
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
MockFilterConfig config = new MockFilterConfig(null, null);
|
||||
|
||||
MockFilterChain chain = new MockFilterChain(false);
|
||||
|
||||
ConcurrentSessionFilter filter = new ConcurrentSessionFilter();
|
||||
SessionRegistry registry = new SessionRegistryImpl();
|
||||
@@ -95,35 +86,36 @@ public class ConcurrentSessionFilterTests extends TestCase {
|
||||
registry.getSessionInformation(session.getId()).expireNow();
|
||||
filter.setSessionRegistry(registry);
|
||||
|
||||
executeFilterInContainerSimulator(config, filter, request, response, chain);
|
||||
FilterChain fc = mock(FilterChain.class);
|
||||
filter.doFilter(request, response, fc);
|
||||
verifyZeroInteractions(fc);
|
||||
|
||||
assertEquals("This session has been expired (possibly due to multiple concurrent logins being " +
|
||||
"attempted as the same user).", response.getContentAsString());
|
||||
}
|
||||
|
||||
public void testDetectsMissingSessionRegistry() throws Exception {
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void detectsMissingSessionRegistry() throws Exception {
|
||||
ConcurrentSessionFilter filter = new ConcurrentSessionFilter();
|
||||
filter.setExpiredUrl("xcx");
|
||||
|
||||
try {
|
||||
filter.afterPropertiesSet();
|
||||
fail("Should have thrown IAE");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
filter.afterPropertiesSet();
|
||||
}
|
||||
|
||||
public void testUpdatesLastRequestTime() throws Exception {
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void detectsInvalidUrl() throws Exception {
|
||||
ConcurrentSessionFilter filter = new ConcurrentSessionFilter();
|
||||
filter.setExpiredUrl("ImNotValid");
|
||||
filter.afterPropertiesSet();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lastRequestTimeUpdatesCorrectly() throws Exception {
|
||||
// Setup our HTTP request
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
MockHttpSession session = new MockHttpSession();
|
||||
request.setSession(session);
|
||||
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
MockFilterConfig config = new MockFilterConfig(null, null);
|
||||
|
||||
// Setup our expectation that the filter chain will be invoked, as our session hasn't expired
|
||||
MockFilterChain chain = new MockFilterChain(true);
|
||||
FilterChain fc = mock(FilterChain.class);
|
||||
|
||||
// Setup our test fixture
|
||||
ConcurrentSessionFilter filter = new ConcurrentSessionFilter();
|
||||
@@ -136,28 +128,9 @@ public class ConcurrentSessionFilterTests extends TestCase {
|
||||
|
||||
Thread.sleep(1000);
|
||||
|
||||
// Test
|
||||
executeFilterInContainerSimulator(config, filter, request, response, chain);
|
||||
filter.doFilter(request, response, fc);
|
||||
|
||||
verify(fc).doFilter(request, response);
|
||||
assertTrue(registry.getSessionInformation(session.getId()).getLastRequest().after(lastRequest));
|
||||
}
|
||||
|
||||
//~ Inner Classes ==================================================================================================
|
||||
|
||||
private class MockFilterChain implements FilterChain {
|
||||
private boolean expectToProceed;
|
||||
|
||||
public MockFilterChain(boolean expectToProceed) {
|
||||
this.expectToProceed = expectToProceed;
|
||||
}
|
||||
|
||||
public void doFilter(ServletRequest request, ServletResponse response)
|
||||
throws IOException, ServletException {
|
||||
if (expectToProceed) {
|
||||
assertTrue(true);
|
||||
} else {
|
||||
fail("Did not expect filter chain to proceed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import static org.junit.Assert.*;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
@@ -15,13 +16,14 @@ import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.web.DefaultRedirectStrategy;
|
||||
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
|
||||
import org.springframework.security.web.authentication.session.SessionAuthenticationException;
|
||||
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
|
||||
import org.springframework.security.web.context.SecurityContextRepository;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Luke Taylor
|
||||
* @version $Id$
|
||||
*/
|
||||
public class SessionManagementFilterTests {
|
||||
|
||||
@@ -89,6 +91,29 @@ public class SessionManagementFilterTests {
|
||||
verifyNoMoreInteractions(strategy);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void strategyFailureInvokesFailureHandler() throws Exception {
|
||||
SecurityContextRepository repo = mock(SecurityContextRepository.class);
|
||||
// repo will return false to containsContext()
|
||||
SessionAuthenticationStrategy strategy = mock(SessionAuthenticationStrategy.class);
|
||||
|
||||
AuthenticationFailureHandler failureHandler = mock(AuthenticationFailureHandler.class);
|
||||
SessionManagementFilter filter = new SessionManagementFilter(repo);
|
||||
filter.setAuthenticationFailureHandler(failureHandler);
|
||||
filter.setSessionAuthenticationStrategy(strategy);
|
||||
HttpServletRequest request = new MockHttpServletRequest();
|
||||
HttpServletResponse response = new MockHttpServletResponse();
|
||||
FilterChain fc = mock(FilterChain.class);
|
||||
authenticateUser();
|
||||
SessionAuthenticationException exception = new SessionAuthenticationException("Failure");
|
||||
doThrow(exception).when(strategy).onAuthentication(
|
||||
SecurityContextHolder.getContext().getAuthentication(), request, response);
|
||||
|
||||
filter.doFilter(request,response, fc);
|
||||
verifyZeroInteractions(fc);
|
||||
verify(failureHandler).onAuthenticationFailure(request, response, exception);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void responseIsRedirectedToTimeoutUrlIfSetAndSessionIsInvalid() throws Exception {
|
||||
SecurityContextRepository repo = mock(SecurityContextRepository.class);
|
||||
@@ -96,6 +121,7 @@ public class SessionManagementFilterTests {
|
||||
SessionAuthenticationStrategy strategy = mock(SessionAuthenticationStrategy.class);
|
||||
SessionManagementFilter filter = new SessionManagementFilter(repo);
|
||||
filter.setSessionAuthenticationStrategy(strategy);
|
||||
filter.setRedirectStrategy(new DefaultRedirectStrategy());
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setRequestedSessionId("xxx");
|
||||
request.setRequestedSessionIdValid(false);
|
||||
@@ -109,7 +135,10 @@ public class SessionManagementFilterTests {
|
||||
request.setRequestedSessionId("xxx");
|
||||
request.setRequestedSessionIdValid(false);
|
||||
filter.setInvalidSessionUrl("/timedOut");
|
||||
filter.doFilter(request, response, new MockFilterChain());
|
||||
FilterChain fc = mock(FilterChain.class);
|
||||
filter.doFilter(request, response, fc);
|
||||
verifyZeroInteractions(fc);
|
||||
|
||||
assertEquals("/timedOut", response.getRedirectedUrl());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user