Updated docs to reflect changes for SEC-1259

This commit is contained in:
Luke Taylor 2009-10-08 14:14:40 +00:00
parent 80eb47c6fe
commit 73905b9ebd
10 changed files with 543 additions and 623 deletions

View File

@ -47,16 +47,17 @@
principal. There is a corresponding <literal>AnonymousAuthenticationProvider</literal>, principal. There is a corresponding <literal>AnonymousAuthenticationProvider</literal>,
which is chained into the <literal>ProviderManager</literal> so that which is chained into the <literal>ProviderManager</literal> so that
<literal>AnonymousAuthenticationToken</literal>s 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 <classname>AnonymousAuthenticationFilter</classname>, which is chained after the
and automatically adds an <literal>AnonymousAuthenticationToken</literal> to the normal authentication mechanisms and automatically adds an
<literal>AnonymousAuthenticationToken</literal> to the
<classname>SecurityContextHolder</classname> if there is no existing <classname>SecurityContextHolder</classname> if there is no existing
<interfacename>Authentication</interfacename> held there. The definition of the <interfacename>Authentication</interfacename> held there. The definition of the
filter and authentication provider appears as follows:</para> filter and authentication provider appears as follows:</para>
<para> <para>
<programlisting> <programlisting>
<![CDATA[ <![CDATA[
<bean id="anonymousProcessingFilter" <bean id="anonymousAuthFilter"
class="org.springframework.security.web.authentication.AnonymousProcessingFilter"> class="org.springframework.security.web.authentication.AnonymousAuthenticationFilter">
<property name="key" value="foobar"/> <property name="key" value="foobar"/>
<property name="userAttribute" value="anonymousUser,ROLE_ANONYMOUS"/> <property name="userAttribute" value="anonymousUser,ROLE_ANONYMOUS"/>
</bean> </bean>
@ -68,10 +69,10 @@
</programlisting> </programlisting>
</para> </para>
<para>The <literal>key</literal> is shared between the filter and authentication provider, <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<footnote> so that tokens created by the former are accepted by the latter<footnote><para>The use
<para>The use of the <literal>key</literal> property should not be regarded as of the <literal>key</literal> property should not be regarded as providing any
providing any real security here. It is merely a book-keeping exercise. If you real security here. It is merely a book-keeping exercise. If you are sharing a
are sharing a <classname>ProviderManager</classname> which contains an <classname>ProviderManager</classname> which contains an
<classname>AnonymousAuthenticationProvider</classname> in a scenario where <classname>AnonymousAuthenticationProvider</classname> in a scenario where
it is possible for an authenticating client to construct the it is possible for an authenticating client to construct the
<interfacename>Authentication</interfacename> object (such as with RMI <interfacename>Authentication</interfacename> object (such as with RMI
@ -82,14 +83,15 @@
anonymous provider. This isn't a problem with normal usage but if you are using 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> 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 which omits the anonymous provider rather than sharing the one you use for your
HTTP authentication mechanisms.</para> HTTP authentication mechanisms.</para></footnote>. The
</footnote>. The <literal>userAttribute</literal> is expressed in the form of <literal>userAttribute</literal> is expressed in the form of
<literal>usernameInTheAuthenticationToken,grantedAuthority[,grantedAuthority]</literal>. <literal>usernameInTheAuthenticationToken,grantedAuthority[,grantedAuthority]</literal>.
This is the same syntax as used after the equals sign for This is the same syntax as used after the equals sign for
<literal>InMemoryDaoImpl</literal>'s <literal>userMap</literal> property.</para> <literal>InMemoryDaoImpl</literal>'s <literal>userMap</literal> property.</para>
<para>As explained earlier, the benefit of anonymous authentication is that all URI patterns <para>As explained earlier, the benefit of anonymous authentication is that all URI patterns
can have security applied to them. For example:</para> can have security applied to them. For example:</para>
<para><programlisting> <para>
<programlisting>
<![CDATA[ <![CDATA[
<bean id="filterSecurityInterceptor" <bean id="filterSecurityInterceptor"
class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor"> class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
@ -105,31 +107,29 @@
</security:filter-security-metadata-source>" + </security:filter-security-metadata-source>" +
</property> </property>
</bean>]]> </bean>]]>
</programlisting></para> </programlisting>
</para>
</section> </section>
<section xml:id="anonymous-auth-trust-resolver"> <section xml:id="anonymous-auth-trust-resolver">
<title><interfacename>AuthenticationTrustResolver</interfacename></title> <title><interfacename>AuthenticationTrustResolver</interfacename></title>
<para> <para> Rounding out the anonymous authentication discussion is the
Rounding out the anonymous authentication discussion is the <interfacename>AuthenticationTrustResolver</interfacename> interface, with its
<interfacename>AuthenticationTrustResolver</interfacename> interface, with its corresponding corresponding <literal>AuthenticationTrustResolverImpl</literal> implementation. This
<literal>AuthenticationTrustResolverImpl</literal> implementation. This interface interface provides an <literal>isAnonymous(Authentication)</literal> method, which
provides an <literal>isAnonymous(Authentication)</literal> method, which allows allows interested classes to take into account this special type of authentication
interested classes to take into account this special type of authentication status. The status. The <classname>ExceptionTranslationFilter</classname> uses this interface in
<classname>ExceptionTranslationFilter</classname> uses this interface in processing processing <literal>AccessDeniedException</literal>s. If an
<literal>AccessDeniedException</literal>s. If an <literal>AccessDeniedException</literal> is thrown, and the authentication is of 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 anonymous type, instead of throwing a 403 (forbidden) response, the filter will instead
commence the <interfacename>AuthenticationEntryPoint</interfacename> so the principal commence the <interfacename>AuthenticationEntryPoint</interfacename> so the principal
can authenticate properly. This is a necessary distinction, otherwise principals would can authenticate properly. This is a necessary distinction, otherwise principals would
always be deemed <quote>authenticated</quote> and never be given an opportunity to login always be deemed <quote>authenticated</quote> and never be given an opportunity to login
via form, basic, digest or some other normal authentication mechanism. via form, basic, digest or some other normal authentication mechanism. </para>
</para> <para> You will often see the <literal>ROLE_ANONYMOUS</literal> attribute in the above
<para> interceptor configuration replaced with <literal>IS_AUTHENTICATED_ANONYMOUSLY</literal>.
You will often see the <literal>ROLE_ANONYMOUS</literal> attribute in the above interceptor configuration This is an example of the use of the <classname>AuthenticatedVoter</classname> which
replaced with <literal>IS_AUTHENTICATED_ANONYMOUSLY</literal>. This is an example of the use of the will see in ???. It uses an <interfacename>AuthenticationTrustResolver</interfacename>
<classname>AuthenticatedVoter</classname> which will see in ???. It uses an to process this particular configuration attribute and grant access to aonymous users.
<interfacename>AuthenticationTrustResolver</interfacename> to process this particular configuration
attribute and grant access to aonymous users.
</para> </para>
</section> </section>
</chapter> </chapter>

View File

@ -62,7 +62,7 @@
<title><literal>realm</literal></title> <title><literal>realm</literal></title>
<para> Sets the realm name used for basic authentication (if enabled). Corresponds to the <para> Sets the realm name used for basic authentication (if enabled). Corresponds to the
<literal>realmName</literal> proerty on <literal>realmName</literal> proerty on
<classname>BasicProcessingFilterEntryPoint</classname>. </para> <classname>BasicAuthenticationEntryPoint</classname>. </para>
</section> </section>
<section xml:id="nsa-entry-point-ref"> <section xml:id="nsa-entry-point-ref">
<title><literal>entry-point-ref</literal></title> <title><literal>entry-point-ref</literal></title>
@ -123,7 +123,7 @@
<interfacename>FilterInvocationDefinitionSource</interfacename> used by the <interfacename>FilterInvocationDefinitionSource</interfacename> used by the
<classname>FilterSecurityInterceptor</classname> and to exclude particular patterns from <classname>FilterSecurityInterceptor</classname> and to exclude particular patterns from
the filter chain entirely (by setting the attribute <literal>filters="none"</literal>). It the filter chain entirely (by setting the attribute <literal>filters="none"</literal>). It
is also responsible for configuring a <classname>ChannelProcessingFilter</classname> if is also responsible for configuring a <classname>ChannelAuthenticationFilter</classname> if
particular URLs need to be accessed by HTTPS, for example. </para> particular URLs need to be accessed by HTTPS, for example. </para>
<section xml:id="nsa-pattern"> <section xml:id="nsa-pattern">
<title><literal>pattern</literal></title> <title><literal>pattern</literal></title>
@ -149,8 +149,8 @@
accessed over HTTP or HTTPS respectively. Alternatively the value "any" can be used when accessed over HTTP or HTTPS respectively. Alternatively the value "any" can be used when
there is no preference. If this attribute is present on any there is no preference. If this attribute is present on any
<literal>&lt;intercept-url&gt;</literal> element, then a <literal>&lt;intercept-url&gt;</literal> element, then a
<classname>ChannelProcessingFilter</classname> will be added to the filter stack and its <classname>ChannelAuthenticationFilter</classname> will be added to the filter stack and
additional dependencies added to the application context. its additional dependencies added to the application context.
<!--See the chapter on <link <!--See the chapter on <link
xlink:href="#channel-security-config">channel security</link> for an example xlink:href="#channel-security-config">channel security</link> for an example
configuration using traditional beans. --></para> configuration using traditional beans. --></para>
@ -237,15 +237,14 @@
</section> </section>
<section xml:id="nsa-http-basic"> <section xml:id="nsa-http-basic">
<title>The <literal>&lt;http-basic&gt;</literal> Element</title> <title>The <literal>&lt;http-basic&gt;</literal> Element</title>
<para> Adds a <classname>BasicProcessingFilter</classname> and <para> Adds a <classname>BasicAuthenticationFilter</classname> and
<classname>BasicProcessingFilterEntryPoint</classname> to the configuration. The latter <classname>BasicAuthenticationEntryPoint</classname> to the configuration. The latter will
will only be used as the configuration entry point if form-based login is not enabled. only be used as the configuration entry point if form-based login is not enabled. </para>
</para>
</section> </section>
<section xml:id="nsa-remember-me"> <section xml:id="nsa-remember-me">
<title>The <literal>&lt;remember-me&gt;</literal> Element</title> <title>The <literal>&lt;remember-me&gt;</literal> Element</title>
<para> Adds the <classname>RememberMeProcessingFilter</classname> to the stack. This in turn <para> Adds the <classname>RememberMeAuthenticationFilter</classname> to the stack. This in
will be configured with either a <classname>TokenBasedRememberMeServices</classname>, a turn will be configured with either a <classname>TokenBasedRememberMeServices</classname>, a
<classname>PersistentTokenBasedRememberMeServices</classname> or a user-specified bean <classname>PersistentTokenBasedRememberMeServices</classname> or a user-specified bean
implementing <interfacename>RememberMeServices</interfacename> depending on the attribute implementing <interfacename>RememberMeServices</interfacename> depending on the attribute
settings. </para> settings. </para>
@ -354,17 +353,17 @@
</section> </section>
<section xml:id="nsa-anonymous"> <section xml:id="nsa-anonymous">
<title>The <literal>&lt;anonymous&gt;</literal> Element</title> <title>The <literal>&lt;anonymous&gt;</literal> Element</title>
<para> Adds an <classname>AnonymousProcessingFilter</classname> to the stack and an <para> Adds an <classname>AnonymousAuthenticationFilter</classname> to the stack and an
<classname>AnonymousAuthenticationProvider</classname>. Required if you are using the <classname>AnonymousAuthenticationProvider</classname>. Required if you are using the
<literal>IS_AUTHENTICATED_ANONYMOUSLY</literal> attribute. </para> <literal>IS_AUTHENTICATED_ANONYMOUSLY</literal> attribute. </para>
</section> </section>
<section xml:id="nsa-x509"> <section xml:id="nsa-x509">
<title>The <literal>&lt;x509&gt;</literal> Element</title> <title>The <literal>&lt;x509&gt;</literal> Element</title>
<para> Adds support for X.509 authentication. An <para> Adds support for X.509 authentication. An
<classname>X509PreAuthenticatedProcessingFilter</classname> will be added to the stack and <classname>X509AuthenticationFilter</classname> will be added to the stack and an
a <classname>PreAuthenticatedProcessingFilterEntryPoint</classname> bean will be created. <classname>Http403ForbiddenEntryPoint</classname> bean will be created. The latter will
The latter will only be used if no other authentication mechanisms are in use (it's only only be used if no other authentication mechanisms are in use (it's only functionality is to
functionality is to return an HTTP 403 error code). A return an HTTP 403 error code). A
<classname>PreAuthenticatedAuthenticationProvider</classname> will also be created which <classname>PreAuthenticatedAuthenticationProvider</classname> will also be created which
delegates the loading of user authorities to a delegates the loading of user authorities to a
<interfacename>UserDetailsService</interfacename>. </para> <interfacename>UserDetailsService</interfacename>. </para>

View File

@ -4,20 +4,21 @@
</info> </info>
<para>Basic and digest authentiation are alternative authentication mechanisms which are popular <para>Basic and digest authentiation are alternative authentication mechanisms which are popular
in web applications. Basic authentication is often used with stateless clients which pass in web applications. Basic authentication is often used with stateless clients which pass
their credentials on each request. It's quite common to use it in combination with form-based their credentials on each request. It's quite common to use it in combination with
authentication where an application is used through both a browser-based user interface form-based authentication where an application is used through both a browser-based user
and as a web-service. However, basic authentication transmits the password as plain text so it interface and as a web-service. However, basic authentication transmits the password as
should only really be used over an encrypted transport layer such as HTTPS.</para> plain text so it should only really be used over an encrypted transport layer such as
HTTPS.</para>
<section xml:id="basic-processing-filter"> <section xml:id="basic-processing-filter">
<info> <info>
<title><classname>BasicProcessingFilter</classname></title> <title><classname>BasicAuthenticationFilter</classname></title>
</info> </info>
<para><literal>BasicProcessingFilter</literal> is responsible for processing basic <para><literal>BasicAuthenticationFilter</literal> is responsible for processing basic
authentication credentials presented in HTTP headers. This can be used for authentication credentials presented in HTTP headers. This can be used for
authenticating calls made by Spring remoting protocols (such as Hessian and Burlap), as authenticating calls made by Spring remoting protocols (such as Hessian and Burlap), as
well as normal browser user agents (such as Firefox and Internet Explorer). The standard well as normal browser user agents (such as Firefox and Internet Explorer). The standard
governing HTTP Basic Authentication is defined by RFC 1945, Section 11, and governing HTTP Basic Authentication is defined by RFC 1945, Section 11, and
<literal>BasicProcessingFilter</literal> conforms with this RFC. Basic <literal>BasicAuthenticationFilter</literal> conforms with this RFC. Basic
Authentication is an attractive approach to authentication, because it is very widely Authentication is an attractive approach to authentication, because it is very widely
deployed in user agents and implementation is extremely simple (it's just a Base64 deployed in user agents and implementation is extremely simple (it's just a Base64
encoding of the username:password, specified in an HTTP header).</para> encoding of the username:password, specified in an HTTP header).</para>
@ -26,51 +27,50 @@
<title>Configuration</title> <title>Configuration</title>
</info> </info>
<para>To implement HTTP Basic Authentication, you need to add a <para>To implement HTTP Basic Authentication, you need to add a
<literal>BasicProcessingFilter</literal> to your filter chain. The application <literal>BasicAuthenticationFilter</literal> to your filter chain. The
context should contain <literal>BasicProcessingFilter</literal> and its application context should contain <literal>BasicAuthenticationFilter</literal> and
required collaborator:</para> its required collaborator:</para>
<para> <para>
<programlisting language="xml"><![CDATA[ <programlisting language="xml"><![CDATA[
<bean id="basicProcessingFilter" <bean id="basicAuthenticationFilter"
class="org.springframework.security.web.authentication.www.BasicProcessingFilter"> class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager"/> <property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationEntryPoint" ref="authenticationEntryPoint"/> <property name="authenticationEntryPoint" ref="authenticationEntryPoint"/>
</bean> </bean>
<bean id="authenticationEntryPoint" <bean id="authenticationEntryPoint"
class="org.springframework.security.web.authentication.www.BasicProcessingFilterEntryPoint"> class="org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint">
<property name="realmName" value="Name Of Your Realm"/> <property name="realmName" value="Name Of Your Realm"/>
</bean>]]> </bean>]]>
</programlisting> </programlisting>
</para> </para>
<para>The configured <interfacename>AuthenticationManager</interfacename> processes each <para>The configured <interfacename>AuthenticationManager</interfacename> processes each
authentication request. If authentication fails, the configured authentication request. If authentication fails, the configured
<interfacename>AuthenticationEntryPoint</interfacename> will be used to retry the <interfacename>AuthenticationEntryPoint</interfacename> will be used to retry
authentication process. Usually you will use the filter in combination with a the authentication process. Usually you will use the filter in combination with a
<literal>BasicProcessingFilterEntryPoint</literal>, which returns a 401 response <literal>BasicAuthenticationEntryPoint</literal>, which returns a 401 response
with a suitable header to retry HTTP Basic authentication. If authentication is with a suitable header to retry HTTP Basic authentication. If authentication is
successful, the resulting <interfacename>Authentication</interfacename> object will be successful, the resulting <interfacename>Authentication</interfacename> object will
placed into the <classname>SecurityContextHolder</classname> as usual.</para> be placed into the <classname>SecurityContextHolder</classname> as usual.</para>
<para>If the authentication event was successful, or authentication was not attempted <para>If the authentication event was successful, or authentication was not attempted
because the HTTP header did not contain a supported authentication request, the filter because the HTTP header did not contain a supported authentication request, the
chain will continue as normal. The only time the filter chain will be interrupted is if filter chain will continue as normal. The only time the filter chain will be
authentication fails and the <interfacename>AuthenticationEntryPoint</interfacename> is interrupted is if authentication fails and the
called.</para> <interfacename>AuthenticationEntryPoint</interfacename> is called.</para>
</section> </section>
</section> </section>
<section xml:id="digest-processing-filter"> <section xml:id="digest-processing-filter">
<title><classname>DigestProcessingFilter</classname></title> <title><classname>DigestAuthenticationFilter</classname></title>
<para><classname>DigestProcessingFilter</classname> is capable <para><classname>DigestAuthenticationFilter</classname> is capable of processing digest
of processing digest authentication credentials presented in HTTP headers. Digest authentication credentials presented in HTTP headers. Digest Authentication attempts to
Authentication attempts to solve many of the weaknesses of Basic authentication, solve many of the weaknesses of Basic authentication, specifically by ensuring
specifically by ensuring credentials are never sent in clear text across the wire. Many credentials are never sent in clear text across the wire. Many user agents support
user agents support Digest Authentication, including FireFox and Internet Explorer. The Digest Authentication, including FireFox and Internet Explorer. The standard governing
standard governing HTTP Digest Authentication is defined by RFC 2617, which updates an HTTP Digest Authentication is defined by RFC 2617, which updates an earlier version of
earlier version of the Digest Authentication standard prescribed by RFC 2069. Most user the Digest Authentication standard prescribed by RFC 2069. Most user agents implement
agents implement RFC 2617. Spring Security's <classname>DigestProcessingFilter</classname> is RFC 2617. Spring Security's <classname>DigestAuthenticationFilter</classname> is
compatible with the "<literal>auth</literal>" quality of protection compatible with the "<literal>auth</literal>" quality of protection
(<literal>qop</literal>) prescribed by RFC 2617, which also provides backward (<literal>qop</literal>) prescribed by RFC 2617, which also provides backward
compatibility with RFC 2069. Digest Authentication is a more attractive option if you compatibility with RFC 2069. Digest Authentication is a more attractive option if you
need to use unencrypted HTTP (i.e. no TLS/HTTPS) and wish to maximise security of the need to use unencrypted HTTP (i.e. no TLS/HTTPS) and wish to maximise security of the
authentication process. Indeed Digest Authentication is a mandatory requirement for the authentication process. Indeed Digest Authentication is a mandatory requirement for the
@ -88,9 +88,9 @@
key: A private key to prevent modification of the nonce token key: A private key to prevent modification of the nonce token
</programlisting> </programlisting>
</para> </para>
<para>The <classname>DigestProcessingFilterEntryPoint</classname> has a property specifying the <para>The <classname>DigestAuthenticatonEntryPoint</classname> has a property specifying the
<literal>key</literal> used for generating the nonce tokens, along with a <literal>key</literal> used for generating the nonce tokens, along with a
<literal>nonceValiditySeconds</literal> property for determining the expiration time <literal>nonceValiditySeconds</literal> property for determining the expiration time
(default 300, which equals five minutes). Whist ever the nonce is valid, the digest is (default 300, which equals five minutes). Whist ever the nonce is valid, the digest is
computed by concatenating various strings including the username, password, nonce, URI computed by concatenating various strings including the username, password, nonce, URI
being requested, a client-generated nonce (merely a random value which the user agent being requested, a client-generated nonce (merely a random value which the user agent
@ -98,12 +98,12 @@
server and user agent perform this digest computation, resulting in different hash codes server and user agent perform this digest computation, resulting in different hash codes
if they disagree on an included value (eg password). In Spring Security implementation, if they disagree on an included value (eg password). In Spring Security implementation,
if the server-generated nonce has merely expired (but the digest was otherwise valid), if the server-generated nonce has merely expired (but the digest was otherwise valid),
the <classname>DigestProcessingFilterEntryPoint</classname> will send a the <classname>DigestAuthenticationEntryPoint</classname> will send a
<literal>"stale=true"</literal> header. This tells the user agent there is no need <literal>"stale=true"</literal> header. This tells the user agent there is no need
to disturb the user (as the password and username etc is correct), but simply to try to disturb the user (as the password and username etc is correct), but simply to try
again using a new nonce.</para> again using a new nonce.</para>
<para>An appropriate value for <classname>DigestProcessingFilterEntryPoint</classname>'s <para>An appropriate value for <classname>DigestAuthenticationEntryPoint</classname>'s
<literal>nonceValiditySeconds</literal> parameter will depend on your application. <literal>nonceValiditySeconds</literal> parameter will depend on your application.
Extremely secure applications should note that an intercepted authentication header can Extremely secure applications should note that an intercepted authentication header can
be used to impersonate the principal until the <literal>expirationTime</literal> be used to impersonate the principal until the <literal>expirationTime</literal>
contained in the nonce is reached. This is the key principle when selecting an contained in the nonce is reached. This is the key principle when selecting an
@ -111,28 +111,30 @@
running over TLS/HTTPS in the first instance.</para> running over TLS/HTTPS in the first instance.</para>
<para>Because of the more complex implementation of Digest Authentication, there are often <para>Because of the more complex implementation of Digest Authentication, there are often
user agent issues. For example, Internet Explorer fails to present an user agent issues. For example, Internet Explorer fails to present an
"<literal>opaque</literal>" token on subsequent requests in the same session. Spring "<literal>opaque</literal>" token on subsequent requests in the same session. Spring
Security filters therefore encapsulate all state information into the Security filters therefore encapsulate all state information into the
"<literal>nonce</literal>" token instead. In our testing, Spring Security's "<literal>nonce</literal>" token instead. In our testing, Spring Security's
implementation works reliably with FireFox and Internet Explorer, correctly handling implementation works reliably with FireFox and Internet Explorer, correctly handling
nonce timeouts etc.</para> nonce timeouts etc.</para>
<section xml:id="digest-config"> <section xml:id="digest-config">
<title>Configuration</title> <title>Configuration</title>
<para>Now that we've reviewed the theory, let's see how to use it. To implement HTTP Digest <para>Now that we've reviewed the theory, let's see how to use it. To implement HTTP
Authentication, it is necessary to define <literal>DigestProcessingFilter</literal> in Digest Authentication, it is necessary to define
the fitler chain. The application context will need to define the <literal>DigestAuthenticationFilter</literal> in the filter chain. The
<literal>DigestProcessingFilter</literal> and its required collaborators:</para> application context will need to define the
<literal>DigestAuthenticationFilter</literal> and its required
collaborators:</para>
<para> <para>
<programlisting><![CDATA[ <programlisting><![CDATA[
<bean id="digestProcessingFilter" class= <bean id="digestFilter" class=
"org.springframework.security.web.authentication.www.DigestProcessingFilter"> "org.springframework.security.web.authentication.www.DigestAuthenticationFilter">
<property name="userDetailsService" ref="jdbcDaoImpl"/> <property name="userDetailsService" ref="jdbcDaoImpl"/>
<property name="authenticationEntryPoint" ref="digestProcessingFilterEntryPoint"/> <property name="authenticationEntryPoint" ref="digestEntryPoint"/>
<property name="userCache" ref="userCache"/> <property name="userCache" ref="userCache"/>
</bean> </bean>
<bean id="digestProcessingFilterEntryPoint" class= <bean id="digestEntryPoint" class=
"org.springframework.security.web.authentication.www.DigestProcessingFilterEntryPoint"> "org.springframework.security.web.authentication.www.DigestAuthenticationEntryPoint">
<property name="realmName" value="Contacts Realm via Digest Authentication"/> <property name="realmName" value="Contacts Realm via Digest Authentication"/>
<property name="key" value="acegi"/> <property name="key" value="acegi"/>
<property name="nonceValiditySeconds" value="10"/> <property name="nonceValiditySeconds" value="10"/>
@ -140,31 +142,31 @@
</programlisting> </programlisting>
</para> </para>
<para>The configured <interfacename>UserDetailsService</interfacename> is needed because <para>The configured <interfacename>UserDetailsService</interfacename> is needed because
<literal>DigestProcessingFilter</literal> must have direct access to the clear text <literal>DigestAuthenticationFilter</literal> must have direct access to the
password of a user. Digest Authentication will NOT work if you are using encoded clear text password of a user. Digest Authentication will NOT work if you are using
passwords in your DAO. The DAO collaborator, along with the encoded passwords in your DAO. The DAO collaborator, along with the
<literal>UserCache</literal>, are typically shared directly with a <literal>UserCache</literal>, are typically shared directly with a
<classname>DaoAuthenticationProvider</classname>. The <classname>DaoAuthenticationProvider</classname>. The
<literal>authenticationEntryPoint</literal> property must be <literal>authenticationEntryPoint</literal> property must be
<classname>DigestProcessingFilterEntryPoint</classname>, so that <classname>DigestAuthenticationEntryPoint</classname>, so that
<classname>DigestProcessingFilter</classname> can obtain the correct <classname>DigestAuthenticationFilter</classname> can obtain the correct
<literal>realmName</literal> and <literal>key</literal> for digest <literal>realmName</literal> and <literal>key</literal> for digest
calculations.</para> calculations.</para>
<para>Like <literal>BasicAuthenticationFilter</literal>, if authentication is successful an <para>Like <literal>BasicAuthenticationFilter</literal>, if authentication is successful
<interfacename>Authentication</interfacename> request token will be placed into the an <interfacename>Authentication</interfacename> request token will be placed into
<classname>SecurityContextHolder</classname>. If the authentication event was the <classname>SecurityContextHolder</classname>. If the authentication event was
successful, or authentication was not attempted because the HTTP header did not contain successful, or authentication was not attempted because the HTTP header did not
a Digest Authentication request, the filter chain will continue as normal. The only time contain a Digest Authentication request, the filter chain will continue as normal.
the filter chain will be interrupted is if authentication fails and the The only time the filter chain will be interrupted is if authentication fails and
<interfacename>AuthenticationEntryPoint</interfacename> is called, as discussed in the <interfacename>AuthenticationEntryPoint</interfacename> is called, as discussed
the previous paragraph.</para> in the previous paragraph.</para>
<para>Digest Authentication's RFC offers a range of additional features to further increase <para>Digest Authentication's RFC offers a range of additional features to further
security. For example, the nonce can be changed on every request. Despite this, Spring increase security. For example, the nonce can be changed on every request. Despite
Security implementation was designed to minimise the complexity of the implementation this, Spring Security implementation was designed to minimise the complexity of the
(and the doubtless user agent incompatibilities that would emerge), and avoid needing to implementation (and the doubtless user agent incompatibilities that would emerge),
store server-side state. You are invited to review RFC 2617 if you wish to explore these and avoid needing to store server-side state. You are invited to review RFC 2617 if
features in more detail. As far as we are aware, Spring Security's implementation does you wish to explore these features in more detail. As far as we are aware, Spring
comply with the minimum standards of this RFC.</para> Security's implementation does comply with the minimum standards of this RFC.</para>
</section> </section>
</section> </section>
</chapter> </chapter>

View File

@ -1,60 +1,44 @@
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="cas" <chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="cas"
xmlns:xlink="http://www.w3.org/1999/xlink"> xmlns:xlink="http://www.w3.org/1999/xlink">
<title>CAS Authentication</title> <title>CAS Authentication</title>
<section xml:id="cas-overview"> <section xml:id="cas-overview">
<title>Overview</title> <title>Overview</title>
<para>JA-SIG produces an enterprise-wide single sign on system known as CAS. Unlike other
<para>JA-SIG produces an enterprise-wide single sign on system known initiatives, JA-SIG's Central Authentication Service is open source, widely used, simple to
as CAS. Unlike other initiatives, JA-SIG's Central Authentication understand, platform independent, and supports proxy capabilities. Spring Security fully
Service is open source, widely used, simple to understand, platform supports CAS, and provides an easy migration path from single-application deployments of
independent, and supports proxy capabilities. Spring Security fully Spring Security through to multiple-application deployments secured by an enterprise-wide CAS
supports CAS, and provides an easy migration path from server.</para>
single-application deployments of Spring Security through to <para>You can learn more about CAS at <literal>http://www.ja-sig.org/products/cas/</literal>.
multiple-application deployments secured by an enterprise-wide CAS You will also need to visit this site to download the CAS Server files.</para>
server.</para>
<para>You can learn more about CAS at
<literal>http://www.ja-sig.org/products/cas/</literal>. You will also need
to visit this site to download the CAS Server files.</para>
</section> </section>
<section xml:id="cas-how-it-works"> <section xml:id="cas-how-it-works">
<info><title>How CAS Works</title></info> <info>
<title>How CAS Works</title>
<para>Whilst the CAS web site contains documents that detail </info>
the architecture of CAS, we present the general overview again here <para>Whilst the CAS web site contains documents that detail the architecture of CAS, we present
within the context of Spring Security. Spring Security 2.0 supports the general overview again here within the context of Spring Security. Spring Security 2.0
CAS 3. At the time of writing, the CAS server was at version 3.2.</para> supports CAS 3. At the time of writing, the CAS server was at version 3.2.</para>
<para>Somewhere in your enterprise you will need to setup a CAS server. The CAS server is simply
<para>Somewhere in your enterprise you will need to setup a CAS a standard WAR file, so there isn't anything difficult about setting up your server. Inside
server. The CAS server is simply a standard WAR file, so there isn't the WAR file you will customise the login and other single sign on pages displayed to
anything difficult about setting up your server. Inside the WAR file users.</para>
you will customise the login and other single sign on pages displayed
to users.</para>
<para>When deploying a CAS 3.2 server, you will also need to specify an <para>When deploying a CAS 3.2 server, you will also need to specify an
<literal>AuthenticationHandler</literal> in the <literal>AuthenticationHandler</literal> in the
<filename>deployerConfigContext.xml</filename> included with CAS. The <filename>deployerConfigContext.xml</filename> included with CAS. The
<literal>AuthenticationHandler</literal> has a simple method that <literal>AuthenticationHandler</literal> has a simple method that returns a boolean as to
returns a boolean as to whether a given set of Credentials is valid. whether a given set of Credentials is valid. Your <literal>AuthenticationHandler</literal>
Your <literal>AuthenticationHandler</literal> implementation will need implementation will need to link into some type of backend authentication repository, such as
to link into some type of backend authentication repository, such as an LDAP server or database. CAS itself includes numerous
an LDAP server or database. CAS itself includes numerous <literal>AuthenticationHandler</literal>s out of the box to assist with this. When you
<literal>AuthenticationHandler</literal>s out of the box to assist download and deploy the server war file, it is set up to successfully authenticate users who
with this. When you download and deploy the server war file, it is set up enter a password matching their username, which is useful for testing.</para>
to successfully authenticate users who enter a password matching their <para>Apart from the CAS server itself, the other key players are of course the secure web
username, which is useful for testing.</para> applications deployed throughout your enterprise. These web applications are known as
"services". There are two types of services: standard services and proxy services. A proxy
<para>Apart from the CAS server itself, the other key players are of service is able to request resources from other services on behalf of the user. This will be
course the secure web applications deployed throughout your explained more fully later.</para>
enterprise. These web applications are known as "services". There are <!--
two types of services: standard services and proxy services. A proxy
service is able to request resources from other services on behalf of
the user. This will be explained more fully later.</para>
<!--
<section xml:id="cas-sequence"> <section xml:id="cas-sequence">
<title>Spring Security and CAS Interaction Sequence</title> <title>Spring Security and CAS Interaction Sequence</title>
@ -260,84 +244,69 @@
</section> </section>
--> -->
</section> </section>
<section xml:id="cas-client"> <section xml:id="cas-client">
<info><title>Configuration of CAS Client</title></info> <info>
<title>Configuration of CAS Client</title>
<para>The web application side of CAS is made easy due to Spring </info>
Security. It is assumed you already know the basics of using Spring <para>The web application side of CAS is made easy due to Spring Security. It is assumed you
Security, so these are not covered again below. We'll assume a namespace already know the basics of using Spring Security, so these are not covered again below. We'll
based configuration is being used and add in the CAS beans as required. assume a namespace based configuration is being used and add in the CAS beans as required. </para>
</para> <para>You will need to add a <literal>ServiceProperties</literal> bean to your application
context. This represents your service:</para>
<para>You will need to add a <literal>ServiceProperties</literal> bean <para>
to your application context. This represents your service:</para> <programlisting><![CDATA[
<para><programlisting><![CDATA[
<bean id="serviceProperties" <bean id="serviceProperties"
class="org.springframework.security.cas.ServiceProperties"> class="org.springframework.security.cas.ServiceProperties">
<property name="service" <property name="service"
value="https://localhost:8443/cas-sample/j_spring_cas_security_check"/> value="https://localhost:8443/cas-sample/j_spring_cas_security_check"/>
<property name="sendRenew" value="false"/> <property name="sendRenew" value="false"/>
</bean>]]> </bean>]]>
</programlisting></para> </programlisting>
</para>
<para>The <literal>service</literal> must equal a URL that will be <para>The <literal>service</literal> must equal a URL that will be monitored by the
monitored by the <literal>CasProcessingFilter</literal>. The <literal>CasAuthenticationFilter</literal>. The <literal>sendRenew</literal> defaults to
<literal>sendRenew</literal> defaults to false, but should be set to false, but should be set to true if your application is particularly sensitive. What this
true if your application is particularly sensitive. What this parameter does is tell the CAS login service that a single sign on login is unacceptable.
parameter does is tell the CAS login service that a single sign on Instead, the user will need to re-enter their username and password in order to gain access to
login is unacceptable. Instead, the user will need to re-enter their the service.</para>
username and password in order to gain access to the service.</para> <para>The following beans should be configured to commence the CAS authentication
process:</para>
<para>The following beans should be configured to commence the CAS <para>
authentication process:</para> <programlisting><![CDATA[
<para><programlisting><![CDATA[
<security:authentication-manager alias="authenticationManager"/> <security:authentication-manager alias="authenticationManager"/>
<bean id="casProcessingFilter" <bean id="casFilter"
class="org.springframework.security.cas.web.CasProcessingFilter"> class="org.springframework.security.cas.web.CasAuthenticationFilter">
<security:custom-filter after="CAS_PROCESSING_FILTER"/> <security:custom-filter after="CAS_PROCESSING_FILTER"/>
<property name="authenticationManager" ref="authenticationManager"/> <property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationFailureUrl" value="/casfailed.jsp"/> <property name="authenticationFailureUrl" value="/casfailed.jsp"/>
<property name="defaultTargetUrl" value="/"/> <property name="defaultTargetUrl" value="/"/>
</bean> </bean>
<bean id="casProcessingFilterEntryPoint" <bean id="casEntryPoint"
class="org.springframework.security.cas.web.CasProcessingFilterEntryPoint"> class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
<property name="loginUrl" value="https://localhost:9443/cas/login"/> <property name="loginUrl" value="https://localhost:9443/cas/login"/>
<property name="serviceProperties" ref="serviceProperties"/> <property name="serviceProperties" ref="serviceProperties"/>
</bean> </bean>
]]> ]]>
</programlisting></para> </programlisting>
<para>
The <classname>CasProcessingFilterEntryPoint</classname> should be selected to
drive authentication using <link xlink:href="ns-entry-point-ref"><literal>entry-point-ref</literal></link>.
</para> </para>
<para> The <classname>CasAuthenticationEntryPoint</classname> should be selected to drive
<para>The <literal>CasProcessingFilter</literal> has very similar authentication using <link xlink:href="ns-entry-point-ref"
properties to the <literal>UsernamePasswordAuthenticationFilter</literal> ><literal>entry-point-ref</literal></link>. </para>
(used for form-based logins). Each property is <para>The <literal>CasAuthenticationFilter</literal> has very similar properties to the
self-explanatory. Note that we've also used the namespace syntax <literal>UsernamePasswordAuthenticationFilter</literal> (used for form-based logins). Each
for setting up an alias to the authentication mnager, since the property is self-explanatory. Note that we've also used the namespace syntax for setting up an
<literal>CasProcessingFilter</literal> needs a reference to it.</para> alias to the authentication mnager, since the <literal>CasAuthenticationFilter</literal> needs
a reference to it.</para>
<para>For CAS to operate, the <para>For CAS to operate, the <classname>ExceptionTranslationFilter</classname> must have its
<classname>ExceptionTranslationFilter</classname> must have its <literal>authenticationEntryPoint</literal> property set to the
<literal>authenticationEntryPoint</literal> property set to the <literal>CasAuthenticationEntryPoint</literal> bean.</para>
<literal>CasProcessingFilterEntryPoint</literal> bean.</para> <para>The <literal>CasAuthenticationEntryPoint</literal> must refer to the
<literal>ServiceProperties</literal> bean (discussed above), which provides the URL to the
<para>The <literal>CasProcessingFilterEntryPoint</literal> must refer enterprise's CAS login server. This is where the user's browser will be redirected.</para>
to the <literal>ServiceProperties</literal> bean (discussed above), <para>Next you need to add a <literal>CasAuthenticationProvider</literal> and its collaborators: <programlisting><![CDATA[
which provides the URL to the enterprise's CAS login server. This is
where the user's browser will be redirected.</para>
<para>Next you need to add a <literal>CasAuthenticationProvider</literal> and its
collaborators:
<programlisting><![CDATA[
<bean id="casAuthenticationProvider" <bean id="casAuthenticationProvider"
class="org.springframework.security.cas.authentication.CasAuthenticationProvider"> class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
<security:custom-authentication-provider /> <security:custom-authentication-provider />
@ -355,16 +324,14 @@
<security:user name="joe" password="joe" authorities="ROLE_USER" /> <security:user name="joe" password="joe" authorities="ROLE_USER" />
... ...
</security:user-service>]]> </security:user-service>]]>
</programlisting> </programlisting> The
The <classname>CasAuthenticationProvider</classname> uses a <interfacename>UserDetailsService</interfacename> <classname>CasAuthenticationProvider</classname> uses a
instance to load the authorities for a user, once they have been authentiated by CAS. We've shown a simple <interfacename>UserDetailsService</interfacename> instance to load the authorities for a
in-memory setup here. user, once they have been authentiated by CAS. We've shown a simple in-memory setup here. </para>
</para> <para>The beans are all reasonable self-explanatory if you refer back to the "How CAS Works"
section.</para>
<para>The beans are all reasonable self-explanatory if you refer back
to the "How CAS Works" section.</para>
</section> </section>
<!-- <!--
<para>Note the <literal>CasProxyTicketValidator</literal> has a <para>Note the <literal>CasProxyTicketValidator</literal> has a
remarked out <literal>trustStore</literal> property. This property remarked out <literal>trustStore</literal> property. This property
might be helpful if you experience HTTPS certificate issues. Also note might be helpful if you experience HTTPS certificate issues. Also note
@ -462,4 +429,4 @@
</section> </section>
--> -->
</chapter> </chapter>

View File

@ -250,15 +250,15 @@ class="org.springframework.security.web.context.SecurityContextPersistenceFilter
<classname>ExceptionTranslationFilter</classname>. <classname>ExceptionTranslationFilter</classname>.
</para></listitem><listitem><para>Implement the login page (using a JSP or </para></listitem><listitem><para>Implement the login page (using a JSP or
MVC controller).</para></listitem><listitem><para>Configure an instance of MVC controller).</para></listitem><listitem><para>Configure an instance of
<classname>UsernamePasswordAuthenticationFilter</classname> in <classname>UsernamePasswordAuthenticationFilter</classname> in the
the application context</para></listitem><listitem><para>Add the filter bean application context</para></listitem><listitem><para>Add the filter bean to
to your filter chain proxy (making sure you pay attention to the order). your filter chain proxy (making sure you pay attention to the order).
<!-- TODO: link --></para></listitem></orderedlist> The login form simply <!-- TODO: link --></para></listitem></orderedlist> The login form simply
contains <literal>j_username</literal> and <literal>j_password</literal> input fields, 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 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 <literal>/j_spring_security_check</literal>). The basic filter configuration looks
something like this: <programlisting><![CDATA[ something like this: <programlisting><![CDATA[
<bean id="authenticationProcessingFilter" class= <bean id="authenticationFilter" class=
"org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"> "org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager"/> <property name="authenticationManager" ref="authenticationManager"/>
<property name="filterProcessesUrl" value="/j_spring_security_check"/> <property name="filterProcessesUrl" value="/j_spring_security_check"/>

View File

@ -188,7 +188,7 @@
authentication and logout handling services respectively <footnote><para>In versions prior authentication and logout handling services respectively <footnote><para>In versions prior
to 3.0, this list also included remember-me functionality. This could cause some to 3.0, this list also included remember-me functionality. This could cause some
confusing errors with some configurations and was removed in 3.0. In 3.0, the addition confusing errors with some configurations and was removed in 3.0. In 3.0, the addition
of an <classname>AnonymousProcessingFilter</classname> is part of the default of an <classname>AnonymousAuthenticationFilter</classname> is part of the default
<literal>&lt;http></literal> configuration, so the <literal>&lt;anonymous <literal>&lt;http></literal> configuration, so the <literal>&lt;anonymous
/></literal> element is added regardless of whether <literal>auto-config</literal> /></literal> element is added regardless of whether <literal>auto-config</literal>
is enabled.</para></footnote> . They each have attributes which can be used to alter is enabled.</para></footnote> . They each have attributes which can be used to alter
@ -472,39 +472,37 @@
align="center">Alias</entry><entry align="center">Filter Class</entry><entry align="center">Alias</entry><entry align="center">Filter Class</entry><entry
align="center">Namespace Element or align="center">Namespace Element or
Attribute</entry></row></thead><tbody><row><entry> Attribute</entry></row></thead><tbody><row><entry>
CHANNEL_FILTER</entry><entry><literal>ChannelProcessingFilter</literal></entry><entry><literal>http/intercept-url</literal></entry></row><row><entry> CHANNEL_FILTER</entry><entry><literal>ChannelProcessingFilter</literal></entry><entry><literal>http/intercept-url@requires-channel</literal></entry></row><row><entry>
CONCURRENT_SESSION_FILTER</entry><entry><literal>ConcurrentSessionFilter</literal> CONCURRENT_SESSION_FILTER</entry><entry><literal>ConcurrentSessionFilter</literal>
</entry><entry><literal>http/concurrent-session-control</literal></entry></row><row><entry> </entry><entry><literal>session-management/concurrency-control</literal></entry></row><row><entry>
SESSION_CONTEXT_INTEGRATION_FILTER</entry><entry><classname>HttpSessionContextIntegrationFilter</classname></entry><entry><literal>http</literal></entry></row><row><entry> SECURITY_CONTEXT_FILTER</entry><entry><classname>SecurityContextPersistenceFilter</classname></entry><entry><literal>http</literal></entry></row><row><entry>
LOGOUT_FILTER LOGOUT_FILTER
</entry><entry><literal>LogoutFilter</literal></entry><entry><literal>http/logout</literal></entry></row><row><entry> </entry><entry><literal>LogoutFilter</literal></entry><entry><literal>http/logout</literal></entry></row><row><entry>
X509_FILTER X509_FILTER
</entry><entry><literal>X509PreAuthenticatedProcessigFilter</literal></entry><entry><literal>http/x509</literal></entry></row><row><entry> </entry><entry><literal>X509AuthenticationFilter</literal></entry><entry><literal>http/x509</literal></entry></row><row><entry>
PRE_AUTH_FILTER PRE_AUTH_FILTER
</entry><entry><literal>AstractPreAuthenticatedProcessingFilter</literal> </entry><entry><literal>AstractPreAuthenticatedProcessingFilter</literal>
Subclasses</entry><entry>N/A</entry></row><row><entry> CAS_PROCESSING_FILTER Subclasses</entry><entry>N/A</entry></row><row><entry> CAS_FILTER
</entry><entry><literal>CasProcessingFilter</literal></entry><entry>N/A</entry></row><row><entry> </entry><entry><literal>CasAuthenticationFilter</literal></entry><entry>N/A</entry></row><row><entry>
AUTHENTICATION_PROCESSING_FILTER FORM_LOGIN_FILTER
</entry><entry><literal>UsernamePasswordAuthenticationFilter</literal></entry><entry><literal>http/form-login</literal></entry></row><row><entry> </entry><entry><literal>UsernamePasswordAuthenticationFilter</literal></entry><entry><literal>http/form-login</literal></entry></row><row><entry>
BASIC_PROCESSING_FILTER BASIC_AUTH_FILTER
</entry><entry><literal>BasicProcessingFilter</literal></entry><entry><literal>http/http-basic</literal></entry></row><row><entry> </entry><entry><literal>BasicAuthenticationFilter</literal></entry><entry><literal>http/http-basic</literal></entry></row><row><entry>
SERVLET_API_SUPPORT_FILTER</entry><entry><literal>SecurityContextHolderAwareRequestFilter</literal></entry><entry><literal>http/@servlet-api-provision</literal></entry></row><row><entry> SERVLET_API_SUPPORT_FILTER</entry><entry><literal>SecurityContextHolderAwareFilter</literal></entry><entry><literal>http/@servlet-api-provision</literal></entry></row><row><entry>
REMEMBER_ME_FILTER REMEMBER_ME_FILTER
</entry><entry><classname>RememberMeProcessingFilter</classname></entry><entry><literal>http/remember-me</literal></entry></row><row><entry> </entry><entry><classname>RememberMeAuthenticationFilter</classname></entry><entry><literal>http/remember-me</literal></entry></row><row><entry>
ANONYMOUS_FILTER ANONYMOUS_FILTER
</entry><entry><literal>AnonymousProcessingFilter</literal></entry><entry><literal>http/anonymous</literal></entry></row><row><entry> </entry><entry><literal>AnonymousAuthenticationFilter</literal></entry><entry><literal>http/anonymous</literal></entry></row><row><entry>
EXCEPTION_TRANSLATION_FILTER SESSION_MANAGEMENT_FILTER</entry><entry><literal>SessionManagementFilter</literal></entry><entry><literal>session-management</literal></entry></row><row><entry>EXCEPTION_TRANSLATION_FILTER
</entry><entry><classname>ExceptionTranslationFilter</classname></entry><entry><literal>http</literal></entry></row><row><entry> </entry><entry><classname>ExceptionTranslationFilter</classname></entry><entry><literal>http</literal></entry></row><row><entry>
NTLM_FILTER
</entry><entry><literal>NtlmProcessingFilter</literal></entry><entry>N/A</entry></row><row><entry>
FILTER_SECURITY_INTERCEPTOR FILTER_SECURITY_INTERCEPTOR
</entry><entry><classname>FilterSecurityInterceptor</classname></entry><entry><literal>http</literal></entry></row><row><entry> </entry><entry><classname>FilterSecurityInterceptor</classname></entry><entry><literal>http</literal></entry></row><row><entry>
SWITCH_USER_FILTER SWITCH_USER_FILTER
</entry><entry><literal>SwitchUserProcessingFilter</literal></entry><entry>N/A</entry></row></tbody></tgroup></table> </entry><entry><literal>SwitchUserFilter</literal></entry><entry>N/A</entry></row></tbody></tgroup></table>
You can add your own filter to the stack, using the <literal>custom-filter</literal> element 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[ and one of these names to specify the position your filter should appear at: <programlisting language="xml"><![CDATA[
<http> <http>
<custom-filter position="AUTHENTICATION_PROCESSING_FILTER" ref="myFilter" /> <custom-filter position="FORM_LOGIN_FILTER" ref="myFilter" />
</http> </http>
<beans:bean id="myFilter" class="com.mycompany.MySpecialAuthenticationFilter"/> <beans:bean id="myFilter" class="com.mycompany.MySpecialAuthenticationFilter"/>

View File

@ -8,150 +8,137 @@
has already been reliably authenticated by some external system prior to accessing the has already been reliably authenticated by some external system prior to accessing the
application. We refer to these situations as <quote>pre-authenticated</quote> scenarios. application. We refer to these situations as <quote>pre-authenticated</quote> scenarios.
Examples include X.509, Siteminder and authentication by the J2EE container in which the Examples include X.509, Siteminder and authentication by the J2EE container in which the
application is running. When using pre-authentication, Spring Security has to application is running. When using pre-authentication, Spring Security has to
<orderedlist> <orderedlist><listitem><para>Identify the user making the request.
<listitem> </para></listitem><listitem><para>Obtain the authorities for the
<para>Identify the user making the request. </para> user.</para></listitem></orderedlist>The details will depend on the external authentication
</listitem> mechanism. A user might be identified by their certificate information in the case of X.509, or
<listitem> by an HTTP request header in the case of Siteminder. If relying on container authentication, the
<para>Obtain the authorities for the user.</para> user will be identified by calling the <methodname>getUserPrincipal()</methodname> method on the
</listitem> incoming HTTP request. In some cases, the external mechanism may supply role/authority
</orderedlist>The details will depend on the external authentication mechanism. A user might be information for the user but in others the authorities must be obtained from a separate source,
identified by their certificate information in the case of X.509, or by an HTTP request header such as a <interfacename>UserDetailsService</interfacename>. </para>
in the case of Siteminder. If relying on container authentication, the user will be identified
by calling the <methodname>getUserPrincipal()</methodname> method on the incoming HTTP request.
In some cases, the external mechanism may supply role/authority information for the user but in
others the authorities must be obtained from a separate source, such as a
<interfacename>UserDetailsService</interfacename>.
</para>
<section> <section>
<title>Pre-Authentication Framework Classes</title> <title>Pre-Authentication Framework Classes</title>
<para> Because most pre-authentication mechanisms follow the same pattern, Spring <para> Because most pre-authentication mechanisms follow the same pattern, Spring Security has a
Security has a set of classes which provide an internal framework for implementing set of classes which provide an internal framework for implementing pre-authenticated
pre-authenticated authentication providers. This removes duplication and allows new authentication providers. This removes duplication and allows new implementations to be added
implementations to be added in a structured fashion, without having to write everything from in a structured fashion, without having to write everything from scratch. You don't need to
scratch. You don't need to know about these classes if you want to use something like know about these classes if you want to use something like <link xlink:href="#x509">X.509
<link xlink:href="#x509">X.509 authentication</link>, as it already has a namespace configuration authentication</link>, as it already has a namespace configuration option which is simpler
option which is simpler to use and get started with. If you need to use explicit bean confiuration or to use and get started with. If you need to use explicit bean confiuration or are planning on
are planning on writing your own implementation then an understanding of how the writing your own implementation then an understanding of how the provided implementations work
provided implementations work will be useful. You will find classes under the will be useful. You will find classes under the
<package>org.springframework.security.web.authentication.preauth</package>. We just provide an outline <package>org.springframework.security.web.authentication.preauth</package>. We just provide
here so you should consult the Javadoc and source where appropriate. an outline here so you should consult the Javadoc and source where appropriate. </para>
</para>
<section> <section>
<title>AbstractPreAuthenticatedProcessingFilter</title> <title>AbstractPreAuthenticatedProcessingFilter</title>
<para> <para> This class will check the current contents of the security context and, if empty, it
This class will check the current contents of the security context and, if empty, it will attempt to extract will attempt to extract user information from the HTTP request and submit it to the
user information from the HTTP request and submit it to the <interfacename>AuthenticationManager</interfacename>. <interfacename>AuthenticationManager</interfacename>. Subclasses override the following
Subclasses override the following methods to obtain this information: methods to obtain this information:
<programlisting language="java"> <programlisting language="java">
protected abstract Object getPreAuthenticatedPrincipal(HttpServletRequest request); protected abstract Object getPreAuthenticatedPrincipal(HttpServletRequest request);
protected abstract Object getPreAuthenticatedCredentials(HttpServletRequest request); protected abstract Object getPreAuthenticatedCredentials(HttpServletRequest request);
</programlisting> </programlisting>
After calling these, the filter will create a <classname>PreAuthenticatedAuthenticationToken</classname> After calling these, the filter will create a
containing the returned data and submit it for authentication. By <quote>authentication</quote> here, we <classname>PreAuthenticatedAuthenticationToken</classname> containing the returned data
really just mean further processing to perhaps load the user's authorities, but the standard Spring Security and submit it for authentication. By <quote>authentication</quote> here, we really just mean
authentication architecture is followed. further processing to perhaps load the user's authorities, but the standard Spring Security
</para> authentication architecture is followed. </para>
</section> </section>
<section> <section>
<title>AbstractPreAuthenticatedAuthenticationDetailsSource</title> <title>AbstractPreAuthenticatedAuthenticationDetailsSource</title>
<para> <para> Like other Spring Security authentication filters, the pre-authentication filter has an
Like other Spring Security authentication filters, the pre-authentication filter has an <literal>authenticationDetailsSource</literal> property which by default will create a
<literal>authenticationDetailsSource</literal> property which by default will create a <classname>WebAuthenticationDetails</classname> object to store additional information
<classname>WebAuthenticationDetails</classname> object to store additional information such as such as the session-identifier and originating IP address in the <literal>details</literal>
the session-identifier and originating IP address in the <literal>details</literal> property of property of the <interfacename>Authentication</interfacename> object. In cases where user
the <interfacename>Authentication</interfacename> object. role information can be obtained from the pre-authentication mechanism, the data is also
In cases where user role information can be obtained from the pre-authentication mechanism, the stored in this property. Subclasses of
data is also stored in this property. Subclasses of <classname>AbstractPreAuthenticatedAuthenticationDetailsSource</classname> use an extended
<classname>AbstractPreAuthenticatedAuthenticationDetailsSource</classname> use an extended details details object which implements the
object which implements the <interfacename>GrantedAuthoritiesContainer</interfacename> interface, thus enabling the <interfacename>GrantedAuthoritiesContainer</interfacename> interface, thus enabling the
authentication provider to read the authorities which were externally allocated to the user. We'll look at a concrete authentication provider to read the authorities which were externally allocated to the user.
example next. We'll look at a concrete example next. </para>
</para>
<section xml:id="j2ee-preauth-details"> <section xml:id="j2ee-preauth-details">
<title>J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource</title> <title>J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource</title>
<para> <para> If the filter is configured with an <literal>authenticationDetailsSource</literal>
If the filter is configured with an <literal>authenticationDetailsSource</literal> which is an instance of this which is an instance of this class, the authority information is obtained by calling the
class, the authority information is obtained by calling the <methodname>isUserInRole(String role)</methodname> method <methodname>isUserInRole(String role)</methodname> method for each of a pre-determined
for each of a pre-determined set of <quote>mappable roles</quote>. The class gets these from a configured set of <quote>mappable roles</quote>. The class gets these from a configured
<interfacename>MappableAttributesRetriever</interfacename>. Possible implementations include hard-coding a list in the application <interfacename>MappableAttributesRetriever</interfacename>. Possible implementations
context and reading the role information from the <literal>&lt;security-role&gt;</literal> information in a include hard-coding a list in the application context and reading the role information
<filename>web.xml</filename> file. The pre-authentication sample application uses the latter approach. from the <literal>&lt;security-role&gt;</literal> information in a
</para> <filename>web.xml</filename> file. The pre-authentication sample application uses the
<para>There is an additional stage where the roles (or attributes) are mapped to Spring Security latter approach. </para>
<interfacename>GrantedAuthority</interfacename> objects using a configured <para>There is an additional stage where the roles (or attributes) are mapped to Spring
<interfacename>Attributes2GrantedAuthoritiesMapper</interfacename>. The default will just add the usual <literal>ROLE_</literal> Security <interfacename>GrantedAuthority</interfacename> objects using a configured
prefix to the names, but it gives you full control over the behaviour. <interfacename>Attributes2GrantedAuthoritiesMapper</interfacename>. The default will
</para> just add the usual <literal>ROLE_</literal> prefix to the names, but it gives you full
control over the behaviour. </para>
</section> </section>
</section> </section>
<section> <section>
<title>PreAuthenticatedAuthenticationProvider</title> <title>PreAuthenticatedAuthenticationProvider</title>
<para> <para> The pre-authenticated provider has little more to do than load the
The pre-authenticated provider has little more to do than load the <interfacename>UserDetails</interfacename> <interfacename>UserDetails</interfacename> object for the user. It does this by delegating
object for the user. It does this by delegating to a <interfacename>AuthenticationUserDetailsService</interfacename>. to a <interfacename>AuthenticationUserDetailsService</interfacename>. The latter is similar
The latter is similar to the standard <interfacename>UserDetailsService</interfacename> but takes an to the standard <interfacename>UserDetailsService</interfacename> but takes an
<interfacename>Authentication</interfacename> object rather than just user name: <interfacename>Authentication</interfacename> object rather than just user name:
<programlisting language="java"> <programlisting language="java">
public interface AuthenticationUserDetailsService { public interface AuthenticationUserDetailsService {
UserDetails loadUserDetails(Authentication token) throws UsernameNotFoundException; UserDetails loadUserDetails(Authentication token) throws UsernameNotFoundException;
} }
</programlisting> </programlisting>
This interface may have also other uses but with pre-authentication it allows access to the authorities which This interface may have also other uses but with pre-authentication it allows access to the
were packaged in the <interfacename>Authentication</interfacename> object, as we saw in the previous section. authorities which were packaged in the <interfacename>Authentication</interfacename> object,
The <classname>PreAuthenticatedGrantedAuthoritiesUserDetailsService</classname> class does this. as we saw in the previous section. The
Alternatively, it may delegate to a standard <interfacename>UserDetailsService</interfacename> via the <classname>PreAuthenticatedGrantedAuthoritiesUserDetailsService</classname> class does
<classname>UserDetailsByNameServiceWrapper</classname> implementation. this. Alternatively, it may delegate to a standard
</para> <interfacename>UserDetailsService</interfacename> via the
<classname>UserDetailsByNameServiceWrapper</classname> implementation. </para>
</section> </section>
<section> <section>
<title>Http403ForbiddenEntryPoint</title> <title>Http403ForbiddenEntryPoint</title>
<para> <para> The <interfacename>AuthenticationEntryPoint</interfacename> was discussed in the <link
The <interfacename>AuthenticationEntryPoint</interfacename> was discussed in the <link xlink:href="#tech-intro-auth-entry-point">technical xlink:href="#tech-intro-auth-entry-point">technical overview</link> chapter. Normally it
overview</link> chapter. Normally it is responsible for kick-starting the authentication process for an unauthenticated user is responsible for kick-starting the authentication process for an unauthenticated user
(when they try to access a protected resource), but in the pre-authenticated case this doesn't apply. You would only (when they try to access a protected resource), but in the pre-authenticated case this
configure the <classname>ExceptionTranslationFilter</classname> with an instance of this class if you aren't doesn't apply. You would only configure the
using pre-authentication in combination with other authentication mechanisms. <classname>ExceptionTranslationFilter</classname> with an instance of this class if you
It will be called if the user is rejected by the <classname>AbstractPreAuthenticatedProcessingFilter</classname> aren't using pre-authentication in combination with other authentication mechanisms. It will
resulting in a null authentication. It always returns a <literal>403</literal>-forbidden response code if called. be called if the user is rejected by the
</para> <classname>AbstractPreAuthenticatedProcessingFilter</classname> resulting in a null
authentication. It always returns a <literal>403</literal>-forbidden response code if
called. </para>
</section> </section>
</section> </section>
<section> <section>
<title>Concrete Implementations</title> <title>Concrete Implementations</title>
<para> <para> X.509 authentication is covered in its <link xlink:href="#x509">own chapter</link>. Here
X.509 authentication is covered in its <link xlink:href="#x509">own chapter</link>. Here we'll look at some classes we'll look at some classes which provide support for other pre-authenticated scenarios. </para>
which provide support for other pre-authenticated scenarios.
</para>
<section> <section>
<title>Request-Header Authentication (Siteminder)</title> <title>Request-Header Authentication (Siteminder)</title>
<para> <para> An external authentication system may supply information to the application by setting
An external authentication system may supply information to the application by setting specific headers on the HTTP request. specific headers on the HTTP request. A well known example of this is is Siteminder, which
A well known example of this is is Siteminder, which passes the username in a header called <literal>SM_USER</literal>. passes the username in a header called <literal>SM_USER</literal>. This mechanism is
This mechanism is supported by the class <classname>RequestHeaderPreAuthenticatedProcessingFilter</classname> which supported by the class <classname>RequestHeaderAuthenticationFilter</classname> which simply
simply extracts the username from the header. It defaults to using the name <literal>SM_USER</literal> as the extracts the username from the header. It defaults to using the name
header name. See the Javadoc for more details. <literal>SM_USER</literal> as the header name. See the Javadoc for more details. </para>
</para>
<tip> <tip>
<para>Note that when using a system like this, the framework performs no authentication checks at all and <para>Note that when using a system like this, the framework performs no authentication
it is <emphasis>extremely</emphasis> important that the external system is configured properly and protects all checks at all and it is <emphasis>extremely</emphasis> important that the external system
access to the application. If an attacker is able to forge the headers in their original request without this being is configured properly and protects all access to the application. If an attacker is able
detected then they could potentially choose any userame they wished. to forge the headers in their original request without this being detected then they could
</para> potentially choose any userame they wished. </para>
</tip> </tip>
<section> <section>
<title>Siteminder Example Configuration</title> <title>Siteminder Example Configuration</title>
<para> <para> A typical configuration using this filter would look like this: <programlisting><![CDATA[
A typical configuration using this filter would look like this:
<programlisting><![CDATA[
<bean id="siteminderFilter" class= <bean id="siteminderFilter" class=
"org.springframework.security.web.authentication.preauth.header.RequestHeaderPreAuthenticatedProcessingFilter"> "org.springframework.security.web.authentication.preauth.header.RequestHeaderAuthenticationFilter">
<security:custom-filter position="PRE_AUTH_FILTER" /> <security:custom-filter position="PRE_AUTH_FILTER" />
<property name="principalRequestHeader" value="SM_USER"/> <property name="principalRequestHeader" value="SM_USER"/>
<property name="authenticationManager" ref="authenticationManager" /> <property name="authenticationManager" ref="authenticationManager" />
@ -170,30 +157,27 @@ class="org.springframework.security.web.authentication.preauth.PreAuthenticatedA
<security:authentication-manager alias="authenticationManager" /> <security:authentication-manager alias="authenticationManager" />
]]> ]]>
</programlisting> </programlisting> We've assumed here that the security namespace is being used for
We've assumed here that the security namespace is being used for configuration (hence the user of the <literal>custom-filter</literal>, configuration (hence the user of the <literal>custom-filter</literal>,
<literal>authentication-manager</literal> and <literal>custom-authentication-provider</literal> elements (you can read more about them <literal>authentication-manager</literal> and
in the <link xlink:href="ns-config">namespace chapter</link>). You would leave these out of a traditional bean configuration. <literal>custom-authentication-provider</literal> elements (you can read more about them
It's also assumed that you have added a <interfacename>UserDetailsService</interfacename> (called <quote>userDetailsService</quote>) in the <link xlink:href="ns-config">namespace chapter</link>). You would leave these out
to your configuration to load the user's roles. of a traditional bean configuration. It's also assumed that you have added a
<interfacename>UserDetailsService</interfacename> (called
<quote>userDetailsService</quote>) to your configuration to load the user's roles.
</para> </para>
</section> </section>
</section> </section>
<section> <section>
<title>J2EE Container Authentication</title> <title>J2EE Container Authentication</title>
<para> <para> The class <classname>J2eePreAuthenticatedProcessingFilter</classname> will extract the
The class <classname>J2eePreAuthenticatedProcessingFilter</classname> will extract the username from the username from the <literal>userPrincipal</literal> property of the
<literal>userPrincipal</literal> property of the <interfacename>HttpServletRequest</interfacename>. use of this <interfacename>HttpServletRequest</interfacename>. use of this filter would usually be
filter would usually be combined with the use of J2EE roles as described above in <xref linkend="j2ee-preauth-details"/>. combined with the use of J2EE roles as described above in <xref
</para> linkend="j2ee-preauth-details"/>. </para>
<para> <para> There is a sample application in the codebase which uses this approach, so get hold of
There is a sample application in the codebase which uses this approach, so get hold of the code from subversion and the code from subversion and have a look at the application context file if you are
have a look at the application context file if you are interested. The code is in the <filename>samples/preauth</filename> interested. The code is in the <filename>samples/preauth</filename> directory. </para>
directory.
</para>
</section> </section>
</section> </section>
</chapter> </chapter>

View File

@ -1,34 +1,33 @@
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="remember-me" <chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="remember-me"
xmlns:xlink="http://www.w3.org/1999/xlink"> xmlns:xlink="http://www.w3.org/1999/xlink">
<info><title>Remember-Me Authentication</title></info> <info>
<title>Remember-Me Authentication</title>
</info>
<section xml:id="remember-me-overview"> <section xml:id="remember-me-overview">
<info><title>Overview</title></info> <info>
<title>Overview</title>
<para>Remember-me or persistent-login authentication refers to web sites being able to </info>
remember the identity of a principal between sessions. This is <para>Remember-me or persistent-login authentication refers to web sites being able to
typically accomplished by sending a cookie to the browser, with the remember the identity of a principal between sessions. This is typically accomplished by
cookie being detected during future sessions and causing automated sending a cookie to the browser, with the cookie being detected during future sessions
login to take place. Spring Security provides the necessary hooks for and causing automated login to take place. Spring Security provides the necessary hooks
these operations to take place, and has two concrete for these operations to take place, and has two concrete remember-me implementations.
remember-me implementations. One uses hashing to preserve the security of One uses hashing to preserve the security of cookie-based tokens and the other uses a
cookie-based tokens and the other uses a database or other persistent storage database or other persistent storage mechanism to store the generated tokens. </para>
mechanism to store the generated tokens. </para> <para> Note that both implemementations require a
<para> <interfacename>UserDetailsService</interfacename>. If you are using an
Note that both implemementations require a <interfacename>UserDetailsService</interfacename>. authentication provider which doesn't use a
If you are using an authentication provider which doesn't use a <interfacename>UserDetailsService</interfacename> <interfacename>UserDetailsService</interfacename> (for example, the LDAP provider)
(for example, the LDAP provider) then it won't work unless you also have a <interfacename>UserDetailsService</interfacename> then it won't work unless you also have a
bean in your application context. <interfacename>UserDetailsService</interfacename> bean in your application context.
</para> </para>
</section> </section>
<section xml:id="remember-me-hash-token"> <section xml:id="remember-me-hash-token">
<title>Simple Hash-Based Token Approach</title> <title>Simple Hash-Based Token Approach</title>
<para>This approach uses hashing to achieve a useful remember-me strategy. <para>This approach uses hashing to achieve a useful remember-me strategy. In essence a
In essence a cookie is sent to the browser upon successful interactive authentication, with the cookie is sent to the browser upon successful interactive authentication, with the
cookie being composed as follows: cookie being composed as follows:
<programlisting> <programlisting>
base64(username + ":" + expirationTime + ":" + base64(username + ":" + expirationTime + ":" +
md5Hex(username + ":" + expirationTime + ":" password + ":" + key)) md5Hex(username + ":" + expirationTime + ":" password + ":" + key))
@ -38,109 +37,101 @@
expressed in milliseconds expressed in milliseconds
key: A private key to prevent modification of the remember-me token key: A private key to prevent modification of the remember-me token
</programlisting></para> </programlisting></para>
<para>As such the remember-me token is valid only for the period <para>As such the remember-me token is valid only for the period specified, and provided
specified, and provided that the username, password and key does not that the username, password and key does not change. Notably, this has a potential
change. Notably, this has a potential security issue in that a security issue in that a captured remember-me token will be usable from any user agent
captured remember-me token will be usable from any user agent until until such time as the token expires. This is the same issue as with digest
such time as the token expires. This is the same issue as with digest authentication. If a principal is aware a token has been captured, they can easily
authentication. If a principal is aware a token has been captured, change their password and immediately invalidate all remember-me tokens on issue. If
they can easily change their password and immediately invalidate all more significant security is needed you should use the approach described in the next
remember-me tokens on issue. If more significant security is section. Alternatively remember-me services should simply not be used at all.</para>
needed you should use the approach described in the next section. Alternatively <para>If you are familiar with the topics discussed in the chapter on <link
remember-me services should simply not be used at all.</para> xlink:href="ns-config">namespace configuration</link>, you can enable remember-me
authentication just by adding the <literal>&lt;remember-me&gt;</literal> element: <programlisting><![CDATA[
<para>If you are familiar with the topics discussed in the chapter on <link xlink:href="ns-config">namespace configuration</link>,
you can enable remember-me authentication just by adding the <literal>&lt;remember-me&gt;</literal> element:
<programlisting><![CDATA[
<http> <http>
... ...
<remember-me key="myAppKey"/> <remember-me key="myAppKey"/>
</http> </http>
]]> ]]>
</programlisting> </programlisting> The <interfacename>UserDetailsService</interfacename> will
The <interfacename>UserDetailsService</interfacename> will normally be selected automatically. If you have more than one in normally be selected automatically. If you have more than one in your application
your application context, you need to specify which one should be used with the <literal>user-service-ref</literal> attribute, context, you need to specify which one should be used with the
where the value is the name of your <interfacename>UserDetailsService</interfacename> bean. <literal>user-service-ref</literal> attribute, where the value is the name of your
</para> <interfacename>UserDetailsService</interfacename> bean. </para>
</section> </section>
<section xml:id="remember-me-persistent-token"> <section xml:id="remember-me-persistent-token">
<title>Persistent Token Approach</title> <title>Persistent Token Approach</title>
<para>This approach is based on the article <para>This approach is based on the article <link
<link xlink:href="http://jaspan.com/improved_persistent_login_cookie_best_practice">http://jaspan.com/improved_persistent_login_cookie_best_practice</link> xlink:href="http://jaspan.com/improved_persistent_login_cookie_best_practice"
with some minor modifications <footnote><para>Essentially, the username is not included in the cookie, to prevent exposing a valid login >http://jaspan.com/improved_persistent_login_cookie_best_practice</link> with some
name unecessarily. There is a discussion on this in the comments section of this article.</para></footnote>. minor modifications <footnote><para>Essentially, the username is not included in the
To use the this approach with namespace configuration, you would supply a datasource reference: cookie, to prevent exposing a valid login name unecessarily. There is a
<programlisting><![CDATA[ discussion on this in the comments section of this article.</para></footnote>.
To use the this approach with namespace configuration, you would supply a datasource
reference: <programlisting><![CDATA[
<http> <http>
... ...
<remember-me data-source-ref="someDataSource"/> <remember-me data-source-ref="someDataSource"/>
</http> </http>
]]> ]]>
</programlisting> </programlisting> The database should contain a
The database should contain a <literal>persistent_logins</literal> table, created using the following SQL (or equivalent): <literal>persistent_logins</literal> table, created using the following SQL (or
<programlisting> equivalent):
<programlisting>
create table persistent_logins (username varchar(64) not null, series varchar(64) primary key, token varchar(64) not null, last_used timestamp not null) create table persistent_logins (username varchar(64) not null, series varchar(64) primary key, token varchar(64) not null, last_used timestamp not null)
</programlisting> </programlisting></para>
</para>
<!-- TODO: Add more info on the implementation and behaviour when tokens are stolen etc. Also some info for admins on invalidating tokens using key, or deleting info from db --> <!-- TODO: Add more info on the implementation and behaviour when tokens are stolen etc. Also some info for admins on invalidating tokens using key, or deleting info from db -->
</section> </section>
<section xml:id="remember-me-impls">
<section xml:id="remember-me-impls"> <info>
<info><title>Remember-Me Interfaces and Implementations</title></info> <title>Remember-Me Interfaces and Implementations</title>
</info>
<para>Remember-me authentication is not used with basic <para>Remember-me authentication is not used with basic authentication, given it is often
authentication, given it is often not used with not used with <literal>HttpSession</literal>s. Remember-me is used with
<literal>HttpSession</literal>s. Remember-me is used with <literal>UsernamePasswordAuthenticationFilter</literal>, and is implemented via
<literal>UsernamePasswordAuthenticationFilter</literal>, and is implemented hooks in the <literal>AbstractAuthenticationProcessingFilter</literal> superclass. The
via hooks in the <literal>AbstractAuthenticationProcessingFilter</literal> hooks will invoke a concrete <interfacename>RememberMeServices</interfacename> at the
superclass. The hooks will invoke a concrete appropriate times. The interface looks like this:
<interfacename>RememberMeServices</interfacename> at the appropriate times. The <programlisting language="java">
interface looks like this:
<programlisting language="java">
Authentication autoLogin(HttpServletRequest request, HttpServletResponse response); Authentication autoLogin(HttpServletRequest request, HttpServletResponse response);
void loginFail(HttpServletRequest request, HttpServletResponse response); void loginFail(HttpServletRequest request, HttpServletResponse response);
void loginSuccess(HttpServletRequest request, HttpServletResponse response, void loginSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication successfulAuthentication); Authentication successfulAuthentication);
</programlisting> </programlisting>
Please refer to the JavaDocs for a fuller discussion on what the Please refer to the JavaDocs for a fuller discussion on what the methods do, although
methods do, although note at this stage that note at this stage that <literal>AbstractAuthenticationProcessingFilter</literal> only
<literal>AbstractAuthenticationProcessingFilter</literal> only calls the calls the <literal>loginFail()</literal> and <literal>loginSuccess()</literal> methods.
<literal>loginFail()</literal> and <literal>loginSuccess()</literal> The <literal>autoLogin()</literal> method is called by
methods. The <literal>autoLogin()</literal> method is called by <classname>RememberMeAuthenticationFilter</classname> whenever the
<classname>RememberMeProcessingFilter</classname> whenever the <classname>SecurityContextHolder</classname> does not contain an
<classname>SecurityContextHolder</classname> does not contain an <interfacename>Authentication</interfacename>. This interface therefore provides the
<interfacename>Authentication</interfacename>. This interface therefore provides underlying remember-me implementation with sufficient notification of
the underlying remember-me implementation with sufficient authentication-related events, and delegates to the implementation whenever a candidate
notification of authentication-related events, and delegates to the web request might contain a cookie and wish to be remembered. This design allows any
implementation whenever a candidate web request might contain a cookie number of remember-me implementation strategies. We've seen above that Spring Security
and wish to be remembered. This design allows any number of remember-me implementation provides two implementations. We'll look at thes in turn.</para>
strategies. We've seen above that Spring Security provides
two implementations. We'll look at thes in turn.</para>
<section> <section>
<title>TokenBasedRememberMeServices</title> <title>TokenBasedRememberMeServices</title>
<para> <para> This implementation supports the simpler approach described in <xref
This implementation supports the simpler approach described in <xref linkend="remember-me-hash-token"/>. linkend="remember-me-hash-token"/>.
<classname>TokenBasedRememberMeServices</classname> generates a <classname>TokenBasedRememberMeServices</classname> generates a
<literal>RememberMeAuthenticationToken</literal>, which is processed <literal>RememberMeAuthenticationToken</literal>, which is processed by
by <literal>RememberMeAuthenticationProvider</literal>. A <literal>RememberMeAuthenticationProvider</literal>. A <literal>key</literal> is
<literal>key</literal> is shared between this authentication provider shared between this authentication provider and the
and the <literal>TokenBasedRememberMeServices</literal>. In addition, <literal>TokenBasedRememberMeServices</literal>. In addition,
<literal>TokenBasedRememberMeServices</literal> requires A <literal>TokenBasedRememberMeServices</literal> requires A UserDetailsService
UserDetailsService from which it can retrieve the username and from which it can retrieve the username and password for signature comparison
password for signature comparison purposes, and generate the purposes, and generate the <literal>RememberMeAuthenticationToken</literal> to
<literal>RememberMeAuthenticationToken</literal> to contain the contain the correct <interfacename>GrantedAuthority</interfacename>[]s. Some sort of
correct <interfacename>GrantedAuthority</interfacename>[]s. Some sort of logout logout command should be provided by the application that invalidates the cookie if
command should be provided by the application that invalidates the cookie if the user requests this. <classname>TokenBasedRememberMeServices</classname> also
the user requests this. <classname>TokenBasedRememberMeServices</classname> also implements Spring Security's implements Spring Security's <interfacename>LogoutHandler</interfacename> interface
<interfacename>LogoutHandler</interfacename> interface so can be used with <classname>LogoutFilter</classname> so can be used with <classname>LogoutFilter</classname> to have the cookie cleared
to have the cookie cleared automatically. automatically. </para>
</para> <para>The beans required in an application context to enable remember-me services are as
<para>The beans required in an application context to enable remember-me services are as follows: follows: <programlisting language="xml"><![CDATA[
<programlisting language="xml"><![CDATA[ <bean id="rememberMeFilter" class=
<bean id="rememberMeProcessingFilter" class= "org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter">
"org.springframework.security.web.authentication.rememberme.RememberMeProcessingFilter">
<property name="rememberMeServices" ref="rememberMeServices"/> <property name="rememberMeServices" ref="rememberMeServices"/>
<property name="authenticationManager" ref="theAuthenticationManager" /> <property name="authenticationManager" ref="theAuthenticationManager" />
</bean> </bean>
@ -157,27 +148,26 @@
</bean> </bean>
]]> ]]>
</programlisting>Don't forget to add your </programlisting>Don't forget to add your
<interfacename>RememberMeServices</interfacename> implementation to your <interfacename>RememberMeServices</interfacename> implementation to your
<literal>UsernamePasswordAuthenticationFilter.setRememberMeServices()</literal> <literal>UsernamePasswordAuthenticationFilter.setRememberMeServices()</literal>
property, include the property, include the <literal>RememberMeAuthenticationProvider</literal> in your
<literal>RememberMeAuthenticationProvider</literal> in your <literal>AuthenticationManager.setProviders()</literal> list, and add
<literal>AuthenticationManager.setProviders()</literal> list, and add <classname>RememberMeAuthenticationFilter</classname> into your
<classname>RememberMeProcessingFilter</classname> into your <classname>FilterChainProxy</classname> (typically immediately after your
<classname>FilterChainProxy</classname> (typically immediately after your <literal>UsernamePasswordAuthenticationFilter</literal>).</para>
<literal>UsernamePasswordAuthenticationFilter</literal>).</para>
</section> </section>
<section> <section>
<title>PersistentTokenBasedRememberMeServices</title> <title>PersistentTokenBasedRememberMeServices</title>
<para> <para> This class can be used in the same way as
This class can be used in the same way as <classname>TokenBasedRememberMeServices</classname>, but it additionally <classname>TokenBasedRememberMeServices</classname>, but it additionally needs
needs to be configured with a <interfacename>PersistentTokenRepository</interfacename> to store the tokens. to be configured with a <interfacename>PersistentTokenRepository</interfacename> to
There are two standard implementations. store the tokens. There are two standard implementations.
<itemizedlist> <itemizedlist><listitem><para><classname>InMemoryTokenRepositoryImpl</classname>
<listitem><para><classname>InMemoryTokenRepositoryImpl</classname> which is intended for testing only.</para></listitem> which is intended for testing
<listitem><para><classname>JdbcTokenRepositoryImpl</classname> which stores the tokens in a database. </para></listitem> only.</para></listitem><listitem><para><classname>JdbcTokenRepositoryImpl</classname>
</itemizedlist> which stores the tokens in a database. </para></listitem></itemizedlist>
The database schema is described above in <xref linkend="remember-me-persistent-token"/>. The database schema is described above in <xref
</para> linkend="remember-me-persistent-token"/>. </para>
</section> </section>
</section> </section>
</chapter> </chapter>

View File

@ -6,27 +6,27 @@
<para>Spring Security's web infrastructure is based entirely on standard servlet filters. It <para>Spring Security's web infrastructure is based entirely on standard servlet filters. It
doesn't use servlets or any other servlet-based frameworks (such as Spring MVC) internally, so doesn't use servlets or any other servlet-based frameworks (such as Spring MVC) internally, so
it has no strong links to any particular web technology. It deals in it has no strong links to any particular web technology. It deals in
<classname>HttpServletRequest</classname>s and <classname>HttpServletResponse</classname>s <classname>HttpServletRequest</classname>s and <classname>HttpServletResponse</classname>s and
and doesn't care whether the requests come from a browser, a web service client, an doesn't care whether the requests come from a browser, a web service client, an
<classname>HttpInvoker</classname> or an AJAX application. </para> <classname>HttpInvoker</classname> or an AJAX application. </para>
<para> Spring Security maintains a filter chain internally where each of the filters has a <para> Spring Security maintains a filter chain internally where each of the filters has a
particular responsibility and filters are added or removed from the configuration depending on particular responsibility and filters are added or removed from the configuration depending on
which services are required. The ordering of the filters is important as there are which services are required. The ordering of the filters is important as there are dependencies
dependencies between them. If you have been using <link xlink:href="#ns-config">namespace between them. If you have been using <link xlink:href="#ns-config">namespace
configuration</link>, then the filters are automatically configured for you and you don't configuration</link>, then the filters are automatically configured for you and you don't have
have to define any Spring beans explicitly but here may be times when you want full control to define any Spring beans explicitly but here may be times when you want full control over the
over the security filter chain, either because you are using features which aren't supported security filter chain, either because you are using features which aren't supported in the
in the namespace, or you are using your own customized versions of classes.</para> namespace, or you are using your own customized versions of classes.</para>
<section xml:id="delegating-filter-proxy"> <section xml:id="delegating-filter-proxy">
<title><classname>DelegatingFilterProxy</classname></title> <title><classname>DelegatingFilterProxy</classname></title>
<para> When using servlet filters, you obviously need to declare them in your <para> When using servlet filters, you obviously need to declare them in your
<filename>web.xml</filename>, or they will be ignored by the servlet container. In Spring <filename>web.xml</filename>, or they will be ignored by the servlet container. In Spring
Security, the filter classes are also Spring beans defined in the application context and Security, the filter classes are also Spring beans defined in the application context and thus
thus able to take advantage of Spring's rich dependency-injection facilities and lifecycle able to take advantage of Spring's rich dependency-injection facilities and lifecycle
interfaces. Spring's <classname>DelegatingFilterProxy</classname> provides the link between interfaces. Spring's <classname>DelegatingFilterProxy</classname> provides the link between
<filename>web.xml</filename> and the application context. </para> <filename>web.xml</filename> and the application context. </para>
<para>When using <classname>DelegatingFilterProxy</classname>, you will see something like <para>When using <classname>DelegatingFilterProxy</classname>, you will see something like this
this in the <filename>web.xml</filename> file: <programlisting><![CDATA[ in the <filename>web.xml</filename> file: <programlisting><![CDATA[
<filter> <filter>
<filter-name>myFilter</filter-name> <filter-name>myFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
@ -37,11 +37,11 @@
<url-pattern>/*</url-pattern> <url-pattern>/*</url-pattern>
</filter-mapping>]]> </filter-mapping>]]>
</programlisting> Notice that the filter is actually a </programlisting> Notice that the filter is actually a
<literal>DelegatingFilterProxy</literal>, and not the class that will actually implement <literal>DelegatingFilterProxy</literal>, and not the class that will actually implement the
the logic of the filter. What <classname>DelegatingFilterProxy</classname> does is delegate logic of the filter. What <classname>DelegatingFilterProxy</classname> does is delegate the
the <interfacename>Filter</interfacename>'s methods through to a bean which is obtained from <interfacename>Filter</interfacename>'s methods through to a bean which is obtained from the
the Spring application context. This enables the bean to benefit from the Spring web Spring application context. This enables the bean to benefit from the Spring web application
application context lifecycle support and configuration flexibility. The bean must implement context lifecycle support and configuration flexibility. The bean must implement
<interfacename>javax.servlet.Filter</interfacename> and it must have the same name as that <interfacename>javax.servlet.Filter</interfacename> and it must have the same name as that
in the <literal>filter-name</literal> element. Read the Javadoc for in the <literal>filter-name</literal> element. Read the Javadoc for
<classname>DelegatingFilterProxy</classname> for more information</para> <classname>DelegatingFilterProxy</classname> for more information</para>
@ -50,11 +50,11 @@
<title><classname>FilterChainProxy</classname></title> <title><classname>FilterChainProxy</classname></title>
<para> It should now be clear that you can declare each Spring Security filter bean that you <para> It should now be clear that you can declare each Spring Security filter bean that you
require in your application context file and add a corresponding require in your application context file and add a corresponding
<classname>DelegatingFilterProxy</classname> entry to <filename>web.xml</filename> for <classname>DelegatingFilterProxy</classname> entry to <filename>web.xml</filename> for each
each filter, making sure that they are ordered correctly. This is a cumbersome approach and filter, making sure that they are ordered correctly. This is a cumbersome approach and
clutters up the <filename>web.xml</filename> file quickly if we have a lot of filters. We clutters up the <filename>web.xml</filename> file quickly if we have a lot of filters. We
would prefer to just add a single entry to <filename>web.xml</filename> and deal entirely would prefer to just add a single entry to <filename>web.xml</filename> and deal entirely with
with the application context file for managing our web security beans. This is where Spring the application context file for managing our web security beans. This is where Spring
Secuiryt's <classname>FilterChainProxy</classname> comes in. It is wired using a Secuiryt's <classname>FilterChainProxy</classname> comes in. It is wired using a
<literal>DelegatingFilterProxy</literal>, just like in the example above, but with the <literal>DelegatingFilterProxy</literal>, just like in the example above, but with the
<literal>filter-name</literal> set to the bean name <quote>filterChainProxy</quote>. The <literal>filter-name</literal> set to the bean name <quote>filterChainProxy</quote>. The
@ -64,24 +64,24 @@
<sec:filter-chain-map path-type="ant"> <sec:filter-chain-map path-type="ant">
<sec:filter-chain pattern="/webServices/**" filters=" <sec:filter-chain pattern="/webServices/**" filters="
securityContextPersistenceFilterWithASCFalse, securityContextPersistenceFilterWithASCFalse,
basicProcessingFilter, basicAuthenticationFilter,
exceptionTranslationFilter, exceptionTranslationFilter,
filterSecurityInterceptor" /> filterSecurityInterceptor" />
<sec:filter-chain pattern="/**" filters=" <sec:filter-chain pattern="/**" filters="
securityContextPersistenceFilterWithASCTrue, securityContextPersistenceFilterWithASCTrue,
authenticationProcessingFilter, formLoginFilter,
exceptionTranslationFilter, exceptionTranslationFilter,
filterSecurityInterceptor" /> filterSecurityInterceptor" />
</sec:filter-chain-map> </sec:filter-chain-map>
</bean> </bean>
]]> ]]>
</programlisting> The namespace element <literal>filter-chain-map</literal> is </programlisting> The namespace element <literal>filter-chain-map</literal> is used
used to set up the security filter chain(s) which are required within the application<footnote> to set up the security filter chain(s) which are required within the
<para>Note that you'll need to include the security namespace in your application context application<footnote><para>Note that you'll need to include the security namespace in your
XML file in order to use this syntax.</para> application context XML file in order to use this syntax.</para></footnote>. It maps a
</footnote>. It maps a particular URL pattern to a chain of filters built up from the bean particular URL pattern to a chain of filters built up from the bean names specified in the
names specified in the <literal>filters</literal> element. Both regular expressions and Ant <literal>filters</literal> element. Both regular expressions and Ant Paths are supported,
Paths are supported, and the most specific URIs appear first. At runtime the and the most specific URIs appear first. At runtime the
<classname>FilterChainProxy</classname> will locate the first URI pattern that matches the <classname>FilterChainProxy</classname> will locate the first URI pattern that matches the
current web request and the list of filter beans specified by the <literal>filters</literal> current web request and the list of filter beans specified by the <literal>filters</literal>
attribute will be applied to that request. The filters will be invoked in the order they are attribute will be applied to that request. The filters will be invoked in the order they are
@ -89,112 +89,92 @@
URL.</para> URL.</para>
<para>You may have noticed we have declared two <para>You may have noticed we have declared two
<classname>SecurityContextPersistenceFilter</classname>s in the filter chain <classname>SecurityContextPersistenceFilter</classname>s in the filter chain
(<literal>ASC</literal> is short for <literal>allowSessionCreation</literal>, a property (<literal>ASC</literal> is short for <literal>allowSessionCreation</literal>, a property of
of <classname>SecurityContextPersistenceFilter</classname>). As web services will never <classname>SecurityContextPersistenceFilter</classname>). As web services will never present
present a <literal>jsessionid</literal> on future requests, creating a <literal>jsessionid</literal> on future requests, creating <literal>HttpSession</literal>s
<literal>HttpSession</literal>s for such user agents would be wasteful. If you had a for such user agents would be wasteful. If you had a high-volume application which required
high-volume application which required maximum scalability, we recommend you use the maximum scalability, we recommend you use the approach shown above. For smaller applications,
approach shown above. For smaller applications, using a single using a single <classname>SecurityContextPersistenceFilter</classname> (with its default
<classname>SecurityContextPersistenceFilter</classname> (with its default
<literal>allowSessionCreation</literal> as <literal>true</literal>) would likely be <literal>allowSessionCreation</literal> as <literal>true</literal>) would likely be
sufficient.</para> sufficient.</para>
<para>In relation to lifecycle issues, the <classname>FilterChainProxy</classname> will always <para>In relation to lifecycle issues, the <classname>FilterChainProxy</classname> will always
delegate <methodname>init(FilterConfig)</methodname> and <methodname>destroy()</methodname> delegate <methodname>init(FilterConfig)</methodname> and <methodname>destroy()</methodname>
methods through to the underlaying <interfacename>Filter</interfacename>s if such methods methods through to the underlaying <interfacename>Filter</interfacename>s if such methods are
are called against <classname>FilterChainProxy</classname> itself. In this case, called against <classname>FilterChainProxy</classname> itself. In this case,
<classname>FilterChainProxy</classname> guarantees to only initialize and destroy each <classname>FilterChainProxy</classname> guarantees to only initialize and destroy each
<literal>Filter</literal> bean once, no matter how many times it is declared in the filter <literal>Filter</literal> bean once, no matter how many times it is declared in the filter
chain(s). You control the overall choice as to whether these methods are called or not via chain(s). You control the overall choice as to whether these methods are called or not via the
the <literal>targetFilterLifecycle</literal> initialization parameter of <literal>targetFilterLifecycle</literal> initialization parameter of
<literal>DelegatingFilterProxy</literal>. By default this property is <literal>DelegatingFilterProxy</literal>. By default this property is
<literal>false</literal> and servlet container lifecycle invocations are not delegated <literal>false</literal> and servlet container lifecycle invocations are not delegated
through <literal>DelegatingFilterProxy</literal>.</para> through <literal>DelegatingFilterProxy</literal>.</para>
<para> When we looked at how to set up web security using <link <para> When we looked at how to set up web security using <link xlink:href="#ns-web-xml"
xlink:href="#ns-web-xml">namespace configuration</link>, we used a >namespace configuration</link>, we used a <literal>DelegatingFilterProxy</literal> with the
<literal>DelegatingFilterProxy</literal> with the name name <quote>springSecurityFilterChain</quote>. You should now be able to see that this is the
<quote>springSecurityFilterChain</quote>. You should now be able to see that this is the
name of the <classname>FilterChainProxy</classname> which is created by the namespace. </para> name of the <classname>FilterChainProxy</classname> which is created by the namespace. </para>
<section> <section>
<title>Bypassing the Filter Chain</title> <title>Bypassing the Filter Chain</title>
<para> As with the namespace, you can use the attribute <literal>filters = "none"</literal> <para> As with the namespace, you can use the attribute <literal>filters = "none"</literal> as
as an alternative to supplying a filter bean list. This will omit the request pattern from an alternative to supplying a filter bean list. This will omit the request pattern from the
the security filter chain entirely. Note that anything matching this path will then have security filter chain entirely. Note that anything matching this path will then have no
no authentication or authorization services applied and will be freely accessible. If you authentication or authorization services applied and will be freely accessible. If you want
want to make use of the contents of the <classname>SecurityContext</classname> contents to make use of the contents of the <classname>SecurityContext</classname> contents during a
during a request, then it must have passed through the security filter chain. Otherwise request, then it must have passed through the security filter chain. Otherwise the
the <classname>SecurityContextHolder</classname> will not have been populated and the <classname>SecurityContextHolder</classname> will not have been populated and the contents
contents will be null.</para> will be null.</para>
</section> </section>
</section> </section>
<section> <section>
<title>Filter Ordering</title> <title>Filter Ordering</title>
<para>The order that filters are defined in the chain is very important. Irrespective of which <para>The order that filters are defined in the chain is very important. Irrespective of which
filters you are actually using, the order should be as follows: filters you are actually using, the order should be as follows:
<orderedlist> <orderedlist><listitem><para><classname>ChannelProcessingFilter</classname>, because
<listitem> it might need to redirect to a different
<para><classname>ChannelProcessingFilter</classname>, because it might need to redirect protocol</para></listitem><listitem><para><classname>ConcurrentSessionFilter</classname>,
to a different protocol</para> because it doesn't use any <classname>SecurityContextHolder</classname> functionality
</listitem> but needs to update the <interfacename>SessionRegistry</interfacename> to reflect
<listitem> ongoing requests from the
<para><classname>ConcurrentSessionFilter</classname>, because it doesn't use any principal</para></listitem><listitem><para><classname>SecurityContextPersistenceFilter</classname>,
<classname>SecurityContextHolder</classname> functionality but needs to update the so a <interfacename>SecurityContext</interfacename> can be set up in the
<interfacename>SessionRegistry</interfacename> to reflect ongoing requests from the
principal</para>
</listitem>
<listitem>
<para><classname>SecurityContextPersistenceFilter</classname>, so a
<interfacename>SecurityContext</interfacename> can be set up in the
<classname>SecurityContextHolder</classname> at the beginning of a web request, and <classname>SecurityContextHolder</classname> at the beginning of a web request, and
any changes to the <interfacename>SecurityContext</interfacename> can be copied to the any changes to the <interfacename>SecurityContext</interfacename> can be copied to the
<literal>HttpSession</literal> when the web request ends (ready for use with the <literal>HttpSession</literal> when the web request ends (ready for use with the next
next web request)</para> web request)</para></listitem><listitem><para>Authentication processing mechanisms -
</listitem>
<listitem>
<para>Authentication processing mechanisms -
<classname>UsernamePasswordAuthenticationFilter</classname>, <classname>UsernamePasswordAuthenticationFilter</classname>,
<classname>CasProcessingFilter</classname>, <classname>CasAuthenticationFilter</classname>,
<classname>BasicProcessingFilter</classname> etc - so that the <classname>BasicAuthenticationFilter</classname> etc - so that the
<classname>SecurityContextHolder</classname> can be modified to contain a valid <classname>SecurityContextHolder</classname> can be modified to contain a valid
<interfacename>Authentication</interfacename> request token</para> <interfacename>Authentication</interfacename> request
</listitem> token</para></listitem><listitem><para>The
<listitem> <literal>SecurityContextHolderAwareRequestFilter</literal>, if you are using it to
<para>The <literal>SecurityContextHolderAwareRequestFilter</literal>, if you are using install a Spring Security aware <literal>HttpServletRequestWrapper</literal> into your
it to install a Spring Security aware <literal>HttpServletRequestWrapper</literal> servlet
into your servlet container</para> container</para></listitem><listitem><para><classname>RememberMeAuthenticationFilter</classname>,
</listitem> so that if no earlier authentication processing mechanism updated the
<listitem>
<para><classname>RememberMeProcessingFilter</classname>, so that if no earlier
authentication processing mechanism updated the
<classname>SecurityContextHolder</classname>, and the request presents a cookie that <classname>SecurityContextHolder</classname>, and the request presents a cookie that
enables remember-me services to take place, a suitable remembered enables remember-me services to take place, a suitable remembered
<interfacename>Authentication</interfacename> object will be put there</para> <interfacename>Authentication</interfacename> object will be put
</listitem> there</para></listitem><listitem><para><classname>AnonymousAuthenticationFilter</classname>,
<listitem> so that if no earlier authentication processing mechanism updated the
<para><classname>AnonymousProcessingFilter</classname>, so that if no earlier
authentication processing mechanism updated the
<classname>SecurityContextHolder</classname>, an anonymous <classname>SecurityContextHolder</classname>, an anonymous
<interfacename>Authentication</interfacename> object will be put there</para> <interfacename>Authentication</interfacename> object will be put
</listitem> there</para></listitem><listitem><para><classname>ExceptionTranslationFilter</classname>,
<listitem> to catch any Spring Security exceptions so that either an HTTP error response can be
<para><classname>ExceptionTranslationFilter</classname>, to catch any Spring Security returned or an appropriate <interfacename>AuthenticationEntryPoint</interfacename> can
exceptions so that either an HTTP error response can be returned or an appropriate be
<interfacename>AuthenticationEntryPoint</interfacename> can be launched</para> launched</para></listitem><listitem><para><classname>FilterSecurityInterceptor</classname>,
</listitem> to protect web URIs and raise exceptions when access is
<listitem> denied</para></listitem></orderedlist></para>
<para><classname>FilterSecurityInterceptor</classname>, to protect web URIs and raise
exceptions when access is denied</para>
</listitem>
</orderedlist></para>
</section> </section>
<section> <section>
<title>Use with other Filter-Based Frameworks</title> <title>Use with other Filter-Based Frameworks</title>
<para>If you're using some other framework that is also filter-based, then you need to make <para>If you're using some other framework that is also filter-based, then you need to make sure
sure that the Spring Security filters come first. This enables the that the Spring Security filters come first. This enables the
<classname>SecurityContextHolder</classname> to be populated in time for use by the other <classname>SecurityContextHolder</classname> to be populated in time for use by the other
filters. Examples are the use of SiteMesh to decorate your web pages or a web framework like filters. Examples are the use of SiteMesh to decorate your web pages or a web framework like
Wicket which uses a filter to handle its requests. </para> Wicket which uses a filter to handle its requests. </para>
</section> </section>
<!-- <!--
<section xml:id="taglib"> <section xml:id="taglib">
<info> <info>
<title>Tag Libraries</title> <title>Tag Libraries</title>

View File

@ -35,11 +35,11 @@
<para> <para>
<interfacename>SessionAuthenticationStrategy</interfacename> is used by both <interfacename>SessionAuthenticationStrategy</interfacename> is used by both
<classname>SessionManagementFilter</classname> and <classname>SessionManagementFilter</classname> and
<classname>AbstractAutheticationProcessingFilter</classname>, so if you are using a <classname>AbstractAuthenticationProcessingFilter</classname>, so if you are using a
customized form-login class, for example, you will need to inject it into both of these. In customized form-login class, for example, you will need to inject it into both of these. In
this case, a typical configuration, combining the namespace and custom beans might look like this:<programlisting><![CDATA[ this case, a typical configuration, combining the namespace and custom beans might look like this:<programlisting><![CDATA[
<http> <http>
<custom-filter position="AUTHENTICATION_PROCESSING_FILTER" ref="myAuthFilter" /> <custom-filter position="FORM_LOGIN_FILTER" ref="myAuthFilter" />
<session-management session-authentication-strategy-ref="sas"/> <session-management session-authentication-strategy-ref="sas"/>
</http> </http>