From 8d867e8b672016874b9966a28726a14a421f1003 Mon Sep 17 00:00:00 2001 From: Luke Taylor Date: Sun, 19 Sep 2010 18:09:59 +0100 Subject: [PATCH] Updated integration tests to detect case reported as SPR-7563. --- .../WEB-INF/http-security-concurrency.xml | 32 ++++++++++++++ .../http-security-custom-concurrency.xml | 1 + itest/web/src/main/webapp/login.jsp | 10 ++--- .../AbstractWebServerIntegrationTests.java | 2 +- .../ConcurrentSessionManagementTests.java | 44 +++++++++++++++++++ ...ustomConcurrentSessionManagementTests.java | 20 +++++++++ .../InMemoryProviderWebAppTests.java | 22 ---------- .../logout/SecurityContextLogoutHandler.java | 9 +++- 8 files changed, 108 insertions(+), 32 deletions(-) create mode 100644 itest/web/src/main/webapp/WEB-INF/http-security-concurrency.xml create mode 100644 itest/web/src/test/java/org/springframework/security/integration/ConcurrentSessionManagementTests.java diff --git a/itest/web/src/main/webapp/WEB-INF/http-security-concurrency.xml b/itest/web/src/main/webapp/WEB-INF/http-security-concurrency.xml new file mode 100644 index 0000000000..cda8631376 --- /dev/null +++ b/itest/web/src/main/webapp/WEB-INF/http-security-concurrency.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/itest/web/src/main/webapp/WEB-INF/http-security-custom-concurrency.xml b/itest/web/src/main/webapp/WEB-INF/http-security-custom-concurrency.xml index d9e7433ddd..2177c12e09 100644 --- a/itest/web/src/main/webapp/WEB-INF/http-security-custom-concurrency.xml +++ b/itest/web/src/main/webapp/WEB-INF/http-security-custom-concurrency.xml @@ -12,6 +12,7 @@ + diff --git a/itest/web/src/main/webapp/login.jsp b/itest/web/src/main/webapp/login.jsp index e8b18e7e77..2c6891658b 100644 --- a/itest/web/src/main/webapp/login.jsp +++ b/itest/web/src/main/webapp/login.jsp @@ -1,5 +1,3 @@ - - @@ -11,13 +9,11 @@

Custom Spring Security Login

