Fixed section boundaries in core-filters doc

This commit is contained in:
Luke Taylor 2009-09-15 15:58:05 +00:00
parent e7486fc203
commit 283aa1b34b
1 changed files with 133 additions and 143 deletions

View File

@ -2,13 +2,14 @@
xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Core Security Filters</title>
<para> There are some key filters which will always be used in a web application which uses
Spring Security, so we'll look at these and their supporting classes and interfaces them
first. We won't cover every feature, so be sure to look at the Javadoc for them if you want
to get the complete picture.</para>
Spring Security, so we'll look at these and their supporting classes and interfaces first.
We won't cover every feature, so be sure to look at the Javadoc for them if you want to get
the complete picture.</para>
<section xml:id="filter-security-interceptor">
<title><classname>FilterSecurityInterceptor</classname></title>
<para>We've already seen <classname>FilterSecurityInterceptor</classname> briefly when
discussing <link xlink:href="#tech-intro-access-control">access-control in general</link>, and we've already used it with the namespace where the
discussing <link xlink:href="#tech-intro-access-control">access-control in
general</link>, and we've already used it with the namespace where the
<literal>&lt;intercept-url></literal> elements are combined to configure it
internally. Now we'll see how to explicitly configure it for use with a
<classname>FilterChainProxy</classname>, along with its companion filter
@ -30,7 +31,8 @@
<interfacename>AuthenticationManager</interfacename> and an
<interfacename>AccessDecisionManager</interfacename>. It is also supplied with
configuration attributes that apply to different HTTP URL requests. Refer back to <link
xlink:href="#tech-intro-config-attributes">the original discussion on these</link> in the technical introduction.</para>
xlink:href="#tech-intro-config-attributes">the original discussion on these</link>
in the technical introduction.</para>
<para>The <classname>FilterSecurityInterceptor</classname> can be configured with
configuration attributes in two ways. The first, which is shown above, is using the
<literal>&lt;filter-security-metadata-source&gt;</literal> namespace element. This
@ -155,159 +157,147 @@
<classname>AccessDeniedHandlerImpl</classname> is used, which just sends a 403
(Forbidden) response to the client. Alternatively you can configure an instance
explicitly (as in the above example) and set an error page URL which it will
forwards the request to <footnote>
<para>We use a forward so that the SecurityContextHolder still contains details
of the principal, which may be useful for displaying to the user. In old
releases of Spring Security we relied upon the servlet container to handle a
403 error message, which lacked this useful contextual information.</para>
</footnote>. This can be a simple <quote>access denied</quote> page, such as a JSP,
or it could be a more complex handler such as an MVC controller. And of course, you
can implement the interface yourself and use your own implementation. </para>
forwards the request to <footnote><para>We use a forward so that the
SecurityContextHolder still contains details of the principal, which may be
useful for displaying to the user. In old releases of Spring Security we
relied upon the servlet container to handle a 403 error message, which
lacked this useful contextual information.</para></footnote>. This can be a
simple <quote>access denied</quote> page, such as a JSP, or it could be a more
complex handler such as an MVC controller. And of course, you can implement the
interface yourself and use your own implementation. </para>
<para>It's also possible to supply a custom
<interfacename>AccessDeniedHandler</interfacename> when you're using the
namespace to configure your application. See
<link xlink:href="#nsa-access-denied-handler">the namespace appendix</link> for more details.</para>
namespace to configure your application. See <link
xlink:href="#nsa-access-denied-handler">the namespace appendix</link> for more
details.</para>
</section>
<section xml:id="security-context-persistence-filter">
<title><classname>SecurityContextPersistenceFilter</classname></title>
<para> We covered the purpose of this all-important filter in <link
xlink:href="#tech-intro-sec-context-persistence"/> so you might want to re-read
that section at this point. Let's first take a look at how you would configure it
for use with a <classname>FilterChainProxy</classname>. A basic configuration only
requires the bean itself <programlisting><![CDATA[
</section>
<section xml:id="security-context-persistence-filter">
<title><classname>SecurityContextPersistenceFilter</classname></title>
<para> We covered the purpose of this all-important filter in <link
xlink:href="#tech-intro-sec-context-persistence"/> so you might want to re-read that
section at this point. Let's first take a look at how you would configure it for use
with a <classname>FilterChainProxy</classname>. A basic configuration only requires the
bean itself <programlisting><![CDATA[
<bean id="securityContextPersistenceFilter"
class="org.springframework.security.web.context.SecurityContextPersistenceFilter"/>
]]></programlisting> As we saw previously, this filter has two main tasks. It is responsible for
storage of the <classname>SecurityContext</classname> contents between HTTP requests
and for clearing the <classname>SecurityContextHolder</classname> when a request is
completed. Clearing the <classname>ThreadLocal</classname> in which the context is
stored is essential, as it might otherwise be possible for a thread to be replaced
into the servlet container's thread pool, with the security context for a particular
user still attached. This thread might then be used at a later stage, performing
operations with the wrong credentials. </para>
<section xml:id="security-context-repository">
<title><interfacename>SecurityContextRepository</interfacename></title>
<para>From Spring Security 3.0, the job of loading and storing the security context
is now delegated to a separate strategy interface:
<programlisting language="java">
class="org.springframework.security.web.context.SecurityContextPersistenceFilter"/>
]]></programlisting> As we saw previously, this filter has two main tasks. It is responsible for
storage of the <classname>SecurityContext</classname> contents between HTTP requests and
for clearing the <classname>SecurityContextHolder</classname> when a request is
completed. Clearing the <classname>ThreadLocal</classname> in which the context is
stored is essential, as it might otherwise be possible for a thread to be replaced into
the servlet container's thread pool, with the security context for a particular user
still attached. This thread might then be used at a later stage, performing operations
with the wrong credentials. </para>
<section xml:id="security-context-repository">
<title><interfacename>SecurityContextRepository</interfacename></title>
<para>From Spring Security 3.0, the job of loading and storing the security context is
now delegated to a separate strategy interface:
<programlisting language="java">
public interface SecurityContextRepository {
SecurityContext loadContext(HttpRequestResponseHolder requestResponseHolder);
void saveContext(SecurityContext context, HttpServletRequest request, HttpServletResponse response);
SecurityContext loadContext(HttpRequestResponseHolder requestResponseHolder);
void saveContext(SecurityContext context, HttpServletRequest request, HttpServletResponse response);
}
</programlisting>
The <classname>HttpRequestResponseHolder</classname> is simply a container for
the incoming request and response objects, allowing the implementation to
replace these with wrapper classes. The returned contents will be passed to the
filter chain. </para>
<para> The default implementation is
<classname>HttpSessionSecurityContextRepository</classname>, which stores
the security context as an <interfacename>HttpSession</interfacename> attribute <footnote>
<para>In Spring Security 2.0 and earlier, this filter was called
<classname>HttpSessionContextIntegrationFilter</classname> and
performed all the work of storing the context was performed by the
filter itself. If you were familiar with this class, then most of the
configuration options which were available can now be found on
<classname>HttpSessionSecurityContextRepository</classname>. </para>
</footnote>. The most important configuration parameter for this implementation
is the <literal>allowSessionCreation</literal> property, which defaults to
<literal>true</literal>, thus allowing the class to create a session if it
needs one to store the security context for an authenticated user (it won't
create one unless authentication has taken place and the contents of the
security context have changed). If you don't want a session to be created, then
you can set this property to <literal>false</literal>: <programlisting language="xml"><![CDATA[
The <classname>HttpRequestResponseHolder</classname> is simply a container for the
incoming request and response objects, allowing the implementation to replace these
with wrapper classes. The returned contents will be passed to the filter chain. </para>
<para> The default implementation is
<classname>HttpSessionSecurityContextRepository</classname>, which stores the
security context as an <interfacename>HttpSession</interfacename> attribute
<footnote><para>In Spring Security 2.0 and earlier, this filter was called
<classname>HttpSessionContextIntegrationFilter</classname> and performed
all the work of storing the context was performed by the filter itself. If
you were familiar with this class, then most of the configuration options
which were available can now be found on
<classname>HttpSessionSecurityContextRepository</classname>.
</para></footnote>. The most important configuration parameter for this
implementation is the <literal>allowSessionCreation</literal> property, which
defaults to <literal>true</literal>, thus allowing the class to create a session if
it needs one to store the security context for an authenticated user (it won't
create one unless authentication has taken place and the contents of the security
context have changed). If you don't want a session to be created, then you can set
this property to <literal>false</literal>: <programlisting language="xml"><![CDATA[
<bean id="securityContextPersistenceFilter"
class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
<property name='securityContextRepository'>
<bean class='org.springframework.security.web.context.HttpSessionSecurityContextRepository'>
<property name='allowSessionCreation' value='false' />
</bean>
</property>
class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
<property name='securityContextRepository'>
<bean class='org.springframework.security.web.context.HttpSessionSecurityContextRepository'>
<property name='allowSessionCreation' value='false' />
</bean>
]]></programlisting> Alternatively you could provide a null implementation of the
<interfacename>SecurityContextRepository</interfacename> interface. </para>
</section>
</property>
</bean>
]]></programlisting> Alternatively you could provide a null implementation of the
<interfacename>SecurityContextRepository</interfacename> interface. </para>
</section>
<section xml:id="form-login-filter">
<title><classname>UsernamePasswordAuthenticationProcessingFilter</classname></title>
<para>We've now seen the three main filters which are always present in a Spring
Security web configuration. These are also the three which are automatically created
by the namespace <literal>&lt;http&gt;</literal> element and cannot be substituted
with alternatives. The only thing that's missing now is an actual authentication
mechanism, something that will allow a user to authenticate. This filter is the most
commonly used authentication filter and the one that is most often customized <footnote>
<para>For historical reasons, prior to Spring Security 3.0, this filter was
called <classname>AuthenticationProcessingFilter</classname> and the entry
point was called
<classname>AuthenticationProcessingFilterEntryPoint</classname>. Since
the framework now supports many different forms of authentication, they have
both been given more specific names in 3.0.</para>
</footnote>. It also provides the implementation used by the &lt;form-login&gt;
element from the namespace. There are three stages required to configure it. <orderedlist>
<listitem>
<para>Configure a <classname>LoginUrlAuthenticationEntryPoint</classname>
with the URL of the login page, just as we did above, and set it on the
<classname>ExceptionTranslationFilter</classname>. </para>
</listitem>
<listitem>
<para>Implement the login page (using a JSP or MVC controller).</para>
</listitem>
<listitem>
<para>Configure an instance of
<classname>UsernamePasswordAuthenticationProcessingFilter</classname>
in the application context</para>
</listitem>
<listitem>
<para>Add the filter bean to your filter chain proxy (making sure you pay
attention to the order). <!-- TODO: link --></para>
</listitem>
</orderedlist> The login form simply contains <literal>j_username</literal> and
<literal>j_password</literal> input fields, and posts to the URL that is
monitored by the filter (by default this is
<literal>/j_spring_security_check</literal>). The basic filter configuration
looks something like this: <programlisting><![CDATA[
</section>
<section xml:id="form-login-filter">
<title><classname>UsernamePasswordAuthenticationProcessingFilter</classname></title>
<para>We've now seen the three main filters which are always present in a Spring Security
web configuration. These are also the three which are automatically created by the
namespace <literal>&lt;http&gt;</literal> element and cannot be substituted with
alternatives. The only thing that's missing now is an actual authentication mechanism,
something that will allow a user to authenticate. This filter is the most commonly used
authentication filter and the one that is most often customized <footnote><para>For
historical reasons, prior to Spring Security 3.0, this filter was called
<classname>AuthenticationProcessingFilter</classname> and the entry point
was called <classname>AuthenticationProcessingFilterEntryPoint</classname>.
Since the framework now supports many different forms of authentication, they
have both been given more specific names in 3.0.</para></footnote>. It also
provides the implementation used by the &lt;form-login&gt; element from the namespace.
There are three stages required to configure it. <orderedlist><listitem><para>Configure
a <classname>LoginUrlAuthenticationEntryPoint</classname> with the URL of
the login page, just as we did above, and set it on the
<classname>ExceptionTranslationFilter</classname>.
</para></listitem><listitem><para>Implement the login page (using a JSP or
MVC controller).</para></listitem><listitem><para>Configure an instance of
<classname>UsernamePasswordAuthenticationProcessingFilter</classname> in
the application context</para></listitem><listitem><para>Add the filter bean
to your filter chain proxy (making sure you pay attention to the order).
<!-- TODO: link --></para></listitem></orderedlist> The login form simply
contains <literal>j_username</literal> and <literal>j_password</literal> input fields,
and posts to the URL that is monitored by the filter (by default this is
<literal>/j_spring_security_check</literal>). The basic filter configuration looks
something like this: <programlisting><![CDATA[
<bean id="authenticationProcessingFilter" class=
"org.springframework.security.web.authentication.UsernamePasswordAuthenticationProcessingFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="filterProcessesUrl" value="/j_spring_security_check"/>
</bean> ]]>
</programlisting></para>
<section xml:id="form-login-flow-handling">
<title>Application Flow on Authentication Success and Failure</title>
<para> The filter calls the configured
<interfacename>AuthenticationManager</interfacename> to process each
authentication request. The destination following a successful authentication or
an authentication failure is controlled by the
<interfacename>AuthenticationSuccessHandler</interfacename> and
<interfacename>AuthenticationFailureHandler</interfacename> strategy
interfaces, respectively. The filter has properties which allow you to set these
so you can customize the behaviour completely <footnote>
<para>In versions prior to 3.0, the application flow at this point had
evolved to a stage was controlled by a mix of properties on this class
and strategy plugins. The decision was made for 3.0 to refactor the code
to make these two strategies entirely responsible. </para>
</footnote>. Some standard implementations are supplied such as
<classname>SimpleUrlAuthenticationSuccessHandler</classname>,
<classname>SavedRequestAwareAuthenticationSuccessHandler</classname>,
<classname>SimpleUrlAuthenticationFailureHandler</classname> and
<classname>ExceptionMappingAuthenticationFailureHandler</classname>. Have a
look at the Javadoc for these classes to see how they work. </para>
<para>If authentication is successful, the resulting
<interfacename>Authentication</interfacename> object will be placed into the
<classname>SecurityContextHolder</classname>. The configured
AuthenticationSuccessHandler will then be called to either redirect or forward
the user to the approprate destination. By default a
<classname>SavedRequestAwareAuthenticationSuccessHandler</classname> is
used, which means that the user will be redirected to the original destination
they requested before they were asked to login. <note>
<para> The <classname>ExceptionTranslationFilter</classname> caches the
original request a user makes. When the user authenticates, the request
handler makes use of this cached request to obtain the original URL and
redirect to it. The original request is then rebuilt and used as an
alternative. </para>
</note> If authentication fails, the configured
<interfacename>AuthenticationFailureHandler</interfacename> will be invoked.
</para>
</section>
</programlisting></para>
<section xml:id="form-login-flow-handling">
<title>Application Flow on Authentication Success and Failure</title>
<para> The filter calls the configured
<interfacename>AuthenticationManager</interfacename> to process each
authentication request. The destination following a successful authentication or an
authentication failure is controlled by the
<interfacename>AuthenticationSuccessHandler</interfacename> and
<interfacename>AuthenticationFailureHandler</interfacename> strategy interfaces,
respectively. The filter has properties which allow you to set these so you can
customize the behaviour completely <footnote><para>In versions prior to 3.0, the
application flow at this point had evolved to a stage was controlled by a
mix of properties on this class and strategy plugins. The decision was made
for 3.0 to refactor the code to make these two strategies entirely
responsible. </para></footnote>. Some standard implementations are supplied
such as <classname>SimpleUrlAuthenticationSuccessHandler</classname>,
<classname>SavedRequestAwareAuthenticationSuccessHandler</classname>,
<classname>SimpleUrlAuthenticationFailureHandler</classname> and
<classname>ExceptionMappingAuthenticationFailureHandler</classname>. Have a look
at the Javadoc for these classes to see how they work. </para>
<para>If authentication is successful, the resulting
<interfacename>Authentication</interfacename> object will be placed into the
<classname>SecurityContextHolder</classname>. The configured
AuthenticationSuccessHandler will then be called to either redirect or forward the
user to the approprate destination. By default a
<classname>SavedRequestAwareAuthenticationSuccessHandler</classname> is used,
which means that the user will be redirected to the original destination they
requested before they were asked to login. <note><para> The
<classname>ExceptionTranslationFilter</classname> caches the original
request a user makes. When the user authenticates, the request handler makes
use of this cached request to obtain the original URL and redirect to it.
The original request is then rebuilt and used as an alternative.
</para></note> If authentication fails, the configured
<interfacename>AuthenticationFailureHandler</interfacename> will be invoked.
</para>
</section>
</section>
</chapter>