From 90d76373cc8288d939ce4a5ef8289af860798ef9 Mon Sep 17 00:00:00 2001 From: Luke Taylor Date: Fri, 7 Aug 2009 17:12:12 +0000 Subject: [PATCH] SEC-1142: Support for session timeout detection. Added redirect to invalidSessionUrl in SessionManagementFilter when an invalid session Id is supplied in the request. --- .../web/session/SessionManagementFilter.java | 17 ++++++++++++ .../session/SessionManagementFilterTests.java | 27 +++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/web/src/main/java/org/springframework/security/web/session/SessionManagementFilter.java b/web/src/main/java/org/springframework/security/web/session/SessionManagementFilter.java index 8025336a23..42a713707e 100644 --- a/web/src/main/java/org/springframework/security/web/session/SessionManagementFilter.java +++ b/web/src/main/java/org/springframework/security/web/session/SessionManagementFilter.java @@ -40,6 +40,8 @@ public class SessionManagementFilter extends SpringSecurityFilter { private AuthenticationTrustResolver authenticationTrustResolver = new AuthenticationTrustResolverImpl(); + private String invalidSessionUrl; + public SessionManagementFilter(SecurityContextRepository securityContextRepository) { this.securityContextRepository = securityContextRepository; } @@ -60,12 +62,23 @@ public class SessionManagementFilter extends SpringSecurityFilter { if (authentication != null && !authenticationTrustResolver.isAnonymous(authentication)) { // The user has been authenticated during the current request, so call the session strategy sessionStrategy.onAuthenticationSuccess(authentication, request, response); + } else { + // No security context or authentication present. Check for a session timeout + if (request.getRequestedSessionId() != null && !request.isRequestedSessionIdValid()) { + invalidSessionRequested(request, response); + } } } chain.doFilter(request, response); } + protected void invalidSessionRequested(HttpServletRequest request, HttpServletResponse response) throws IOException { + if (invalidSessionUrl != null) { + response.sendRedirect(invalidSessionUrl); + } + } + /** * Sets the strategy object which handles the session management behaviour when a * user has been authenticated during the current request. @@ -76,4 +89,8 @@ public class SessionManagementFilter extends SpringSecurityFilter { Assert.notNull(sessionStrategy, "authenticatedSessionStratedy must not be null"); this.sessionStrategy = sessionStrategy; } + + public void setInvalidSessionUrl(String sessionTimeoutUrl) { + this.invalidSessionUrl = sessionTimeoutUrl; + } } diff --git a/web/src/test/java/org/springframework/security/web/session/SessionManagementFilterTests.java b/web/src/test/java/org/springframework/security/web/session/SessionManagementFilterTests.java index c0e4bc8be6..5ecaaef5d1 100644 --- a/web/src/test/java/org/springframework/security/web/session/SessionManagementFilterTests.java +++ b/web/src/test/java/org/springframework/security/web/session/SessionManagementFilterTests.java @@ -83,6 +83,33 @@ public class SessionManagementFilterTests { filter.doFilter(request, new MockHttpServletResponse(), new MockFilterChain()); verify(strategy).onAuthenticationSuccess(any(Authentication.class), any(HttpServletRequest.class), any(HttpServletResponse.class)); + // Check that it is only applied once to the request + filter.doFilter(request, new MockHttpServletResponse(), new MockFilterChain()); + verifyNoMoreInteractions(strategy); + } + + @Test + public void responseIsRedirectedToTimeoutUrlIfSetAndSessionIsInvalid() throws Exception { + SecurityContextRepository repo = mock(SecurityContextRepository.class); + // repo will return false to containsContext() + AuthenticatedSessionStrategy strategy = mock(AuthenticatedSessionStrategy.class); + SessionManagementFilter filter = new SessionManagementFilter(repo); + filter.setAuthenticatedSessionStrategy(strategy); + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setRequestedSessionId("xxx"); + request.setRequestedSessionIdValid(false); + MockHttpServletResponse response = new MockHttpServletResponse(); + + filter.doFilter(request, response, new MockFilterChain()); + assertNull(response.getRedirectedUrl()); + + // Now set a redirect URL + request = new MockHttpServletRequest(); + request.setRequestedSessionId("xxx"); + request.setRequestedSessionIdValid(false); + filter.setInvalidSessionUrl("/timedOut"); + filter.doFilter(request, response, new MockFilterChain()); + assertEquals("/timedOut", response.getRedirectedUrl()); } private void authenticateUser() {