Manual updates
This commit is contained in:
parent
853b4c8753
commit
be12d93f7a
|
@ -6,31 +6,49 @@
|
|||
<info>
|
||||
<title>Overview</title>
|
||||
</info>
|
||||
<para>Particularly in the case of web request URI security, sometimes it is more convenient
|
||||
to assign configuration attributes against every possible secure object invocation. Put
|
||||
differently, sometimes it is nice to say <literal>ROLE_SOMETHING</literal> is required
|
||||
by default and only allow certain exceptions to this rule, such as for login, logout and
|
||||
home pages of an application. There are also other situations where anonymous
|
||||
authentication would be desired, such as when an auditing interceptor queries the
|
||||
<classname>SecurityContextHolder</classname> to identify which principal was
|
||||
responsible for a given operation. Such classes can be authored with more robustness if
|
||||
they know the <classname>SecurityContextHolder</classname> always contains an
|
||||
<interfacename>Authentication</interfacename> object, and never
|
||||
<para>It's generally considered good security practice to adopt a
|
||||
<quote>deny-by-default</quote> where you explicitly specify what is allowed and
|
||||
disallow everything else. Defining what is accessible to unauthenticated users is a
|
||||
similar situation, particularly for web applications. Many sites require that users must
|
||||
be authenticated for anything other than a few URLs (for example the home and login
|
||||
pages). In this case it is easiest to define access configuration attributes for these
|
||||
specific URLs rather than have for every secured resource. Put differently, sometimes it
|
||||
is nice to say <literal>ROLE_SOMETHING</literal> is required by default and only allow
|
||||
certain exceptions to this rule, such as for login, logout and home pages of an
|
||||
application. You could also omit these pages from the filter chain entirely, thus
|
||||
bypassing the access control checks, but this may be undesirable for other reasons,
|
||||
particularly if the pages behave differently for authenticated users.</para>
|
||||
<para>This is what we mean by anonymous authentication. Note that there is no real
|
||||
conceptual difference between a user who is <quote>anonymously authenticated</quote> and
|
||||
an unauthenticated user. Spring Security's anonymous authentication just gives you a
|
||||
more convenient way to configure your access-control attributes. Calls to servlet API
|
||||
calls such as <methodname>getCallerPrincipal</methodname>, for example, will still
|
||||
return null even though there is actually an anonymous authentication object in the
|
||||
<classname>SecurityContextHolder</classname>.</para>
|
||||
<para>There are other situations where anonymous authentication is useful, such as when an
|
||||
auditing interceptor queries the <classname>SecurityContextHolder</classname> to
|
||||
identify which principal was responsible for a given operation. Classes can be authored
|
||||
more robustly if they know the <classname>SecurityContextHolder</classname> always
|
||||
contains an <interfacename>Authentication</interfacename> object, and never
|
||||
<literal>null</literal>.</para>
|
||||
</section>
|
||||
<section xml:id="anonymous-config">
|
||||
<info>
|
||||
<title>Configuration</title>
|
||||
</info>
|
||||
<para>Spring Security provides three classes that together provide an anonymous
|
||||
authentication feature. <literal>AnonymousAuthenticationToken</literal> is an
|
||||
implementation of <interfacename>Authentication</interfacename>, and stores the
|
||||
<interfacename>GrantedAuthority</interfacename>[]s which apply to the anonymous
|
||||
<para>Anonymous authentication support is provided automatically when using the HTTP
|
||||
configurain Spring Security 3.0 and can be customized (or disabled) using the
|
||||
<literal><anonymous></literal> element. You don't need to configure the beans
|
||||
described here unless you are using traditional bean configuration.</para>
|
||||
<para>Three classes that together provide the anonymous authentication feature.
|
||||
<literal>AnonymousAuthenticationToken</literal> is an implementation of
|
||||
<interfacename>Authentication</interfacename>, and stores the
|
||||
<interfacename>GrantedAuthority</interfacename>s which apply to the anonymous
|
||||
principal. There is a corresponding <literal>AnonymousAuthenticationProvider</literal>,
|
||||
which is chained into the <literal>ProviderManager</literal> so that
|
||||
<literal>AnonymousAuthenticationTokens</literal> are accepted. Finally, there is an
|
||||
<literal>AnonymousAuthenticationToken</literal>s are accepted. Finally, there is an
|
||||
AnonymousProcessingFilter, which is chained after the normal authentication mechanisms
|
||||
and automatically add an <literal>AnonymousAuthenticationToken</literal> to the
|
||||
and automatically adds an <literal>AnonymousAuthenticationToken</literal> to the
|
||||
<classname>SecurityContextHolder</classname> if there is no existing
|
||||
<interfacename>Authentication</interfacename> held there. The definition of the
|
||||
filter and authentication provider appears as follows:</para>
|
||||
|
@ -50,8 +68,22 @@
|
|||
</programlisting>
|
||||
</para>
|
||||
<para>The <literal>key</literal> is shared between the filter and authentication provider,
|
||||
so that tokens created by the former are accepted by the latter. The
|
||||
<literal>userAttribute</literal> is expressed in the form of
|
||||
so that tokens created by the former are accepted by the latter<footnote>
|
||||
<para>The use of the <literal>key</literal> property should not be regarded as
|
||||
providing any real security here. It is merely a book-keeping exercise. If you
|
||||
are sharing a <classname>ProviderManager</classname> which contains an
|
||||
<classname>AnonymousAuthenticationProvider</classname> in a scenario where
|
||||
it is possible for an authenticating client to construct the
|
||||
<interfacename>Authentication</interfacename> object (such as with RMI
|
||||
invocations), then a malicious client could submit an
|
||||
<classname>AnonyousAuthenticationToken</classname> which it had created
|
||||
itself (with chosen username and authority list). If the <literal>key</literal>
|
||||
is guessable or can be found out, then the token would be accepted by the
|
||||
anonymous provider. This isn't a problem with normal usage but if you are using
|
||||
RMI you would be best to use a customized <classname>ProviderManager</classname>
|
||||
which omits the anonymous provider rather than sharing the one you use for your
|
||||
HTTP authentication mechanisms.</para>
|
||||
</footnote>. The <literal>userAttribute</literal> is expressed in the form of
|
||||
<literal>usernameInTheAuthenticationToken,grantedAuthority[,grantedAuthority]</literal>.
|
||||
This is the same syntax as used after the equals sign for
|
||||
<literal>InMemoryDaoImpl</literal>'s <literal>userMap</literal> property.</para>
|
||||
|
@ -59,7 +91,7 @@
|
|||
can have security applied to them. For example:</para>
|
||||
<para><programlisting>
|
||||
<![CDATA[
|
||||
<bean id="filterInvocationInterceptor"
|
||||
<bean id="filterSecurityInterceptor"
|
||||
class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
|
||||
<property name="authenticationManager" ref="authenticationManager"/>
|
||||
<property name="accessDecisionManager" ref="httpRequestAccessDecisionManager"/>
|
||||
|
@ -73,18 +105,31 @@
|
|||
</security:filter-security-metadata-source>" +
|
||||
</property>
|
||||
</bean>]]>
|
||||
</programlisting>Rounding out the anonymous authentication discussion is the
|
||||
<literal>AuthenticationTrustResolver</literal> interface, with its corresponding
|
||||
<literal>AuthenticationTrustResolverImpl</literal> implementation. This interface
|
||||
</programlisting></para>
|
||||
</section>
|
||||
<section xml:id="anonymous-auth-trust-resolver">
|
||||
<title><interfacename>AuthenticationTrustResolver</interfacename></title>
|
||||
<para>
|
||||
Rounding out the anonymous authentication discussion is the
|
||||
<interfacename>AuthenticationTrustResolver</interfacename> interface, with its corresponding
|
||||
<literal>AuthenticationTrustResolverImpl</literal> implementation. This interface
|
||||
provides an <literal>isAnonymous(Authentication)</literal> method, which allows
|
||||
interested classes to take into account this special type of authentication status. The
|
||||
<classname>ExceptionTranslationFilter</classname> uses this interface in processing
|
||||
<literal>AccessDeniedException</literal>s. If an
|
||||
<literal>AccessDeniedException</literal> is thrown, and the authentication is of an
|
||||
<classname>ExceptionTranslationFilter</classname> uses this interface in processing
|
||||
<literal>AccessDeniedException</literal>s. If an
|
||||
<literal>AccessDeniedException</literal> is thrown, and the authentication is of an
|
||||
anonymous type, instead of throwing a 403 (forbidden) response, the filter will instead
|
||||
commence the <interfacename>AuthenticationEntryPoint</interfacename> so the principal
|
||||
can authenticate properly. This is a necessary distinction, otherwise principals would
|
||||
always be deemed "authenticated" and never be given an opportunity to login via form,
|
||||
basic, digest or some other normal authentication mechanism</para>
|
||||
always be deemed <quote>authenticated</quote> and never be given an opportunity to login
|
||||
via form, basic, digest or some other normal authentication mechanism.
|
||||
</para>
|
||||
<para>
|
||||
You will often see the <literal>ROLE_ANONYMOUS</literal> attribute in the above interceptor configuration
|
||||
replaced with <literal>IS_AUTHENTICATED_ANONYMOUSLY</literal>. This is an example of the use of the
|
||||
<classname>AuthenticatedVoter</classname> which will see in ???. It uses an
|
||||
<interfacename>AuthenticationTrustResolver</interfacename> to process this particular configuration
|
||||
attribute and grant access to aonymous users.
|
||||
</para>
|
||||
</section>
|
||||
</chapter>
|
||||
|
|
|
@ -86,7 +86,7 @@
|
|||
<literal>/secure/</literal> pattern. If they were reversed, the
|
||||
<literal>/secure/</literal> pattern would always match and the
|
||||
<literal>/secure/super/</literal> pattern would never be evaluated.</para>
|
||||
<!--
|
||||
<!--
|
||||
TODO: Put in FAQ instead. Or drop.
|
||||
<para>As with other security interceptors, the <literal>validateConfigAttributes</literal>
|
||||
property is observed. When set to <literal>true</literal> (the default), at startup time
|
||||
|
@ -96,16 +96,15 @@
|
|||
<interfacename>AccessDecisionManager</interfacename> or the
|
||||
<literal>RunAsManager</literal>. If neither of these can process a particular
|
||||
configuration attribute, an exception is thrown.</para>
|
||||
-->
|
||||
-->
|
||||
</section>
|
||||
<section xml:id="exception-translation-filter">
|
||||
<title>
|
||||
<classname>ExceptionTranslationFilter</classname></title>
|
||||
<para>The <classname>ExceptionTranslationFilter</classname> sits above the <classname>FilterSecurityInterceptor</classname>
|
||||
in the security filter stack. It doesn't do any actual security enforcement itself,
|
||||
but handles exceptions thrown by the security interceptors and provides suitable
|
||||
and HTTP responses.
|
||||
<programlisting language="xml"><![CDATA[
|
||||
<para>The <classname>ExceptionTranslationFilter</classname> sits above the
|
||||
<classname>FilterSecurityInterceptor</classname> in the security filter stack. It
|
||||
doesn't do any actual security enforcement itself, but handles exceptions thrown by the
|
||||
security interceptors and provides suitable and HTTP responses. <programlisting language="xml"><![CDATA[
|
||||
<bean id="exceptionTranslationFilter"
|
||||
class="org.springframework.security.web.access.ExceptionTranslationFilter">
|
||||
<property name="authenticationEntryPoint" ref="authenticationEntryPoint"/>
|
||||
|
@ -121,22 +120,20 @@
|
|||
class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
|
||||
<property name="errorPage" value="/accessDenied.htm"/>
|
||||
</bean>
|
||||
]]></programlisting>
|
||||
</para>
|
||||
]]></programlisting></para>
|
||||
<section xml:id="auth-entry-point">
|
||||
<title><interfacename>AuthenticationEntryPoint</interfacename></title>
|
||||
<para>
|
||||
The <interfacename>AuthenticationEntryPoint</interfacename> will be
|
||||
called if the user requests a secure HTTP resource but they are not authenticated. An
|
||||
appropriate <exceptionname>AuthenticationException</exceptionname> or
|
||||
<exceptionname>AccessDeniedException</exceptionname> will be thrown by a security
|
||||
interceptor further down the call stack, triggering the
|
||||
<methodname>commence</methodname> method on the entry point. This does the job of
|
||||
presenting the appropriate response to the user so that authentication can begin. The
|
||||
one we've used here is <classname>LoginUrlAuthenticationEntryPoint</classname>, which
|
||||
redirects the request to a different URL (typically a login page). The actual
|
||||
implementation used will depend on the authentication mechanism you want to be used in
|
||||
your application. </para>
|
||||
<para> The <interfacename>AuthenticationEntryPoint</interfacename> will be called if the
|
||||
user requests a secure HTTP resource but they are not authenticated. An appropriate
|
||||
<exceptionname>AuthenticationException</exceptionname> or
|
||||
<exceptionname>AccessDeniedException</exceptionname> will be thrown by a
|
||||
security interceptor further down the call stack, triggering the
|
||||
<methodname>commence</methodname> method on the entry point. This does the job
|
||||
of presenting the appropriate response to the user so that authentication can begin.
|
||||
The one we've used here is <classname>LoginUrlAuthenticationEntryPoint</classname>,
|
||||
which redirects the request to a different URL (typically a login page). The actual
|
||||
implementation used will depend on the authentication mechanism you want to be used
|
||||
in your application. </para>
|
||||
</section>
|
||||
<section xml:id="access-denied-handler">
|
||||
<title><interfacename>AccessDeniedHandler</interfacename></title>
|
||||
|
@ -156,65 +153,69 @@
|
|||
for which they don't have enough permissions. In this case,
|
||||
<classname>ExceptionTranslationFilter</classname> will invoke a second strategy,
|
||||
the <interfacename>AccessDeniedHandler</interfacename>. By default, an
|
||||
<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>
|
||||
<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"/>.</para>
|
||||
<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>
|
||||
<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"/>.</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[
|
||||
<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>
|
||||
|
||||
]]></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">
|
||||
<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);
|
||||
}
|
||||
</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[
|
||||
</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[
|
||||
<bean id="securityContextPersistenceFilter"
|
||||
class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
|
||||
<property name='securityContextRepository'>
|
||||
|
@ -223,83 +224,89 @@ public interface SecurityContextRepository {
|
|||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
]]></programlisting>
|
||||
|
||||
Alternatively you could provide a null implementation of the <interfacename>SecurityContextRepository</interfacename> interface.
|
||||
</para>
|
||||
]]></programlisting> Alternatively you could provide a null implementation of the
|
||||
<interfacename>SecurityContextRepository</interfacename> interface. </para>
|
||||
</section>
|
||||
</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><http></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 <form-login> 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>
|
||||
<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><http></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 <form-login>
|
||||
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
|
||||
<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[
|
||||
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>
|
||||
|
||||
</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>
|
||||
processes 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 as
|
||||
much as you want
|
||||
<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> 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.
|
||||
<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>
|
||||
|
|
|
@ -27,17 +27,15 @@
|
|||
chapter and refresh your memory. The most common approach to verifying an authentication
|
||||
request is to load the corresponding <interfacename>UserDetails</interfacename> and
|
||||
check the loaded password against the one that has been entered by the user. This is the
|
||||
approach used by the <classname>DaoAuthenticationProvider</classname>, which wraps a
|
||||
<interfacename>UserDetailsService</interfacename> to implement an
|
||||
<interfacename>AuthenticationProvider</interfacename>. The loaded
|
||||
<interfacename>UserDetails</interfacename> object - and particularly the
|
||||
approach used by the <classname>DaoAuthenticationProvider</classname> (see below). The
|
||||
loaded <interfacename>UserDetails</interfacename> object - and particularly the
|
||||
<literal>GrantedAuthority</literal>s it contains - will be used when building the
|
||||
fully populated <interfacename>Authentication</interfacename> object which is returned
|
||||
from a successful authentication and stored in the
|
||||
<classname>SecurityContext</classname>. </para>
|
||||
<para> If you are using the namespace, an instance of
|
||||
<classname>ProviderMananger</classname> is created and maintained internally, and
|
||||
you add providers to it either by using the namespace authentication provired elements,
|
||||
you add providers to it either by using the namespace authentication provider elements,
|
||||
or by adding the <literal><custom-authentication-provider></literal> element to a
|
||||
bean (see <link xlink:href="#ns-auth-manager">the namespace chapter</link>). In this
|
||||
case, you should not declare a <classname>ProviderManager</classname> bean in your
|
||||
|
@ -76,6 +74,33 @@
|
|||
concerned about this, because if you forget to register a suitable provider, you'll
|
||||
simply receive a <literal>ProviderNotFoundException</literal> when an attempt to
|
||||
authenticate is made.</para>
|
||||
<section>
|
||||
<title><literal>DaoAuthenticationProvider</literal></title>
|
||||
<para>The simplest <interfacename>AuthenticationProvider</interfacename> implemented by
|
||||
Spring Security is <literal>DaoAuthenticationProvider</literal>, which is is also
|
||||
one of the earliest supported by the framework. It leverages a
|
||||
<interfacename>UserDetailsService</interfacename> (as a DAO) in order to lookup
|
||||
the username, password and <interfacename>GrantedAuthority</interfacename>s. It
|
||||
authenticates the user simply by comparing the password submitted in a
|
||||
<classname>UsernamePasswordAuthenticationToken</classname> against the one
|
||||
loaded by the <interfacename>UserDetailsService</interfacename>. Configuring the
|
||||
provider is quite simple:
|
||||
<programlisting language="xml"><![CDATA[
|
||||
<bean id="daoAuthenticationProvider"
|
||||
class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
|
||||
<property name="userDetailsService" ref="inMemoryDaoImpl"/>
|
||||
<property name="saltSource" ref bean="saltSource"/>
|
||||
<property name="passwordEncoder" ref="passwordEncoder"/>
|
||||
</bean>]]></programlisting>
|
||||
The <interfacename>PasswordEncoder</interfacename> and <interfacename>SaltSource</interfacename> are
|
||||
optional. A <interfacename>PasswordEncoder</interfacename> provides encoding and decoding of passwords
|
||||
presented in the <interfacename>UserDetails</interfacename> object that is returned from the configured
|
||||
<interfacename>UserDetailsService</interfacename>. A <interfacename>SaltSource</interfacename> enables
|
||||
the passwords to be populated with a "salt", which enhances the security of the
|
||||
passwords in the authentication repository. These will be discussed in more detail in ???.
|
||||
<!-- TODO: Add sections on password encoding and user caching to advaced topics -->
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
<section>
|
||||
<title><interfacename>UserDetailsService</interfacename> Implementations</title>
|
||||
|
|
|
@ -1,36 +1,34 @@
|
|||
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="dao-provider">
|
||||
|
||||
<info><title>DAO Authentication Provider</title></info>
|
||||
|
||||
<section xml:id="dao-provider-overview">
|
||||
<info><title>Overview</title></info>
|
||||
|
||||
<para>Spring Security includes a production-quality
|
||||
<classname>AuthenticationProvider</classname> implementation called
|
||||
<literal>DaoAuthenticationProvider</literal>. This authentication
|
||||
provider is compatible with all of the authentication mechanisms that
|
||||
generate a <literal>UsernamePasswordAuthenticationToken</literal>, and
|
||||
is probably the most commonly used provider in the framework. Like
|
||||
most of the other authentication providers, the
|
||||
DaoAuthenticationProvider leverages a UserDetailsService in order to
|
||||
lookup the username, password and GrantedAuthority[]s. Unlike most of
|
||||
the other authentication providers that leverage UserDetailsService,
|
||||
this authentication provider actually requires the password to be
|
||||
presented, and the provider will actually evaluate the validity or
|
||||
otherwise of the password presented in an authentication request
|
||||
object.</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="dao-provider-config">
|
||||
<info><title>Configuration</title></info>
|
||||
|
||||
<para>Aside from adding DaoAuthenticationProvider to your
|
||||
ProviderManager list (as discussed at the start of this part of the
|
||||
reference guide), and ensuring a suitable authentication mechanism is
|
||||
configured to present a UsernamePasswordAuthenticationToken, the
|
||||
configuration of the provider itself is rather simple:</para>
|
||||
|
||||
<para><programlisting>
|
||||
<info>
|
||||
<title>DAO Authentication Provider</title>
|
||||
</info>
|
||||
<section xml:id="dao-provider-overview">
|
||||
<info>
|
||||
<title>Overview</title>
|
||||
</info>
|
||||
<para>Spring Security includes a production-quality
|
||||
<classname>AuthenticationProvider</classname> implementation called
|
||||
<literal>DaoAuthenticationProvider</literal>. This authentication provider is
|
||||
compatible with all of the authentication mechanisms that generate a
|
||||
<literal>UsernamePasswordAuthenticationToken</literal>, and is probably the most
|
||||
commonly used provider in the framework. Like most of the other authentication
|
||||
providers, the DaoAuthenticationProvider leverages a UserDetailsService in order to
|
||||
lookup the username, password and GrantedAuthority[]s. Unlike most of the other
|
||||
authentication providers that leverage UserDetailsService, this authentication provider
|
||||
actually requires the password to be presented, and the provider will actually evaluate
|
||||
the validity or otherwise of the password presented in an authentication request
|
||||
object.</para>
|
||||
</section>
|
||||
<section xml:id="dao-provider-config">
|
||||
<info>
|
||||
<title>Configuration</title>
|
||||
</info>
|
||||
<para>Aside from adding DaoAuthenticationProvider to your ProviderManager list (as discussed
|
||||
at the start of this part of the reference guide), and ensuring a suitable
|
||||
authentication mechanism is configured to present a UsernamePasswordAuthenticationToken,
|
||||
the configuration of the provider itself is rather simple:</para>
|
||||
<para>
|
||||
<programlisting>
|
||||
<![CDATA[
|
||||
<bean id="daoAuthenticationProvider"
|
||||
class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
|
||||
|
@ -38,38 +36,33 @@
|
|||
<property name="saltSource" ref bean="saltSource"/>
|
||||
<property name="passwordEncoder" ref="passwordEncoder"/>
|
||||
</bean> ]]>
|
||||
</programlisting></para>
|
||||
|
||||
<para>The <literal>PasswordEncoder</literal> and
|
||||
<literal>SaltSource</literal> are optional. A
|
||||
<literal>PasswordEncoder</literal> provides encoding and decoding of
|
||||
passwords presented in the <interfacename>UserDetails</interfacename> object that
|
||||
is returned from the configured <interfacename>UserDetailsService</interfacename>.
|
||||
A <literal>SaltSource</literal> enables the passwords to be populated
|
||||
with a "salt", which enhances the security of the passwords in the
|
||||
authentication repository. <literal>PasswordEncoder</literal>
|
||||
implementations are provided with Spring Security covering MD5, SHA
|
||||
and cleartext encodings. Two <literal>SaltSource</literal>
|
||||
implementations are also provided:
|
||||
<literal>SystemWideSaltSource</literal> which encodes all passwords
|
||||
with the same salt, and <literal>ReflectionSaltSource</literal>, which
|
||||
inspects a given property of the returned
|
||||
<interfacename>UserDetails</interfacename> object to obtain the salt. Please refer
|
||||
to the JavaDocs for further details on these optional features.</para>
|
||||
|
||||
<para>In addition to the properties above, the
|
||||
<literal>DaoAuthenticationProvider</literal> supports optional caching
|
||||
of <interfacename>UserDetails</interfacename> objects. The
|
||||
<literal>UserCache</literal> interface enables the
|
||||
<literal>DaoAuthenticationProvider</literal> to place a
|
||||
<interfacename>UserDetails</interfacename> object into the cache, and retrieve it
|
||||
from the cache upon subsequent authentication attempts for the same
|
||||
username. By default the <literal>DaoAuthenticationProvider</literal>
|
||||
uses the <literal>NullUserCache</literal>, which performs no caching.
|
||||
A usable caching implementation is also provided,
|
||||
<literal>EhCacheBasedUserCache</literal>, which is configured as
|
||||
follows:</para>
|
||||
<para><programlisting><![CDATA[
|
||||
</programlisting>
|
||||
</para>
|
||||
<para>The <literal>PasswordEncoder</literal> and <literal>SaltSource</literal> are optional.
|
||||
A <literal>PasswordEncoder</literal> provides encoding and decoding of passwords
|
||||
presented in the <interfacename>UserDetails</interfacename> object that is returned from
|
||||
the configured <interfacename>UserDetailsService</interfacename>. A
|
||||
<literal>SaltSource</literal> enables the passwords to be populated with a "salt",
|
||||
which enhances the security of the passwords in the authentication repository.
|
||||
<literal>PasswordEncoder</literal> implementations are provided with Spring Security
|
||||
covering MD5, SHA and cleartext encodings. Two <literal>SaltSource</literal>
|
||||
implementations are also provided: <literal>SystemWideSaltSource</literal> which encodes
|
||||
all passwords with the same salt, and <literal>ReflectionSaltSource</literal>, which
|
||||
inspects a given property of the returned <interfacename>UserDetails</interfacename>
|
||||
object to obtain the salt. Please refer to the JavaDocs for further details on these
|
||||
optional features.</para>
|
||||
<para>In addition to the properties above, the <literal>DaoAuthenticationProvider</literal>
|
||||
supports optional caching of <interfacename>UserDetails</interfacename> objects. The
|
||||
<literal>UserCache</literal> interface enables the
|
||||
<literal>DaoAuthenticationProvider</literal> to place a
|
||||
<interfacename>UserDetails</interfacename> object into the cache, and retrieve it
|
||||
from the cache upon subsequent authentication attempts for the same username. By default
|
||||
the <literal>DaoAuthenticationProvider</literal> uses the
|
||||
<literal>NullUserCache</literal>, which performs no caching. A usable caching
|
||||
implementation is also provided, <literal>EhCacheBasedUserCache</literal>, which is
|
||||
configured as follows:</para>
|
||||
<para>
|
||||
<programlisting><![CDATA[
|
||||
<bean id="daoAuthenticationProvider"
|
||||
class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
|
||||
<property name="userDetailsService" ref="userDetailsService"/>
|
||||
|
@ -89,42 +82,19 @@
|
|||
class="org.springframework.security.core.userdetails.cache.EhCacheBasedUserCache">
|
||||
<property name="cache" ref="userCacheBackend"/>
|
||||
</bean>]]>
|
||||
</programlisting></para>
|
||||
|
||||
<para>All Spring Security EH-CACHE implementations (including
|
||||
<literal>EhCacheBasedUserCache</literal>) require an EH-CACHE
|
||||
<literal>Cache</literal> object. The <literal>Cache</literal> object
|
||||
can be obtained from wherever you like, although we recommend you use
|
||||
Spring's factory classes as shown in the above configuration. If using
|
||||
Spring's factory classes, please refer to the Spring documentation for
|
||||
further details on how to optimise the cache storage location, memory
|
||||
usage, eviction policies, timeouts etc.</para>
|
||||
<note><para>In the majority of cases, where your application is a stateful web
|
||||
application, you don't need to use a cache as the user's authentication
|
||||
information will be stored in the <literal>HttpSession</literal>.
|
||||
</para></note>
|
||||
|
||||
<para>A design decision was made not to support account locking in the
|
||||
<literal>DaoAuthenticationProvider</literal>, as doing so would have
|
||||
increased the complexity of the <interfacename>UserDetailsService</interfacename>
|
||||
interface. For instance, a method would be required to increase the
|
||||
count of unsuccessful authentication attempts. Such functionality
|
||||
could be easily provided by leveraging the application event
|
||||
publishing features discussed below.</para>
|
||||
|
||||
<para><literal>DaoAuthenticationProvider</literal> returns an
|
||||
<interfacename>Authentication</interfacename> object which in turn has its
|
||||
<literal>principal</literal> property set. The principal will be
|
||||
either a <literal>String</literal> (which is essentially the username)
|
||||
or a <interfacename>UserDetails</interfacename> object (which was looked up from
|
||||
the <interfacename>UserDetailsService</interfacename>). By default the
|
||||
<interfacename>UserDetails</interfacename> is returned, as this enables
|
||||
applications to add extra properties potentially of use in
|
||||
applications, such as the user's full name, email address etc. If
|
||||
using container adapters, or if your applications were written to
|
||||
operate with <literal>String</literal>s (as was the case for releases
|
||||
prior to Spring Security 0.6), you should set the
|
||||
<literal>DaoAuthenticationProvider.forcePrincipalAsString</literal>
|
||||
property to <literal>true</literal> in your application context</para>
|
||||
</section>
|
||||
</chapter>
|
||||
</programlisting>
|
||||
</para>
|
||||
<para>All Spring Security EH-CACHE implementations (including
|
||||
<literal>EhCacheBasedUserCache</literal>) require an EH-CACHE
|
||||
<literal>Cache</literal> object. The <literal>Cache</literal> object can be obtained
|
||||
from wherever you like, although we recommend you use Spring's factory classes as shown
|
||||
in the above configuration. If using Spring's factory classes, please refer to the
|
||||
Spring documentation for further details on how to optimise the cache storage location,
|
||||
memory usage, eviction policies, timeouts etc.</para>
|
||||
<note>
|
||||
<para>In the majority of cases, where your application is a stateful web application,
|
||||
you don't need to use a cache as the user's authentication information will be
|
||||
stored in the <literal>HttpSession</literal>. </para>
|
||||
</note>
|
||||
</section>
|
||||
</chapter>
|
||||
|
|
|
@ -113,7 +113,7 @@
|
|||
<section xml:id="ns-web-xml">
|
||||
<title><literal>web.xml</literal> Configuration</title>
|
||||
<para> The first thing you need to do is add the following filter declaration to your
|
||||
<literal>web.xml</literal> file: <programlisting language="xml"><![CDATA[
|
||||
<literal>web.xml</literal> file: <programlisting language="xml"><![CDATA[
|
||||
<filter>
|
||||
<filter-name>springSecurityFilterChain</filter-name>
|
||||
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
|
||||
|
@ -277,7 +277,7 @@
|
|||
containing the standard Spring Security <link xlink:href="#db_schema_users_authorities">user
|
||||
data tables</link>. Alternatively, you could configure a Spring Security
|
||||
<classname>JdbcDaoImpl</classname> bean and point at that using the
|
||||
<literal>user-service-ref</literal> attribute: <programlisting language="xml"><![CDATA[
|
||||
<literal>user-service-ref</literal> attribute: <programlisting language="xml"><![CDATA[
|
||||
<authentication-provider user-service-ref='myUserDetailsService'/>
|
||||
|
||||
<beans:bean id="myUserDetailsService"
|
||||
|
@ -332,7 +332,7 @@
|
|||
<title>Adding HTTP/HTTPS Channel Security</title>
|
||||
<para>If your application supports both HTTP and HTTPS, and you require that particular URLs
|
||||
can only be accessed over HTTPS, then this is directly supported using the
|
||||
<literal>requires-channel</literal> attribute on <literal><intercept-url></literal>: <programlisting language="xml"><![CDATA[
|
||||
<literal>requires-channel</literal> attribute on <literal><intercept-url></literal>: <programlisting language="xml"><![CDATA[
|
||||
<http>
|
||||
<intercept-url pattern="/secure/**" access="ROLE_USER" requires-channel="https"/>
|
||||
<intercept-url pattern="/**" access="ROLE_USER" requires-channel="any"/>
|
||||
|
@ -406,14 +406,21 @@
|
|||
version of a standard namespace filter, such as the
|
||||
<literal>UsernamePasswordAuthenticationProcessingFilter</literal> which is created by the
|
||||
<literal><form-login></literal> element, taking advantage of some of the extra
|
||||
configuration options which are available by using defining the bean directly. How can you
|
||||
do this with namespace configuration, since the filter chain is not directly exposed? </para>
|
||||
<para>The order of the filters is always strictly enforced when using the namespace. Each
|
||||
Spring Security filter implements the Spring <interfacename>Ordered</interfacename>
|
||||
interface and the filters created by the namespace are sorted during initialization. The
|
||||
standard Spring Security filters each have an alias in the namespace. The filters, aliases
|
||||
and namespace elements/attributes which create the filters are shown in <xref
|
||||
linkend="filter-stack"/>. <table xml:id="filter-stack">
|
||||
configuration options which are available by using the bean explicitly. How can you do this
|
||||
with namespace configuration, since the filter chain is not directly exposed? </para>
|
||||
<para>The order of the filters is always strictly enforced when using the namespace. When the
|
||||
application context is being created, the filter beans are sorted by the namespace handling
|
||||
code and the standard Spring Security filters each have an alias in the namespace and a
|
||||
well-known position.<note>
|
||||
<para>In previous versions, the sorting took place after the filter instances had been
|
||||
created, during post-processing of the application context. In version 3.0+ the sorting
|
||||
is now done at the bean metadata level, before the classes have been instantiated. This
|
||||
has implications for how you add your own filters to the stack as the entire filter list
|
||||
must be known during the parsing of the <literal><http></literal> element, so the
|
||||
syntax has changed slightly in 3.0.</para>
|
||||
</note>The filters, aliases and namespace elements/attributes which create the filters are
|
||||
shown in <xref linkend="filter-stack"/>. The filters are listed in the order in which they
|
||||
occur in the filter chain. <table xml:id="filter-stack">
|
||||
<title>Standard Filter Aliases and Ordering</title>
|
||||
<tgroup cols="3" align="left">
|
||||
<thead>
|
||||
|
@ -510,10 +517,13 @@
|
|||
</table> You can add your own filter to the stack, using the
|
||||
<literal>custom-filter</literal> element and one of these names to specify the position
|
||||
your filter should appear at: <programlisting language="xml"><![CDATA[
|
||||
<beans:bean id="myFilter" class="com.mycompany.MySpecialAuthenticationFilter">
|
||||
<custom-filter position="AUTHENTICATION_PROCESSING_FILTER"/>
|
||||
</beans:bean>
|
||||
]]></programlisting> You can also use the <literal>after</literal> or <literal>before</literal>
|
||||
<http>
|
||||
<custom-filter position="AUTHENTICATION_PROCESSING_FILTER" ref="myFilter" />
|
||||
</http>
|
||||
|
||||
<beans:bean id="myFilter" class="com.mycompany.MySpecialAuthenticationFilter"/>
|
||||
]]>
|
||||
</programlisting> You can also use the <literal>after</literal> or <literal>before</literal>
|
||||
attributes if you want your filter to be inserted before or after another filter in the
|
||||
stack. The names "FIRST" and "LAST" can be used with the <literal>position</literal>
|
||||
attribute to indicate that you want your filter to appear before or after the entire stack,
|
||||
|
@ -575,12 +585,12 @@
|
|||
</section>
|
||||
<section xml:id="ns-method-security">
|
||||
<title>Method Security</title>
|
||||
<para>From version 2.0 onwards Spring Security has improved support substantially for adding security to your
|
||||
service layer methods. It provides support for JSR-250 security
|
||||
as well as the framework's native <literal>@Secured</literal>
|
||||
annotation. You can apply security to a single bean, using the
|
||||
<literal>intercept-methods</literal> element to decorate the bean declaration, or you can
|
||||
secure multiple beans across the entire service layer using the AspectJ style pointcuts. </para>
|
||||
<para>From version 2.0 onwards Spring Security has improved support substantially for adding
|
||||
security to your service layer methods. It provides support for JSR-250 security as well as
|
||||
the framework's native <literal>@Secured</literal> annotation. You can apply security to a
|
||||
single bean, using the <literal>intercept-methods</literal> element to decorate the bean
|
||||
declaration, or you can secure multiple beans across the entire service layer using the
|
||||
AspectJ style pointcuts. </para>
|
||||
<section xml:id="ns-global-method">
|
||||
<title>The <literal><global-method-security></literal> Element</title>
|
||||
<para> This element is used to enable annotation-based security in your application (by
|
||||
|
@ -664,7 +674,7 @@
|
|||
<para> For method security, you do this by setting the
|
||||
<literal>access-decision-manager-ref</literal> attribute on
|
||||
<literal>global-method-security</literal>to the Id of the appropriate
|
||||
<interfacename>AccessDecisionManager</interfacename> bean in the application context: <programlisting language="xml"><![CDATA[
|
||||
<interfacename>AccessDecisionManager</interfacename> bean in the application context: <programlisting language="xml"><![CDATA[
|
||||
<global-method-security access-decision-manager-ref="myAccessDecisionManagerBean">
|
||||
...
|
||||
</global-method-security>
|
||||
|
@ -681,8 +691,9 @@
|
|||
<para> We've touched on the idea that the namespace configuration automatically registers an
|
||||
authentication manager bean for you. This is an instance of Spring Security's
|
||||
<classname>ProviderManager</classname> class, which you may already be familiar with if
|
||||
you've used the framework before. If not, it will be covered later, in <link xlink:href="#tech-intro-authentication"/>.
|
||||
You can't use a custom <classname>AuthenticationManager</classname> if you are using either HTTP or method security
|
||||
you've used the framework before. If not, it will be covered later, in <link
|
||||
xlink:href="#tech-intro-authentication"/>. You can't use a custom
|
||||
<classname>AuthenticationManager</classname> if you are using either HTTP or method security
|
||||
through the namespace, but this should not be a problem as you have full control over the
|
||||
<classname>AuthenticationProvider</classname>s that are used. </para>
|
||||
<para> You may want to register additional <classname>AuthenticationProvider</classname> beans
|
||||
|
|
|
@ -115,7 +115,9 @@
|
|||
<xi:include href="basic-and-digest-auth.xml"/>
|
||||
<xi:include href="remember-me-authentication.xml"/>
|
||||
<xi:include href="concurrent-sessions.xml"/>
|
||||
<xi:include href="anon-auth-provider.xml"/>
|
||||
</part>
|
||||
<!--
|
||||
<part xml:id="authentication">
|
||||
<title>Authentication</title>
|
||||
<partintro>
|
||||
|
@ -138,9 +140,8 @@
|
|||
</footnote>. </para>
|
||||
</partintro>
|
||||
<xi:include href="dao-auth-provider.xml"/>
|
||||
<xi:include href="anon-auth-provider.xml"/>
|
||||
<xi:include href="runas-auth-provider.xml"/>
|
||||
</part>
|
||||
-->
|
||||
<part xml:id="authorization">
|
||||
<title>Authorization</title>
|
||||
<partintro>
|
||||
|
@ -164,7 +165,7 @@
|
|||
Essentially standalone features which do not have to follow on directly from earlier chapters
|
||||
-->
|
||||
<partintro>
|
||||
<para> In this part we cover some of the more advanced features of the framework. </para>
|
||||
<para> In this part we cover some of the more advanced and less-commonly used features of the framework.</para>
|
||||
</partintro>
|
||||
<xi:include href="domain-acls.xml"/>
|
||||
<xi:include href="preauth.xml"/>
|
||||
|
@ -172,6 +173,7 @@
|
|||
<xi:include href="jaas-auth-provider.xml"/>
|
||||
<xi:include href="cas-auth-provider.xml"/>
|
||||
<xi:include href="x509-auth-provider.xml"/>
|
||||
<xi:include href="runas-auth-provider.xml"/>
|
||||
</part>
|
||||
<xi:include href="appendix-db-schema.xml"/>
|
||||
<xi:include href="appendix-namespace.xml"/>
|
||||
|
|
|
@ -28,8 +28,8 @@
|
|||
web-application security, LDAP or namespace configuration. We'll take a look here at some of
|
||||
the Java types that you'll find in the core module. They represent the building blocks of the
|
||||
the framework, so if you ever need to go beyond a simple namespace configuration then it's
|
||||
important that you understand what they are, even if you don't actually need to directly
|
||||
interact with them.</para>
|
||||
important that you understand what they are, even if you don't actually need to interact with
|
||||
them directly.</para>
|
||||
<section>
|
||||
<title> SecurityContextHolder, SecurityContext and Authentication Objects </title>
|
||||
<para>The most fundamental object is <classname>SecurityContextHolder</classname>. This is
|
||||
|
@ -44,13 +44,15 @@
|
|||
no need to worry about it.</para>
|
||||
<para>Some applications aren't entirely suitable for using a <literal>ThreadLocal</literal>,
|
||||
because of the specific way they work with threads. For example, a Swing client might want
|
||||
all threads in a Java Virtual Machine to use the same security context. For this situation
|
||||
you would use the <literal>SecurityContextHolder.MODE_GLOBAL</literal>. Other applications
|
||||
might want to have threads spawned by the secure thread also assume the same security
|
||||
identity. This is achieved by using
|
||||
all threads in a Java Virtual Machine to use the same security context.
|
||||
<classname>SecurityContextHolder</classname> can be configured with a strategy on startup
|
||||
to specify how you would like the contex to be stored. For a standalone application you
|
||||
would use the <literal>SecurityContextHolder.MODE_GLOBAL</literal> strategy. Other
|
||||
applications might want to have threads spawned by the secure thread also assume the same
|
||||
security identity. This is achieved by using
|
||||
<literal>SecurityContextHolder.MODE_INHERITABLETHREADLOCAL</literal>. You can change the
|
||||
mode from the default <literal>SecurityContextHolder.MODE_THREADLOCAL</literal> in two ways.
|
||||
The first is to set a system property. Alternatively, call a static method on
|
||||
The first is to set a system property, the second is to call a static method on
|
||||
<classname>SecurityContextHolder</classname>. Most applications won't need to change from
|
||||
the default, but if you do, take a look at the JavaDocs for
|
||||
<classname>SecurityContextHolder</classname> to learn more.</para>
|
||||
|
@ -74,9 +76,9 @@ if (principal instanceof UserDetails) {
|
|||
}</programlisting>
|
||||
<para>The object returned by the call to <methodname>getContext()</methodname> is an
|
||||
instance of the <interfacename>SecurityContext</interfacename> interface. This is the
|
||||
object that is kept in thread-local storage. Most authentication mechanisms withing Spring
|
||||
Security return an instance of <interfacename>UserDetails</interfacename> as the principal
|
||||
as we'll see below. </para>
|
||||
object that is kept in thread-local storage. As we'll see below, Most authentication
|
||||
mechanisms withing Spring Security return an instance of
|
||||
<interfacename>UserDetails</interfacename> as the principal. </para>
|
||||
</section>
|
||||
</section>
|
||||
<section>
|
||||
|
@ -109,15 +111,15 @@ if (principal instanceof UserDetails) {
|
|||
<para> On successful authentication, <interfacename>UserDetails</interfacename> is used to
|
||||
build the <interfacename>Authentication</interfacename> object that is stored in the
|
||||
<classname>SecurityContextHolder</classname> (more on this <link
|
||||
xlink:href="#tech-intro-authentication-mgr">below</link>). The good news is that we provide a
|
||||
number of <interfacename>UserDetailsService</interfacename> implementations, including one
|
||||
that uses an in-memory map (<classname>InMemoryDaoImpl</classname>) and another that uses
|
||||
JDBC (<interfacename>JdbcDaoImpl</interfacename>). Most users tend to write their own,
|
||||
though, with their implementations often simply sitting on top of an existing Data Access
|
||||
Object (DAO) that represents their employees, customers, or other users of the application.
|
||||
Remember the advantage that whatever your <interfacename>UserDetailsService</interfacename>
|
||||
returns can always be obtained from the <classname>SecurityContextHolder</classname> using
|
||||
the above code fragment. </para>
|
||||
xlink:href="#tech-intro-authentication-mgr">below</link>). The good news is that we
|
||||
provide a number of <interfacename>UserDetailsService</interfacename> implementations,
|
||||
including one that uses an in-memory map (<classname>InMemoryDaoImpl</classname>) and
|
||||
another that uses JDBC (<interfacename>JdbcDaoImpl</interfacename>). Most users tend to
|
||||
write their own, though, with their implementations often simply sitting on top of an
|
||||
existing Data Access Object (DAO) that represents their employees, customers, or other users
|
||||
of the application. Remember the advantage that whatever your
|
||||
<interfacename>UserDetailsService</interfacename> returns can always be obtained from the
|
||||
<classname>SecurityContextHolder</classname> using the above code fragment. </para>
|
||||
</section>
|
||||
<section xml:id="tech-granted-authority">
|
||||
<title>GrantedAuthority</title>
|
||||
|
@ -321,10 +323,8 @@ Successfully authenticated. Security context contains: \
|
|||
(or equivalent) that reads the third-party user information from a location, build a
|
||||
Spring Security-specific <interfacename>Authentication</interfacename> object, and put it
|
||||
onto the <classname>SecurityContextHolder</classname>.</para>
|
||||
<para>
|
||||
If you're wondering how the <interfacename>AuthenticationManager</interfacename>
|
||||
manager is implemented in a real world example, we'll look at that in
|
||||
</para>
|
||||
<para> If you're wondering how the <interfacename>AuthenticationManager</interfacename>
|
||||
manager is implemented in a real world example, we'll look at that in </para>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
|
@ -511,10 +511,11 @@ Successfully authenticated. Security context contains: \
|
|||
<title>What are Configuration Attributes?</title>
|
||||
<para> A <quote>configuration attribute</quote> can be thought of as a String that has
|
||||
special meaning to the classes used by <classname>AbstractSecurityInterceptor</classname>.
|
||||
They are represented by the interface <interfacename>ConfigAttribute</interfacename> within
|
||||
the framework. They may be simple role names or have more complex meaning, depending on the how
|
||||
sophisticated the <interfacename>AccessDecisionManager</interfacename> implementation is.
|
||||
The <classname>AbstractSecurityInterceptor</classname> is configured with a
|
||||
They are represented by the interface <interfacename>ConfigAttribute</interfacename>
|
||||
within the framework. They may be simple role names or have more complex meaning,
|
||||
depending on the how sophisticated the
|
||||
<interfacename>AccessDecisionManager</interfacename> implementation is. The
|
||||
<classname>AbstractSecurityInterceptor</classname> is configured with a
|
||||
<interfacename>SecurityMetadataSource</interfacename> which it uses to look up the
|
||||
attributes for a secure object. Usually this configuration will be hidden from the user.
|
||||
Configuration attributes will be entered as annotations on secured methods, or as access
|
||||
|
|
Loading…
Reference in New Issue