diff --git a/core/src/main/java/org/acegisecurity/intercept/web/FilterSecurityInterceptor.java b/core/src/main/java/org/acegisecurity/intercept/web/FilterSecurityInterceptor.java index e288a651d7..2012462d54 100644 --- a/core/src/main/java/org/acegisecurity/intercept/web/FilterSecurityInterceptor.java +++ b/core/src/main/java/org/acegisecurity/intercept/web/FilterSecurityInterceptor.java @@ -1,4 +1,4 @@ -/* Copyright 2004 Acegi Technology Pty Limited +/* Copyright 2004, 2005 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,6 +44,10 @@ import net.sf.acegisecurity.intercept.ObjectDefinitionSource; * @version $Id$ */ public class FilterSecurityInterceptor extends AbstractSecurityInterceptor { + //~ Static fields/initializers ============================================= + + private static final String FILTER_APPLIED = "__acegi_filterSecurityInterceptor_filterApplied"; + //~ Instance fields ======================================================== private FilterInvocationDefinitionSource objectDefinitionSource; @@ -64,12 +68,23 @@ public class FilterSecurityInterceptor extends AbstractSecurityInterceptor { } public void invoke(FilterInvocation fi) throws Throwable { - InterceptorStatusToken token = super.beforeInvocation(fi); - - try { + if ((fi.getRequest() != null) + && (fi.getRequest().getAttribute(FILTER_APPLIED) != null)) { + // filter already applied to this request, so don't re-do security checking fi.getChain().doFilter(fi.getRequest(), fi.getResponse()); - } finally { - super.afterInvocation(token, null); + } else { + // first time this request being called, so perform security checking + if (fi.getRequest() != null) { + fi.getRequest().setAttribute(FILTER_APPLIED, Boolean.TRUE); + } + + InterceptorStatusToken token = super.beforeInvocation(fi); + + try { + fi.getChain().doFilter(fi.getRequest(), fi.getResponse()); + } finally { + super.afterInvocation(token, null); + } } } diff --git a/core/src/test/java/org/acegisecurity/MockHttpServletRequest.java b/core/src/test/java/org/acegisecurity/MockHttpServletRequest.java index d1b168e16d..a1c7fe06b6 100644 --- a/core/src/test/java/org/acegisecurity/MockHttpServletRequest.java +++ b/core/src/test/java/org/acegisecurity/MockHttpServletRequest.java @@ -49,6 +49,7 @@ public class MockHttpServletRequest implements HttpServletRequest { //~ Instance fields ======================================================== private HttpSession session = new MockHttpSession(); + private Map attribMap = new HashMap(); private Map headersMap = new HashMap(); private Map paramMap = new HashMap(); private Principal principal; @@ -86,11 +87,11 @@ public class MockHttpServletRequest implements HttpServletRequest { //~ Methods ================================================================ public void setAttribute(String arg0, Object arg1) { - throw new UnsupportedOperationException("mock method not implemented"); + this.attribMap.put(arg0, arg1); } public Object getAttribute(String arg0) { - throw new UnsupportedOperationException("mock method not implemented"); + return this.attribMap.get(arg0); } public Enumeration getAttributeNames() { diff --git a/doc/xdocs/changes.xml b/doc/xdocs/changes.xml index 8a9439cc9d..28ee90775a 100644 --- a/doc/xdocs/changes.xml +++ b/doc/xdocs/changes.xml @@ -33,6 +33,7 @@ User now accepted blank passwords (null passwords still rejected) ContextHolderAwareRequestWrapper now provides a getUserPrincipal() method HttpSessionIntegrationFilter no longer creates a HttpSession unnecessarily + FilterSecurityInterceptor now only executes once per request (improves performance with SiteMesh) Contacts sample web.xml no longer expect Log4j to be in classpath JaasAuthenticatinProvider now uses System.property "java.security.auth.login.config" JaasAuthenticationCallbackHandler Authentication is passed to handle method setAuthenticatoin removed