<% - if (request.getParameter("login_error") != null) { + if (request.getParameter("login_error") != null) { %> - - Your login attempt was not successful, try again.

-
+Your login attempt was not successful, try again. ${SPRING_SECURITY_LAST_EXCEPTION.message}

<% - } + } %>
diff --git a/itest/web/src/test/java/org/springframework/security/integration/AbstractWebServerIntegrationTests.java b/itest/web/src/test/java/org/springframework/security/integration/AbstractWebServerIntegrationTests.java index 011f2c269d..8b84135015 100644 --- a/itest/web/src/test/java/org/springframework/security/integration/AbstractWebServerIntegrationTests.java +++ b/itest/web/src/test/java/org/springframework/security/integration/AbstractWebServerIntegrationTests.java @@ -108,7 +108,7 @@ public abstract class AbstractWebServerIntegrationTests { return getAppContext().getBean(beanName); } - private WebApplicationContext getAppContext() { + protected final WebApplicationContext getAppContext() { ServletContext servletCtx = ((WebAppContext)server.getHandler()).getServletContext(); WebApplicationContext appCtx = WebApplicationContextUtils.getRequiredWebApplicationContext(servletCtx); diff --git a/itest/web/src/test/java/org/springframework/security/integration/ConcurrentSessionManagementTests.java b/itest/web/src/test/java/org/springframework/security/integration/ConcurrentSessionManagementTests.java new file mode 100644 index 0000000000..effb5f9ff5 --- /dev/null +++ b/itest/web/src/test/java/org/springframework/security/integration/ConcurrentSessionManagementTests.java @@ -0,0 +1,44 @@ +package org.springframework.security.integration; + +import net.sourceforge.jwebunit.junit.WebTester; +import org.testng.annotations.Test; + +/** + * @author Luke Taylor + */ +public class ConcurrentSessionManagementTests extends AbstractWebServerIntegrationTests { + + protected String getContextConfigLocations() { + return "/WEB-INF/http-security-concurrency.xml /WEB-INF/in-memory-provider.xml"; + } + + @Test + public void maxConcurrentLoginsValueIsRespected() throws Exception { + System.out.println("Client: ******* First login ******* "); + beginAt("secure/index.html"); + login("jimi", "jimispassword"); + // Login again + System.out.println("Client: ******* Second login ******* "); + WebTester tester2 = new WebTester(); + tester2.getTestContext().setBaseUrl(getBaseUrl()); + tester2.beginAt("secure/index.html"); + // seems to be a bug in checking for form here (it fails) + //tester2.assertFormPresent(); + tester2.setTextField("j_username", "jimi"); + tester2.setTextField("j_password", "jimispassword"); + // tester2.submit() also fails to detect the form + tester2.getTestingEngine().submit(); + tester2.assertTextPresent("Maximum sessions of 1 for this principal exceeded"); + + // Now logout to kill first session + tester.gotoPage("/logout"); + + + // Try second session again + tester2.setTextField("j_username", "jimi"); + tester2.setTextField("j_password", "jimispassword"); + // tester2.submit() also fails to detect the form + tester2.getTestingEngine().submit(); + tester2.assertTextPresent("A Secure Page"); + } +} diff --git a/itest/web/src/test/java/org/springframework/security/integration/CustomConcurrentSessionManagementTests.java b/itest/web/src/test/java/org/springframework/security/integration/CustomConcurrentSessionManagementTests.java index 8980f6f803..11e5140907 100644 --- a/itest/web/src/test/java/org/springframework/security/integration/CustomConcurrentSessionManagementTests.java +++ b/itest/web/src/test/java/org/springframework/security/integration/CustomConcurrentSessionManagementTests.java @@ -3,6 +3,7 @@ package org.springframework.security.integration; import net.sourceforge.jwebunit.junit.WebTester; import org.junit.Assert; +import org.springframework.security.core.session.SessionRegistry; import org.testng.annotations.Test; /** @@ -30,4 +31,23 @@ public class CustomConcurrentSessionManagementTests extends AbstractWebServerInt Assert.assertTrue(tester2.getServerResponse().contains("Maximum sessions of 1 for this principal exceeded")); } + @Test + public void logoutClearsSessionRegistryAndAllowsSecondLogin() throws Exception { + beginAt("secure/index.html"); + login("bessie", "bessiespassword"); + SessionRegistry reg = getAppContext().getBean(SessionRegistry.class); + + tester.gotoPage("/j_spring_security_logout"); + + // Login again + System.out.println("Client: ******* Second login ******* "); + WebTester tester2 = new WebTester(); + tester2.getTestContext().setBaseUrl(getBaseUrl()); + tester2.beginAt("secure/index.html"); + tester2.setTextField("j_username", "bessie"); + tester2.setTextField("j_password", "bessiespassword"); + tester2.setIgnoreFailingStatusCodes(true); + tester2.submit(); + Assert.assertTrue(tester2.getServerResponse().contains("A secure page")); + } } diff --git a/itest/web/src/test/java/org/springframework/security/integration/InMemoryProviderWebAppTests.java b/itest/web/src/test/java/org/springframework/security/integration/InMemoryProviderWebAppTests.java index 1d10f99526..d6539bde8d 100644 --- a/itest/web/src/test/java/org/springframework/security/integration/InMemoryProviderWebAppTests.java +++ b/itest/web/src/test/java/org/springframework/security/integration/InMemoryProviderWebAppTests.java @@ -72,26 +72,4 @@ public class InMemoryProviderWebAppTests extends AbstractWebServerIntegrationTes beginAt("secure/index.html"); assertTextPresent("A Secure Page"); } - - @Test - public void maxConcurrentLoginsValueIsRespected() throws Exception { - System.out.println("Client: ******* First login ******* "); - beginAt("secure/index.html"); - login("jimi", "jimispassword"); - // Login again - System.out.println("Client: ******* Second login ******* "); - WebTester tester2 = new WebTester(); - tester2.getTestContext().setBaseUrl(getBaseUrl()); - tester2.beginAt("secure/index.html"); - // seems to be a bug in checking for form here (it fails) - //tester2.assertFormPresent(); - tester2.setTextField("j_username", "jimi"); - tester2.setTextField("j_password", "jimispassword"); - // tester2.submit() also fails to detect the form - tester2.getTestingEngine().submit(); - // Try an use the original - System.out.println("Client: ******* Retry Original Session ******* "); - tester.gotoPage("secure/index.html"); - tester.assertTextPresent("This session has been expired"); - } } diff --git a/web/src/main/java/org/springframework/security/web/authentication/logout/SecurityContextLogoutHandler.java b/web/src/main/java/org/springframework/security/web/authentication/logout/SecurityContextLogoutHandler.java index 512a65fe40..a2110244f4 100644 --- a/web/src/main/java/org/springframework/security/web/authentication/logout/SecurityContextLogoutHandler.java +++ b/web/src/main/java/org/springframework/security/web/authentication/logout/SecurityContextLogoutHandler.java @@ -16,6 +16,8 @@ package org.springframework.security.web.authentication.logout; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.util.Assert; @@ -27,12 +29,14 @@ import javax.servlet.http.HttpSession; /** * Performs a logout by modifying the {@link org.springframework.security.core.context.SecurityContextHolder}. *

- * Will also invalidate the {@link HttpSession} if {@link #isInvalidateHttpSession()} is true and the - * session is not null. + * Will also invalidate the {@link HttpSession} if {@link #isInvalidateHttpSession()} is {@code true} and the + * session is not {@code null}. * * @author Ben Alex */ public class SecurityContextLogoutHandler implements LogoutHandler { + protected final Log logger = LogFactory.getLog(this.getClass()); + private boolean invalidateHttpSession = true; //~ Methods ======================================================================================================== @@ -49,6 +53,7 @@ public class SecurityContextLogoutHandler implements LogoutHandler { if (invalidateHttpSession) { HttpSession session = request.getSession(false); if (session != null) { + logger.debug("Invalidating session: " + session.getId()); session.invalidate(); } }