Ver Fonte

SEC-572: Added allowSessionCreation (default=true) property to AbstractProcessingFilter and modified it and AuthenticationProcessingFilter to stop them creating a new session for storing data if this property is set to false.

Luke Taylor há 17 anos atrás
pai
commit
2eca8ee7b0

+ 24 - 4
core/src/main/java/org/springframework/security/ui/AbstractProcessingFilter.java

@@ -207,6 +207,8 @@ public abstract class AbstractProcessingFilter extends SpringSecurityFilter impl
      */
     private boolean migrateInvalidatedSessionAttributes = true;
 
+    private boolean allowSessionCreation = true;
+
     //~ Methods ========================================================================================================
 
 	public void afterPropertiesSet() throws Exception {
@@ -264,9 +266,15 @@ public abstract class AbstractProcessingFilter extends SpringSecurityFilter impl
 	}
 
 	public static String obtainFullRequestUrl(HttpServletRequest request) {
-		SavedRequest savedRequest = (SavedRequest) request.getSession().getAttribute(SPRING_SECURITY_SAVED_REQUEST_KEY);
+        HttpSession session = request.getSession(false);
 
-		return (savedRequest == null) ? null : savedRequest.getFullRequestUrl();
+        if (session == null) {
+            return null;
+        }
+
+        SavedRequest savedRequest = (SavedRequest) session.getAttribute(SPRING_SECURITY_SAVED_REQUEST_KEY);
+
+        return savedRequest == null ? null : savedRequest.getFullRequestUrl();
 	}
 
 	protected void onPreAuthentication(HttpServletRequest request, HttpServletResponse response)
@@ -434,8 +442,12 @@ public abstract class AbstractProcessingFilter extends SpringSecurityFilter impl
 		}
 
 		try {
-			request.getSession().setAttribute(SPRING_SECURITY_LAST_EXCEPTION_KEY, failed);
-		}
+            HttpSession session = request.getSession(false);
+
+            if (session != null || allowSessionCreation) {            
+                request.getSession().setAttribute(SPRING_SECURITY_LAST_EXCEPTION_KEY, failed);
+            }
+        }
 		catch (Exception ignored) {
 		}
 
@@ -558,4 +570,12 @@ public abstract class AbstractProcessingFilter extends SpringSecurityFilter impl
 	public void setUseRelativeContext(boolean useRelativeContext) {
 		this.useRelativeContext = useRelativeContext;
 	}
+
+    protected boolean getAllowSessionCreation() {
+        return allowSessionCreation;
+    }
+
+    public void setAllowSessionCreation(boolean allowSessionCreation) {
+        this.allowSessionCreation = allowSessionCreation;
+    }
 }

+ 6 - 1
core/src/main/java/org/springframework/security/ui/webapp/AuthenticationProcessingFilter.java

