Add FilterChainProxy discussion.
This commit is contained in:
parent
f57b1b9a8f
commit
436d37c166
|
@ -193,7 +193,8 @@
|
|||
|
||||
<para><mediaobject>
|
||||
<imageobject role="html">
|
||||
<imagedata align="center" fileref="images/SecurityInterception.gif"
|
||||
<imagedata align="center"
|
||||
fileref="images/SecurityInterception.gif"
|
||||
format="GIF" />
|
||||
</imageobject>
|
||||
|
||||
|
@ -344,7 +345,8 @@
|
|||
|
||||
<para><mediaobject>
|
||||
<imageobject role="html">
|
||||
<imagedata align="center" fileref="images/Context.gif" format="GIF" />
|
||||
<imagedata align="center" fileref="images/Context.gif"
|
||||
format="GIF" />
|
||||
</imageobject>
|
||||
|
||||
<caption>
|
||||
|
@ -1716,7 +1718,8 @@ public boolean supports(Class clazz);</programlisting></para>
|
|||
|
||||
<para><mediaobject>
|
||||
<imageobject role="html">
|
||||
<imagedata align="center" fileref="images/AccessDecisionVoting.gif"
|
||||
<imagedata align="center"
|
||||
fileref="images/AccessDecisionVoting.gif"
|
||||
format="GIF" />
|
||||
</imageobject>
|
||||
|
||||
|
@ -3795,7 +3798,8 @@ $CATALINA_HOME/bin/startup.sh</programlisting></para>
|
|||
|
||||
<para><mediaobject>
|
||||
<imageobject role="html">
|
||||
<imagedata align="center" fileref="images/ACLSecurity.gif" format="GIF" />
|
||||
<imagedata align="center" fileref="images/ACLSecurity.gif"
|
||||
format="GIF" />
|
||||
</imageobject>
|
||||
|
||||
<caption>
|
||||
|
@ -4156,6 +4160,99 @@ INSERT INTO acl_permission VALUES (null, 6, 'scott', 1);</programlisting></para>
|
|||
WebApplicationContextUtils.getWebApplicationContext(ServletContext)</literal>,
|
||||
so you should configure a <literal>ContextLoaderListener</literal> in
|
||||
<literal>web.xml</literal>.</para>
|
||||
|
||||
<para>There is a lifecycle issue to consider when hosting
|
||||
<literal>Filter</literal>s in an IoC container instead of a servlet
|
||||
container. Specifically, which container should be responsible for
|
||||
calling the <literal>Filter</literal>'s "startup" and "shutdown"
|
||||
methods? It is noted that the order of initialization and destruction
|
||||
of a <literal>Filter</literal> can vary by servlet container, and this
|
||||
can cause problems if one <literal>Filter</literal> depends on
|
||||
configuration settings established by an earlier initialized
|
||||
<literal>Filter</literal>. The Spring IoC container on the other hand
|
||||
has more comprehensive lifecycle/IoC interfaces (such as
|
||||
<literal>InitializingBean</literal>,
|
||||
<literal>DisposableBean</literal>, <literal>BeanNameAware</literal>,
|
||||
<literal>ApplicationContextAware</literal> 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 <literal>destroy-method</literal> 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 <literal>FilterToBeanProxy</literal>
|
||||
will not delegate <literal>init(FilterConfig)</literal> and
|
||||
<literal>destroy()</literal> methods through to the proxied bean. If
|
||||
you do require such invocations to be delegated, set the
|
||||
<literal>lifecycle</literal> initialization parameter to
|
||||
<literal>servlet-container-managed</literal>.</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="security-filters-filterchainproxy">
|
||||
<title>FilterChainProxy</title>
|
||||
|
||||
<para>Whilst <literal>FilterToBeanProxy</literal> is a very useful
|
||||
class, the problem is that the lines of code required for
|
||||
<literal><filter></literal> and
|
||||
<literal><filter-mapping></literal> entries in
|
||||
<literal>web.xml</literal> explodes when using more than a few
|
||||
filters. To overcome this issue, Acegi Security provides a
|
||||
<literal>FilterChainProxy</literal> class. It is wired using a
|
||||
<literal>FilterToBeanProxy</literal> (just like in the example above),
|
||||
but the target class is
|
||||
<literal>net.sf.acegisecurity.util.FilterChainProxy</literal>. The
|
||||
filter chain is then declared in the application context, using code
|
||||
such as this:</para>
|
||||
|
||||
<para><programlisting><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></programlisting></para>
|
||||
|
||||
<para>You may notice similarities with the way
|
||||
<literal>SecurityEnforcementFilter</literal> is declared. Both regular
|
||||
expressions and Ant Paths are supported, and the most specific URIs
|
||||
appear first. At runtime the <literal>FilterChainProxy</literal> 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
|
||||
<literal>FilterChain</literal> behaviour being respected (a
|
||||
<literal>Filter</literal> can elect not to proceed with the chain if
|
||||
it wishes to end processing).</para>
|
||||
|
||||
<para>As you can see, <literal>FitlerChainProxy</literal> requires the
|
||||
duplication of filter names for different request patterns (in the
|
||||
above example, <literal>httpSessionIntegrationFilter</literal> and
|
||||
<literal>securityEnforcementFilter</literal> are duplicated). This
|
||||
design decision was made to enable <literal>FilterChainProxy</literal>
|
||||
to specify different <literal>Filter</literal> invocation orders for
|
||||
different URI patterns, and also to improve both the expressiveness
|
||||
(in terms of regular expressions, Ant Paths, and any custom
|
||||
<literal>FilterInvocationDefinitionSource</literal> implementations)
|
||||
and clarity of which <literal>Filter</literal>s should be
|
||||
invoked.</para>
|
||||
|
||||
<para>In relation to lifecycle issues, the
|
||||
<literal>FilterChainProxy</literal> will always delegate
|
||||
<literal>init(FilterConfig)</literal> and <literal>destroy()</literal>
|
||||
methods through to the underlaying <literal>Filter</literal>s if such
|
||||
methods are called against <literal>FilterChainProxy</literal> itself.
|
||||
In this case, <literal>FilterChainProxy</literal> guarantees to only
|
||||
initialize and destroy each <literal>Filter</literal> once,
|
||||
irrespective of how many times it is declared by the
|
||||
<literal>FilterInvocationDefinitionSource</literal>. You control the
|
||||
overall choice as to whether these methods are called or not via the
|
||||
<literal>lifecycle</literal> initialization parameter of the
|
||||
<literal>FilterToBeanProxy</literal> that proxies
|
||||
<literal>FilterChainProxy</literal>. As discussed above, by default
|
||||
any servlet container lifecycle invocations are not delegated through
|
||||
to <literal>FilterChainProxy</literal>.</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="security-filters-order">
|
||||
|
@ -4201,8 +4298,13 @@ INSERT INTO acl_permission VALUES (null, 6, 'scott', 1);</programlisting></para>
|
|||
</orderedlist>
|
||||
|
||||
<para>All of the above filters use
|
||||
<literal>FilterToBeanProxy</literal>, which is discussed in the
|
||||
previous section.</para>
|
||||
<literal>FilterToBeanProxy</literal> or
|
||||
<literal>FilterChainProxy</literal>, which is discussed in the
|
||||
previous sections. It is recommended that a single
|
||||
<literal>FilterToBeProxy</literal> proxy through to a single
|
||||
<literal>FilterChainProxy</literal> for each application, with that
|
||||
<literal>FilterChainProxy</literal> defining all of the Acegi Security
|
||||
<literal>Filter</literal>s.</para>
|
||||
|
||||
<para>If you're using SiteMesh, ensure the Acegi Security filters
|
||||
execute before the SiteMesh filters are called. This enables the
|
||||
|
|
Loading…
Reference in New Issue