mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-05-31 09:12:14 +00:00
Updated docs to reflect changes for SEC-1259
This commit is contained in:
parent
80eb47c6fe
commit
73905b9ebd
@ -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>
|
||||||
|
@ -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><intercept-url></literal> element, then a
|
<literal><intercept-url></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><http-basic></literal> Element</title>
|
<title>The <literal><http-basic></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><remember-me></literal> Element</title>
|
<title>The <literal><remember-me></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><anonymous></literal> Element</title>
|
<title>The <literal><anonymous></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><x509></literal> Element</title>
|
<title>The <literal><x509></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>
|
||||||
|
@ -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>
|
||||||
|
@ -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>
|
||||||
|
@ -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"/>
|
||||||
|
@ -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><http></literal> configuration, so the <literal><anonymous
|
<literal><http></literal> configuration, so the <literal><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"/>
|
||||||
|
@ -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><security-role></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><security-role></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>
|
||||||
|
@ -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><remember-me></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><remember-me></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>
|
||||||
|
@ -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>
|
||||||
|
@ -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>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user