@@ -25,6 +25,7 @@ import org.springframework.security.ui.FilterChainOrderUtils;
 import org.springframework.util.Assert;
 
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
 
 
 /**
@@ -72,7 +73,11 @@ public class AuthenticationProcessingFilter extends AbstractProcessingFilter {
         UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
 
         // Place the last username attempted into HttpSession for views
-        request.getSession().setAttribute(SPRING_SECURITY_LAST_USERNAME_KEY, username);
+        HttpSession session = request.getSession(false);
+
+        if (session != null || getAllowSessionCreation()) {
+            request.getSession().setAttribute(SPRING_SECURITY_LAST_USERNAME_KEY, username);
+        }
 
         // Allow subclasses to set the "details" property
         setDetails(request, authRequest);

+ 21 - 2
core/src/test/java/org/springframework/security/ui/AbstractProcessingFilterTests.java

@@ -471,11 +471,9 @@ public class AbstractProcessingFilterTests extends TestCase {
         MockHttpServletRequest request = createMockRequest();
         HttpSession oldSession = request.getSession();
         MockFilterConfig config = new MockFilterConfig(null, null);
-
         MockFilterChain chain = new MockFilterChain(true);
         MockHttpServletResponse response = new MockHttpServletResponse();
 
-        // Setup our test object, to grant access
         MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(true);
         filter.setInvalidateSessionOnSuccessfulAuthentication(true);
         filter.setMigrateInvalidatedSessionAttributes(false);
@@ -488,6 +486,27 @@ public class AbstractProcessingFilterTests extends TestCase {
         assertNull(newSession.getAttribute("test"));
     }
 
+    /**
+     * SEC-571
+     */
+    public void testNoSessionIsCreatedIfAllowSessionCreationIsFalse() throws Exception {
+        MockHttpServletRequest request = createMockRequest();
+
+        MockFilterConfig config = new MockFilterConfig(null, null);
+        MockFilterChain chain = new MockFilterChain(true);
+        MockHttpServletResponse response = new MockHttpServletResponse();
+
+        // Reject authentication, so exception would normally be stored in session
+        MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(false);
+        filter.setAllowSessionCreation(false);
+        filter.setAuthenticationFailureUrl("/");
+        filter.setDefaultTargetUrl("http://monkeymachine.co.uk/");
+
+        executeFilterInContainerSimulator(config, filter, request, response, chain);
+
+        assertNull(request.getSession(false));
+    }
+
     //~ Inner Classes ==================================================================================================
 
     private class MockAbstractProcessingFilter extends AbstractProcessingFilter {

+ 37 - 4
core/src/test/java/org/springframework/security/ui/webapp/AuthenticationProcessingFilterTests.java

@@ -19,10 +19,13 @@ import junit.framework.TestCase;
 
 import org.springframework.security.Authentication;
 import org.springframework.security.MockAuthenticationManager;
+import org.springframework.security.AuthenticationException;
 
 import org.springframework.security.ui.WebAuthenticationDetails;
 
 import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockFilterConfig;
+import org.springframework.mock.web.MockHttpServletResponse;
 
 import javax.servlet.ServletException;
 
@@ -61,6 +64,8 @@ public class AuthenticationProcessingFilterTests extends TestCase {
 
         Authentication result = filter.attemptAuthentication(request);
         assertTrue(result != null);
+        assertEquals("rod", request.getSession().getAttribute(
+                AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY));
         assertEquals("127.0.0.1", ((WebAuthenticationDetails) result.getDetails()).getRemoteAddress());
     }
 
@@ -70,7 +75,6 @@ public class AuthenticationProcessingFilterTests extends TestCase {
 
         AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
         filter.setAuthenticationManager(new MockAuthenticationManager(true));
-        filter.init(null);
 
         Authentication result = filter.attemptAuthentication(request);
         assertTrue(result != null);
@@ -82,7 +86,6 @@ public class AuthenticationProcessingFilterTests extends TestCase {
 
         AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
         filter.setAuthenticationManager(new MockAuthenticationManager(true));
-        filter.init(null);
 
         Authentication result = filter.attemptAuthentication(request);
         assertTrue(result != null);
@@ -93,7 +96,6 @@ public class AuthenticationProcessingFilterTests extends TestCase {
         filter.setAuthenticationManager(new MockAuthenticationManager(true));
         filter.setUsernameParameter("x");
         filter.setPasswordParameter("y");
-        filter.init(null);
 
         MockHttpServletRequest request = new MockHttpServletRequest();
         request.addParameter("x", "rod");
@@ -111,9 +113,40 @@ public class AuthenticationProcessingFilterTests extends TestCase {
 
         AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
         filter.setAuthenticationManager(new MockAuthenticationManager(true));
-        filter.init(null);
 
         Authentication result = filter.attemptAuthentication(request);
         assertEquals("rod", result.getName());
     }
+
+    public void testFailedAuthenticationThrowsException() {
+        MockHttpServletRequest request = new MockHttpServletRequest();
+        request.addParameter(AuthenticationProcessingFilter.SPRING_SECURITY_FORM_USERNAME_KEY, "rod");
+        AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
+        filter.setAuthenticationManager(new MockAuthenticationManager(false));
+
+        try {
+            filter.attemptAuthentication(request);
+            fail("Expected AuthenticationException");
+        } catch (AuthenticationException e) {
+        }
+
+        // Check username has still been set
+        assertEquals("rod", request.getSession().getAttribute(
+                AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY));
+    }
+
+    /**
+     * SEC-571
+     */
+    public void testNoSessionIsCreatedIfAllowSessionCreationIsFalse() throws Exception {
+        MockHttpServletRequest request = new MockHttpServletRequest();
+
+        AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
+        filter.setAllowSessionCreation(false);
+        filter.setAuthenticationManager(new MockAuthenticationManager(true));
+
+        filter.attemptAuthentication(request);
+
+        assertNull(request.getSession(false));
+    }
 }