diff --git a/core/src/main/java/org/acegisecurity/ui/AbstractProcessingFilter.java b/core/src/main/java/org/acegisecurity/ui/AbstractProcessingFilter.java
index 4403a8b052..5cd6faac65 100644
--- a/core/src/main/java/org/acegisecurity/ui/AbstractProcessingFilter.java
+++ b/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 false.
*/
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 HttpSession
+ * 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;
+ }
}
diff --git a/core/src/test/java/org/acegisecurity/ui/AbstractProcessingFilterTests.java b/core/src/test/java/org/acegisecurity/ui/AbstractProcessingFilterTests.java
index 1001d20548..93c69d5e22 100644
--- a/core/src/test/java/org/acegisecurity/ui/AbstractProcessingFilterTests.java
+++ b/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());
}
/**