Browse Source

Add the AccessDeniedException to the HttpSession as per http://forum.springframework.org/viewtopic.php?t=1515.

Ben Alex 21 years ago
parent
commit
26f5f1a9b3

+ 1 - 0
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)

+ 10 - 4
core/src/main/java/org/acegisecurity/intercept/web/SecurityEnforcementFilter.java

@@ -54,10 +54,13 @@ import javax.servlet.http.HttpServletResponse;
  * </p>
  * 
  * <p>
- * If an {@link AccessDeniedException} is detected, the filter will response
- * with a <code>HttpServletResponse.SC_FORBIDDEN</code> (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 <code>HttpServletResponse.SC_FORBIDDEN</code> (403 error).  In
+ * addition, the <code>AccessDeniedException</code> itself will be placed in
+ * the <code>HttpSession</code> 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.
  * </p>
  * 
  * <p>
@@ -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);

+ 7 - 1
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()