Jelajahi Sumber

SEC-398: Delay sending of redirect until after HttpSession updated with revised SecurityContextHolder contents.

Ben Alex 18 tahun lalu
induk
melakukan
4f13db5552

+ 13 - 0
core/src/main/java/org/acegisecurity/ui/AbstractProcessingFilter.java

@@ -146,6 +146,13 @@ public abstract class AbstractProcessingFilter implements Filter, InitializingBe
      * certain environment (eg Tapestry). Defaults to <code>false</code>.
      */
     private boolean continueChainBeforeSuccessfulAuthentication = false;
+    
+    /**
+     * Specifies the buffer size to use in the event of a directory. A buffer size is used to ensure the
+     * response is not written back to the client immediately. This provides a way for the <code>HttpSession</code>
+     * to be updated before the browser redirect will be sent. Defaults to an 8 Kb buffer.
+     */
+    private int bufferSize = 8 * 1024;
 
     //~ Methods ========================================================================================================
 
@@ -323,6 +330,8 @@ public abstract class AbstractProcessingFilter implements Filter, InitializingBe
             url = request.getContextPath() + url;
         }
 
+        Assert.isTrue(!response.isCommitted(), "Response already committed; the authentication mechanism must be able to modify buffer size");
+        response.setBufferSize(bufferSize);
         response.sendRedirect(response.encodeRedirectURL(url));
     }
 
@@ -437,4 +446,8 @@ public abstract class AbstractProcessingFilter implements Filter, InitializingBe
         // Required due to SEC-310
         return authenticationDetailsSource;
     }
+
+	public void setBufferSize(int bufferSize) {
+		this.bufferSize = bufferSize;
+	}
 }

+ 5 - 0
core/src/test/java/org/acegisecurity/ui/AbstractProcessingFilterTests.java

@@ -177,6 +177,7 @@ public class AbstractProcessingFilterTests extends TestCase {
 
         assertEquals("/mycontext/accountExpired.jsp", response.getRedirectedUrl());
         assertNull(SecurityContextHolder.getContext().getAuthentication());
+        assertEquals(8*1024, response.getBufferSize());
     }
 
     public void testFilterProcessesUrlVariationsRespected()
@@ -203,6 +204,7 @@ public class AbstractProcessingFilterTests extends TestCase {
         assertEquals("/mycontext/logged_in.jsp", response.getRedirectedUrl());
         assertNotNull(SecurityContextHolder.getContext().getAuthentication());
         assertEquals("test", SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString());
+        assertEquals(8*1024, response.getBufferSize());
     }
 
     public void testGettersSetters() {
@@ -286,6 +288,7 @@ public class AbstractProcessingFilterTests extends TestCase {
         assertEquals("/mycontext/logged_in.jsp", response.getRedirectedUrl());
         assertNotNull(SecurityContextHolder.getContext().getAuthentication());
         assertEquals("test", SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString());
+        assertEquals(8*1024, response.getBufferSize());
     }
 
     public void testStartupDetectsInvalidAuthenticationFailureUrl()
@@ -371,6 +374,7 @@ public class AbstractProcessingFilterTests extends TestCase {
         assertEquals("/mycontext/logged_in.jsp", response.getRedirectedUrl());
         assertNotNull(SecurityContextHolder.getContext().getAuthentication());
         assertEquals("test", SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString());
+        assertEquals(8*1024, response.getBufferSize());
 
         // Now try again but this time have filter deny access
         // Setup our HTTP request
@@ -436,6 +440,7 @@ public class AbstractProcessingFilterTests extends TestCase {
         executeFilterInContainerSimulator(config, filter, request, response, chain);
         assertEquals(makeSavedRequestForUrl().getFullRequestUrl(), response.getRedirectedUrl());
         assertNotNull(SecurityContextHolder.getContext().getAuthentication());
+        assertEquals(8*1024, response.getBufferSize());
     }
 
     /**