diff --git a/changelog.txt b/changelog.txt index 3666e1a10f..d29357e0d6 100644 --- a/changelog.txt +++ b/changelog.txt @@ -6,6 +6,7 @@ Changes in version 0.7 (2004-xx-xx) * Added MethodDefinitionSourceAdvisor for performance and autoproxying * Added MethodDefinitionMap querying of interfaces defined by secure objects * Added AuthenticationProcessingFilter.setDetails for use by subclasses +* Added 403-causing exception to HttpSession via SecurityEnforcementFilter * Refactored MethodDefinitionSource to work with Method, not MethodInvocation * Refactored AbstractSecurityInterceptor to better support other AOP libraries * Fixed AbstractProcessingFitler to use removeAttribute (JRun compatibility) diff --git a/core/src/main/java/org/acegisecurity/intercept/web/SecurityEnforcementFilter.java b/core/src/main/java/org/acegisecurity/intercept/web/SecurityEnforcementFilter.java index 7254b9efb5..4bcf31b837 100644 --- a/core/src/main/java/org/acegisecurity/intercept/web/SecurityEnforcementFilter.java +++ b/core/src/main/java/org/acegisecurity/intercept/web/SecurityEnforcementFilter.java @@ -54,10 +54,13 @@ import javax.servlet.http.HttpServletResponse; *
* *
- * If an {@link AccessDeniedException} is detected, the filter will response
- * with a HttpServletResponse.SC_FORBIDDEN
(403 error). Again,
- * this allows common access denied handling irrespective of the originating
- * security interceptor.
+ * If an {@link AccessDeniedException} is detected, the filter will respond
+ * with a HttpServletResponse.SC_FORBIDDEN
(403 error). In
+ * addition, the AccessDeniedException
itself will be placed in
+ * the HttpSession
attribute keyed against {@link
+ * #ACEGI_SECURITY_ACCESS_DENIED_EXCEPTION_KEY} (to allow access to the stack
+ * trace etc). Again, this allows common access denied handling irrespective
+ * of the originating security interceptor.
*
@@ -96,6 +99,7 @@ public class SecurityEnforcementFilter implements Filter, InitializingBean { //~ Static fields/initializers ============================================= private static final Log logger = LogFactory.getLog(SecurityEnforcementFilter.class); + public static final String ACEGI_SECURITY_ACCESS_DENIED_EXCEPTION_KEY = "ACEGI_SECURITY_403_EXCEPTION"; //~ Instance fields ======================================================== @@ -202,6 +206,8 @@ public class SecurityEnforcementFilter implements Filter, InitializingBean { "Access is denied - sending back forbidden response"); } + ((HttpServletRequest) request).getSession().setAttribute(ACEGI_SECURITY_ACCESS_DENIED_EXCEPTION_KEY, + accessDenied); sendAccessDeniedError(request, response); } catch (Throwable otherException) { throw new ServletException(otherException); diff --git a/core/src/test/java/org/acegisecurity/intercept/web/SecurityEnforcementFilterTests.java b/core/src/test/java/org/acegisecurity/intercept/web/SecurityEnforcementFilterTests.java index 011a0b3838..dd2a2e6539 100644 --- a/core/src/test/java/org/acegisecurity/intercept/web/SecurityEnforcementFilterTests.java +++ b/core/src/test/java/org/acegisecurity/intercept/web/SecurityEnforcementFilterTests.java @@ -32,6 +32,7 @@ import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; +import javax.servlet.http.HttpSession; /** @@ -64,8 +65,9 @@ public class SecurityEnforcementFilterTests extends TestCase { public void testAccessDeniedWhenAccessDeniedException() throws Exception { // Setup our HTTP request + HttpSession session = new MockHttpSession(); MockHttpServletRequest request = new MockHttpServletRequest(null, - new MockHttpSession()); + session); request.setServletPath("/secure/page.html"); // Setup our expectation that the filter chain will not be invoked, as access is denied @@ -84,6 +86,10 @@ public class SecurityEnforcementFilterTests extends TestCase { MockHttpServletResponse response = new MockHttpServletResponse(); filter.doFilter(request, response, chain); assertEquals(403, response.getError()); + assertEquals(AccessDeniedException.class, + session.getAttribute( + SecurityEnforcementFilter.ACEGI_SECURITY_ACCESS_DENIED_EXCEPTION_KEY) + .getClass()); } public void testDoFilterWithNonHttpServletRequestDetected()