diff --git a/doc/docbook/acegi.xml b/doc/docbook/acegi.xml index 61b6cc18a9..d54a7f08f1 100644 --- a/doc/docbook/acegi.xml +++ b/doc/docbook/acegi.xml @@ -193,7 +193,8 @@ - @@ -344,7 +345,8 @@ - + @@ -1716,7 +1718,8 @@ public boolean supports(Class clazz); - @@ -3795,7 +3798,8 @@ $CATALINA_HOME/bin/startup.sh - + @@ -4156,6 +4160,99 @@ INSERT INTO acl_permission VALUES (null, 6, 'scott', 1); WebApplicationContextUtils.getWebApplicationContext(ServletContext), so you should configure a ContextLoaderListener in web.xml. + + There is a lifecycle issue to consider when hosting + Filters in an IoC container instead of a servlet + container. Specifically, which container should be responsible for + calling the Filter's "startup" and "shutdown" + methods? It is noted that the order of initialization and destruction + of a Filter can vary by servlet container, and this + can cause problems if one Filter depends on + configuration settings established by an earlier initialized + Filter. The Spring IoC container on the other hand + has more comprehensive lifecycle/IoC interfaces (such as + InitializingBean, + DisposableBean, BeanNameAware, + ApplicationContextAware and many others) as well as + a well-understood interface contract, predictable method invocation + ordering, autowiring support, and even options to avoid implementing + Spring interfaces (eg the destroy-method attribute + in Spring XML). For this reason we recommend the use of Spring + lifecycle services instead of servlet container lifecycle services + wherever possible. By default FilterToBeanProxy + will not delegate init(FilterConfig) and + destroy() methods through to the proxied bean. If + you do require such invocations to be delegated, set the + lifecycle initialization parameter to + servlet-container-managed. + + + + FilterChainProxy + + Whilst FilterToBeanProxy is a very useful + class, the problem is that the lines of code required for + <filter> and + <filter-mapping> entries in + web.xml explodes when using more than a few + filters. To overcome this issue, Acegi Security provides a + FilterChainProxy class. It is wired using a + FilterToBeanProxy (just like in the example above), + but the target class is + net.sf.acegisecurity.util.FilterChainProxy. The + filter chain is then declared in the application context, using code + such as this: + + <bean id="filterChainProxy" class="net.sf.acegisecurity.util.FilterChainProxy"> + <property name="filterInvocationDefinitionSource"> + <value> + CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON + PATTERN_TYPE_APACHE_ANT + /webServices/**=basicProcessingFilter,httpSessionIntegrationFilter,securityEnforcementFilter + /**=authenticationProcessingFilter,httpSessionIntegrationFilter,securityEnforcementFilter + </value> + </property> +</bean> + + You may notice similarities with the way + SecurityEnforcementFilter is declared. Both regular + expressions and Ant Paths are supported, and the most specific URIs + appear first. At runtime the FilterChainProxy will + locate the first URI pattern that matches the current web request. + Each of the corresponding configuration attributes represent the name + of a bean defined in the application context. The filters will then be + invoked in the order they are specified, with standard + FilterChain behaviour being respected (a + Filter can elect not to proceed with the chain if + it wishes to end processing). + + As you can see, FitlerChainProxy requires the + duplication of filter names for different request patterns (in the + above example, httpSessionIntegrationFilter and + securityEnforcementFilter are duplicated). This + design decision was made to enable FilterChainProxy + to specify different Filter invocation orders for + different URI patterns, and also to improve both the expressiveness + (in terms of regular expressions, Ant Paths, and any custom + FilterInvocationDefinitionSource implementations) + and clarity of which Filters should be + invoked. + + In relation to lifecycle issues, the + FilterChainProxy will always delegate + init(FilterConfig) and destroy() + methods through to the underlaying Filters if such + methods are called against FilterChainProxy itself. + In this case, FilterChainProxy guarantees to only + initialize and destroy each Filter once, + irrespective of how many times it is declared by the + FilterInvocationDefinitionSource. You control the + overall choice as to whether these methods are called or not via the + lifecycle initialization parameter of the + FilterToBeanProxy that proxies + FilterChainProxy. As discussed above, by default + any servlet container lifecycle invocations are not delegated through + to FilterChainProxy. @@ -4201,8 +4298,13 @@ INSERT INTO acl_permission VALUES (null, 6, 'scott', 1); All of the above filters use - FilterToBeanProxy, which is discussed in the - previous section. + FilterToBeanProxy or + FilterChainProxy, which is discussed in the + previous sections. It is recommended that a single + FilterToBeProxy proxy through to a single + FilterChainProxy for each application, with that + FilterChainProxy defining all of the Acegi Security + Filters. If you're using SiteMesh, ensure the Acegi Security filters execute before the SiteMesh filters are called. This enables the