Intermediate ref manual commits

This commit is contained in:
Luke Taylor 2009-06-12 10:45:21 +00:00
parent d5aec71fac
commit 8d4c09c191
8 changed files with 704 additions and 1361 deletions

View File

@ -1,139 +1,71 @@
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="authentication-common-auth-services" xmlns:xlink="http://www.w3.org/1999/xlink">
<info><title>Common Authentication Services</title></info>
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0"
xml:id="authentication-common-auth-services" xmlns:xlink="http://www.w3.org/1999/xlink">
<info>
<title>Common Authentication Services</title>
</info>
<section xml:id="mechanisms-providers-entry-points">
<info>
<title>Mechanisms, Providers and Entry Points</title>
</info>
<para>To use Spring Security's authentication services,
you'll usually need to configure a web filter, together
with an <classname>AuthenticationProvider</classname> and
<interfacename>AuthenticationEntryPoint</interfacename>. In this section we are
going to explore an example application that needs to support both
form-based authentication (so a nice HTML page is presented to a
user for them to login) and BASIC authentication (so a web service
or similar can access protected resources).</para>
<para>In the web.xml, this application will need a single Spring
Security filter in order to use the FilterChainProxy. Nearly every
Spring Security application will have such an entry, and it looks like
this:</para>
<para><programlisting><![CDATA[
<filter>
<filter-name>filterChainProxy</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>filterChainProxy</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>]]>
</programlisting></para>
<para>The above declarations will cause every web request to be passed
through to the bean called <literal>filterChainProxy</literal>
which will usually be an instance of Spring Security's
<classname>FilterChainProxy</classname>.
As explained in the filters section of this reference guide, the
<classname>FilterChainProxy</classname> is a generally-useful class
that enables web requests to be passed to different filters based on
URL patterns. Those delegated filters are managed inside the
application context, so they can benefit from dependency injection.
Let's have a look at what the FilterChainProxy bean definition would
look like inside your application context:</para>
<para><programlisting><![CDATA[
<bean id="filterChainProxy"
class="org.springframework.security.web.FilterChainProxy">
<security:filter-chain-map path-type="ant">
<security:filter-chain pattern="/**" filters="
securityContextPersistenceFilter,
logoutFilter,
authenticationProcessingFilter,
basicProcessingFilter,
securityContextHolderAwareRequestFilter,
rememberMeProcessingFilter,
anonymousProcessingFilter,
exceptionTranslationFilter,
filterInvocationInterceptor,
switchUserProcessingFilter"/>
</security:filter-chain-map>
</bean>]]></programlisting></para>
<para>The <literal>filter-chain-map</literal> syntax from the security namespace
allows you to define the mapping from URLs to filter chains, using a sequence of
<literal>filter-chain</literal> child elements. Each of these defines a set of URLs using
the <literal>pattern</literal> attribute and a chain of filters using the <literal>filters</literal>
attribute.What's important to note at this stage is that a series of filters will be
run - in the order specified by the declaration - and each of those
filters are actually the <literal>id</literal> of another
bean in the application context. So, in our case some extra beans
will also appear in the application context, and they'll be named
<literal>httpSessionContextIntegrationFilter</literal>,
<literal>logoutFilter</literal> and so on. The order that the filters
should appear is discussed in the filters section of the reference
guide - although they are correct in the above example.</para>
<para>To use Spring Security's authentication services, you'll usually need to configure a web
filter, together with an <classname>AuthenticationProvider</classname> and
<interfacename>AuthenticationEntryPoint</interfacename>. In this section we are going to
explore an example application that needs to support both form-based authentication (so a nice
HTML page is presented to a user for them to login) and BASIC authentication (so a web service
or similar can access protected resources).</para>
<para>The <literal>filter-chain-map</literal> syntax from the security namespace allows you to
define the mapping from URLs to filter chains, using a sequence of
<literal>filter-chain</literal> child elements. Each of these defines a set of URLs using
the <literal>pattern</literal> attribute and a chain of filters using the
<literal>filters</literal> attribute.What's important to note at this stage is that a series
of filters will be run - in the order specified by the declaration - and each of those filters
are actually the <literal>id</literal> of another bean in the application context. So, in our
case some extra beans will also appear in the application context, and they'll be named
<literal>httpSessionContextIntegrationFilter</literal>, <literal>logoutFilter</literal> and
so on. The order that the filters should appear is discussed in the filters section of the
reference guide - although they are correct in the above example.</para>
<para>In our example we have the
<literal>UsernamePasswordAuthenticationProcessingFilter</literal> and
<literal>BasicProcessingFilter</literal> being used. These are the
"authentication mechanisms" that respond to form-based authentication
and BASIC HTTP header-based authentication respectively (we discussed
the role of authentication mechanisms earlier in this reference
guide). If you weren't using form or BASIC authentication, neither of
these beans would be defined. You'd instead define filters applicable
to your desired authentication environment, such as
<literal>DigestProcessingFilter</literal> or
<literal>CasProcessingFilter</literal>. Refer to the individual
chapters of this part of the reference guide to learn how to configure
each of these authentication mechanisms.</para>
<para>Recall that
<classname>HttpSessionContextIntegrationFilter</classname> keeps the
contents of the <interfacename>SecurityContext</interfacename> between invocations
inside an HTTP session. This means the authentication mechanisms are
only used once, being when the principal initially tries to
authenticate. The rest of the time the authentication mechanisms sit
there and silently pass the request through to the next filter in the
chain. That is a practical requirement due to the fact that few
authentication approaches present credentials on each and every call
(BASIC authentication being a notable exception), but what happens if
a principal's account gets cancelled or disabled or otherwise changed
(eg an increase or decrease in <literal>GrantedAuthority[]</literal>s)
after the initial authentication step? Let's look at how that is
handled now.</para>
<para>The major authorization provider for secure objects has
previously been introduced as
<classname>AbstractSecurityInterceptor</classname>. This class needs to
have access to an <interfacename>AuthenticationManager</interfacename>. It also
has configurable settings to indicate whether an
<interfacename>Authentication</interfacename> object should be re-authenticated on
each secure object invocation. By default it just accepts any
<interfacename>Authentication</interfacename> inside the
<classname>SecurityContextHolder</classname> is authenticated if
<literal>Authentication.isAuthenticated()</literal> returns true. This
is great for performance, but not ideal if you want to ensure
up-to-the-moment authentication validity. For such cases you'll
probably want to set the
<literal>AbstractSecurityInterceptor.alwaysReauthenticate</literal>
property to true.</para>
<literal>UsernamePasswordAuthenticationProcessingFilter</literal> and
<literal>BasicProcessingFilter</literal> being used. These are the "authentication
mechanisms" that respond to form-based authentication and BASIC HTTP header-based
authentication respectively (we discussed the role of authentication mechanisms earlier in
this reference guide). If you weren't using form or BASIC authentication, neither of these
beans would be defined. You'd instead define filters applicable to your desired authentication
environment, such as <literal>DigestProcessingFilter</literal> or
<literal>CasProcessingFilter</literal>. Refer to the individual chapters of this part of the
reference guide to learn how to configure each of these authentication mechanisms.</para>
<para>Recall that <classname>HttpSessionContextIntegrationFilter</classname> keeps the contents
of the <interfacename>SecurityContext</interfacename> between invocations inside an HTTP
session. This means the authentication mechanisms are only used once, being when the principal
initially tries to authenticate. The rest of the time the authentication mechanisms sit there
and silently pass the request through to the next filter in the chain. That is a practical
requirement due to the fact that few authentication approaches present credentials on each and
every call (BASIC authentication being a notable exception), but what happens if a principal's
account gets cancelled or disabled or otherwise changed (eg an increase or decrease in
<literal>GrantedAuthority[]</literal>s) after the initial authentication step? Let's look at
how that is handled now.</para>
<para>The major authorization provider for secure objects has previously been introduced as
<classname>AbstractSecurityInterceptor</classname>. This class needs to have access to an
<interfacename>AuthenticationManager</interfacename>. It also has configurable settings to
indicate whether an <interfacename>Authentication</interfacename> object should be
re-authenticated on each secure object invocation. By default it just accepts any
<interfacename>Authentication</interfacename> inside the
<classname>SecurityContextHolder</classname> is authenticated if
<literal>Authentication.isAuthenticated()</literal> returns true. This is great for
performance, but not ideal if you want to ensure up-to-the-moment authentication validity. For
such cases you'll probably want to set the
<literal>AbstractSecurityInterceptor.alwaysReauthenticate</literal> property to true.</para>
<para>You might be asking yourself, "what's this
<interfacename>AuthenticationManager</interfacename>?". We haven't explored it
before, but we have discussed the concept of an
<classname>AuthenticationProvider</classname>. Quite simply, an
<interfacename>AuthenticationManager</interfacename> is responsible
for passing requests through a chain of AuthenticationProviders. It's
a little like the filter chain we discussed earlier, although there
are some differences. There is only one
<interfacename>AuthenticationManager</interfacename> implementation
shipped with Spring Security, so let's look at how it's configured for
the example we're using in this chapter:</para>
<para><programlisting><![CDATA[
<interfacename>AuthenticationManager</interfacename>?". We haven't explored it before, but
we have discussed the concept of an <classname>AuthenticationProvider</classname>. Quite
simply, an <interfacename>AuthenticationManager</interfacename> is responsible for passing
requests through a chain of AuthenticationProviders. It's a little like the filter chain we
discussed earlier, although there are some differences. There is only one
<interfacename>AuthenticationManager</interfacename> implementation shipped with Spring
Security, so let's look at how it's configured for the example we're using in this
chapter:</para>
<para>
<programlisting><![CDATA[
<bean id="authenticationManager"
class="org.springframework.security.authentication.ProviderManager">
<property name="providers">
@ -143,60 +75,47 @@
<ref local="rememberMeAuthenticationProvider"/>
</list>
</property>
</bean>]]></programlisting></para>
<para>It's probably worth mentioning at this point that your
authentication mechanisms (which are usually filters) are also
injected with a reference to the
<interfacename>AuthenticationManager</interfacename>. So both
<classname>AbstractSecurityInterceptor</classname> as well as the
authentication mechanisms will use the above
<literal>ProviderManager</literal> to poll a list of
<classname>AuthenticationProvider</classname>s.</para>
<para>In our example we have three providers. They are tried in the
order shown (which is implied by the use of a <literal>List</literal>
instead of a <literal>Set</literal>), with each provider able to
attempt authentication, or skip authentication by simply returning
<literal>null</literal>. If all implementations return null, the
<literal>ProviderManager</literal> will throw a suitable exception. If
you're interested in learning more about chaining providers, please
refer to the <literal>ProviderManager</literal> JavaDocs.</para>
<para>The providers to use will sometimes be interchangeable with the
authentication mechanisms, whilst at other times they will depend on a
specific authentication mechanism. For example, the
<literal>DaoAuthenticationProvider</literal> just needs a string-based
username and password. Various authentication mechanisms result in the
collection of a string-based username and password, including (but not
limited to) BASIC and form authentication. Equally, some
authentication mechanisms create an authentication request object
which can only be interpreted by a single type of
<classname>AuthenticationProvider</classname>. An example of this
one-to-one mapping would be JA-SIG CAS, which uses the notion of a
service ticket which can therefore only be authenticated by
<literal>CasAuthenticationProvider</literal>. A further example of a
one-to-one mapping would be the LDAP authentication mechanism, which
can only be processed an the
<literal>LdapAuthenticationProvider</literal>. The specifics of such
relationships are detailed in the JavaDocs for each class, plus the
authentication approach-specific chapters of this reference guide. You
need not be terribly concerned about this implementation detail,
because if you forget to register a suitable provider, you'll simply
receive a <literal>ProviderNotFoundException</literal> when an attempt
to authenticate is made.</para>
</bean>]]></programlisting>
</para>
<para>It's probably worth mentioning at this point that your authentication mechanisms (which
are usually filters) are also injected with a reference to the
<interfacename>AuthenticationManager</interfacename>. So both
<classname>AbstractSecurityInterceptor</classname> as well as the authentication mechanisms
will use the above <literal>ProviderManager</literal> to poll a list of
<classname>AuthenticationProvider</classname>s.</para>
<para>In our example we have three providers. They are tried in the order shown (which is
implied by the use of a <literal>List</literal> instead of a <literal>Set</literal>), with
each provider able to attempt authentication, or skip authentication by simply returning
<literal>null</literal>. If all implementations return null, the
<literal>ProviderManager</literal> will throw a suitable exception. If you're interested in
learning more about chaining providers, please refer to the <literal>ProviderManager</literal>
JavaDocs.</para>
<para>The providers to use will sometimes be interchangeable with the authentication mechanisms,
whilst at other times they will depend on a specific authentication mechanism. For example,
the <literal>DaoAuthenticationProvider</literal> just needs a string-based username and
password. Various authentication mechanisms result in the collection of a string-based
username and password, including (but not limited to) BASIC and form authentication. Equally,
some authentication mechanisms create an authentication request object which can only be
interpreted by a single type of <classname>AuthenticationProvider</classname>. An example of
this one-to-one mapping would be JA-SIG CAS, which uses the notion of a service ticket which
can therefore only be authenticated by <literal>CasAuthenticationProvider</literal>. A further
example of a one-to-one mapping would be the LDAP authentication mechanism, which can only be
processed an the <literal>LdapAuthenticationProvider</literal>. The specifics of such
relationships are detailed in the JavaDocs for each class, plus the authentication
approach-specific chapters of this reference guide. You need not be terribly concerned about
this implementation detail, because if you forget to register a suitable provider, you'll
simply receive a <literal>ProviderNotFoundException</literal> when an attempt to authenticate
is made.</para>
<para>After configuring the correct authentication mechanisms in the
<classname>FilterChainProxy</classname>, and ensuring that a corresponding
<classname>AuthenticationProvider</classname> is registered in the
<literal>ProviderManager</literal>, your last step is to configure an
<interfacename>AuthenticationEntryPoint</interfacename>. Recall that earlier we
discussed the role of <classname>ExceptionTranslationFilter</classname>,
which is used when HTTP-based requests should receive back an HTTP
header or HTTP redirect in order to start authentication. Continuing
on with our earlier example:</para>
<para><programlisting><![CDATA[
<classname>FilterChainProxy</classname>, and ensuring that a corresponding
<classname>AuthenticationProvider</classname> is registered in the
<literal>ProviderManager</literal>, your last step is to configure an
<interfacename>AuthenticationEntryPoint</interfacename>. Recall that earlier we discussed
the role of <classname>ExceptionTranslationFilter</classname>, which is used when HTTP-based
requests should receive back an HTTP header or HTTP redirect in order to start authentication.
Continuing on with our earlier example:</para>
<para>
<programlisting><![CDATA[
<bean id="exceptionTranslationFilter"
class="org.springframework.security.web.access.ExceptionTranslationFilter">
<property name="authenticationEntryPoint" ref="authenticationEntryPoint"/>
@ -211,132 +130,105 @@
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<property name="loginFormUrl" value="/login.jsp"/>
<property name="forceHttps" value="false"/>
</bean>]]></programlisting></para>
<para>Notice that the <classname>ExceptionTranslationFilter</classname>
requires two collaborators. The first,
<literal>AccessDeniedHandlerImpl</literal>, uses a
<literal>RequestDispatcher</literal> forward to display the specified
access denied error page. We use a forward so that the
<classname>SecurityContextHolder</classname> still contains details of the
principal, which may be useful for display to the user (in old
releases of Spring Security we relied upon the servlet container to
handle a 403 error message, which lacked this useful contextual
information). <literal>AccessDeniedHandlerImpl</literal> will also set
the HTTP header to 403, which is the official error code to indicate
access denied. In the case of the
<literal>AuthentionEntryPoint</literal>, here we're setting what
action we would like taken when an unauthenticated principal attempts
to perform a protected operation. Because in our example we're going
to be using form-based authentication, we specify
<literal>AuthenticationProcessinFilterEntryPoint</literal> and the URL
of the login page. Your application will usually only have one entry
point, and most authentication approaches define their own specific
<interfacename>AuthenticationEntryPoint</interfacename>. Details of which entry
point to use for each authentication approach is discussed in the
authentication approach-specific chapters of this reference
guide.</para>
</bean>]]></programlisting>
</para>
<para>Notice that the <classname>ExceptionTranslationFilter</classname> requires two
collaborators. The first, <literal>AccessDeniedHandlerImpl</literal>, uses a
<literal>RequestDispatcher</literal> forward to display the specified access denied error
page. We use a forward so that the <classname>SecurityContextHolder</classname> still contains
details of the principal, which may be useful for display to the user (in old releases of
Spring Security we relied upon the servlet container to handle a 403 error message, which
lacked this useful contextual information). <literal>AccessDeniedHandlerImpl</literal> will
also set the HTTP header to 403, which is the official error code to indicate access denied.
In the case of the <literal>AuthentionEntryPoint</literal>, here we're setting what action we
would like taken when an unauthenticated principal attempts to perform a protected operation.
Because in our example we're going to be using form-based authentication, we specify
<literal>AuthenticationProcessinFilterEntryPoint</literal> and the URL of the login page.
Your application will usually only have one entry point, and most authentication approaches
define their own specific <interfacename>AuthenticationEntryPoint</interfacename>. Details of
which entry point to use for each authentication approach is discussed in the authentication
approach-specific chapters of this reference guide.</para>
</section>
<section xml:id="userdetails-and-associated-types">
<info><title>UserDetails and Associated Types</title></info>
<para>As mentioned in the first part of the reference guide, most
authentication providers take advantage of the
<interfacename>UserDetails</interfacename> and
<interfacename>UserDetailsService</interfacename> interfaces. The contract for
this latter interface consists of a single method:</para>
<para><programlisting>
<info>
<title>UserDetails and Associated Types</title>
</info>
<para>As mentioned in the first part of the reference guide, most authentication providers take
advantage of the <interfacename>UserDetails</interfacename> and
<interfacename>UserDetailsService</interfacename> interfaces. The contract for this latter
interface consists of a single method:</para>
<para>
<programlisting>
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException;
</programlisting></para>
<para>The returned <interfacename>UserDetails</interfacename> is an interface that
provides getters that guarantee non-null provision of basic
authentication information such as the username, password, granted
authorities and whether the user is enabled or disabled. Most
authentication providers will use a
<interfacename>UserDetailsService</interfacename>, even if the username and
password are not actually used as part of the authentication decision.
Generally such providers will be using the returned
<interfacename>UserDetails</interfacename> object just for its
<literal>GrantedAuthority[]</literal> information, because some other
system (like LDAP or X509 or CAS etc) has undertaken the
responsibility of actually validating the credentials.</para>
<para>A single concrete implementation of
<interfacename>UserDetails</interfacename> is provided with Spring Security, being
the <literal>User</literal> class. Spring Security users will need to
decide when writing their <interfacename>UserDetailsService</interfacename> what
concrete <interfacename>UserDetails</interfacename> class to return. In most cases
<literal>User</literal> will be used directly or subclassed, although
special circumstances (such as object relational mappers) may require
users to write their own <interfacename>UserDetails</interfacename> implementation
from scratch. This is not such an unusual situation, and users should
not hesitate to simply return their normal domain object that
represents a user of the system. This is especially common given that
<interfacename>UserDetails</interfacename> is often used to store additional
principal-related properties (such as their telephone number and email
address), so that they can be easily used by web views.</para>
<para>Given <interfacename>UserDetailsService</interfacename> is so simple to
implement, it should be easy for users to retrieve authentication
information using a persistence strategy of their choice. Having said
that, Spring Security does include a couple of useful base
implementations, which we'll look at below.</para>
</programlisting>
</para>
<para>The returned <interfacename>UserDetails</interfacename> is an interface that provides
getters that guarantee non-null provision of basic authentication information such as the
username, password, granted authorities and whether the user is enabled or disabled. Most
authentication providers will use a <interfacename>UserDetailsService</interfacename>, even if
the username and password are not actually used as part of the authentication decision.
Generally such providers will be using the returned <interfacename>UserDetails</interfacename>
object just for its <literal>GrantedAuthority[]</literal> information, because some other
system (like LDAP or X509 or CAS etc) has undertaken the responsibility of actually validating
the credentials.</para>
<para>A single concrete implementation of <interfacename>UserDetails</interfacename> is provided
with Spring Security, being the <literal>User</literal> class. Spring Security users will need
to decide when writing their <interfacename>UserDetailsService</interfacename> what concrete
<interfacename>UserDetails</interfacename> class to return. In most cases
<literal>User</literal> will be used directly or subclassed, although special circumstances
(such as object relational mappers) may require users to write their own
<interfacename>UserDetails</interfacename> implementation from scratch. This is not such an
unusual situation, and users should not hesitate to simply return their normal domain object
that represents a user of the system. This is especially common given that
<interfacename>UserDetails</interfacename> is often used to store additional
principal-related properties (such as their telephone number and email address), so that they
can be easily used by web views.</para>
<para>Given <interfacename>UserDetailsService</interfacename> is so simple to implement, it
should be easy for users to retrieve authentication information using a persistence strategy
of their choice. Having said that, Spring Security does include a couple of useful base
implementations, which we'll look at below.</para>
<section xml:id="in-memory-service">
<info><title>In-Memory Authentication</title></info>
<info>
<title>In-Memory Authentication</title>
</info>
<para>Whilst it is easy to use create a custom
<interfacename>UserDetailsService</interfacename> implementation that extracts
information from a persistence engine of choice, many applications
do not require such complexity. This is particularly true if you're
undertaking a rapid prototype or just starting integrating Spring
Security, when you don't really want to spend time configuring
databases or writing <interfacename>UserDetailsService</interfacename>
implementations. For this sort of situation, a simple option is to
use the <literal>user-service</literal> element from the security
<link xlink:href="#namespace-minimal" >namespace</link>:
<programlisting><![CDATA[
<interfacename>UserDetailsService</interfacename> implementation that extracts information
from a persistence engine of choice, many applications do not require such complexity. This
is particularly true if you're undertaking a rapid prototype or just starting integrating
Spring Security, when you don't really want to spend time configuring databases or writing
<interfacename>UserDetailsService</interfacename> implementations. For this sort of
situation, a simple option is to use the <literal>user-service</literal> element from the
security <link xlink:href="#namespace-minimal">namespace</link>: <programlisting><![CDATA[
<user-service id="userDetailsService">
<user name="jimi" password="jimispassword" authorities="ROLE_USER, ROLE_ADMIN" />
<user name="bob" password="bobspassword" authorities="ROLE_USER" />
</user-service>
]]>
</programlisting>
This also suppots the use of an external properties file:
<programlisting><![CDATA[
</programlisting> This also suppots the use of an external properties file: <programlisting><![CDATA[
<user-service id="userDetailsService" properties="users.properties"/>
]]></programlisting>
The properties file should contain entries in the form
<programlisting>
]]></programlisting> The properties file should contain entries in the form
<programlisting>
username=password,grantedAuthority[,grantedAuthority][,enabled|disabled]
</programlisting>
For example
<programlisting>
<programlisting>
jimi=jimispassword,ROLE_USER,ROLE_ADMIN,enabled
bob=bobspassword,ROLE_USER,enabled
</programlisting>
</para>
</programlisting></para>
</section>
<section xml:id="jdbc-service">
<info>
<title>JDBC Authentication</title>
</info>
<para>Spring Security also includes a
<interfacename>UserDetailsService</interfacename> that can obtain authentication
information from a JDBC data source. Internally Spring JDBC is used,
so it avoids the complexity of a fully-featured object relational
mapper (ORM) just to store user details. If your application does
use an ORM tool, you might prefer to write a custom
<interfacename>UserDetailsService</interfacename> to reuse the mapping files
you've probably already created. Returning to
<literal>JdbcDaoImpl</literal>, an example configuration is shown
below:</para>
<para><programlisting>
<para>Spring Security also includes a <interfacename>UserDetailsService</interfacename> that
can obtain authentication information from a JDBC data source. Internally Spring JDBC is
used, so it avoids the complexity of a fully-featured object relational mapper (ORM) just to
store user details. If your application does use an ORM tool, you might prefer to write a
custom <interfacename>UserDetailsService</interfacename> to reuse the mapping files you've
probably already created. Returning to <literal>JdbcDaoImpl</literal>, an example
configuration is shown below:</para>
<para>
<programlisting>
<![CDATA[
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
@ -347,21 +239,17 @@
<bean id="userDetailsService" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
<property name="dataSource" ref="dataSource"/>
</bean> ]]> </programlisting></para>
<para>You can use different relational database management systems
by modifying the <literal>DriverManagerDataSource</literal> shown
above. You can also use a global data source obtained from JNDI, as
per normal Spring options.
</bean> ]]> </programlisting>
</para>
<para>You can use different relational database management systems by modifying the
<literal>DriverManagerDataSource</literal> shown above. You can also use a global data
source obtained from JNDI, as per normal Spring options. </para>
<section xml:id="jdbc-default-schema">
<title>Default User Database Schema</title>
<para>
Irrespective of the database you are using and how
a <literal>DataSource</literal> is obtained, a standard schema must
be in place. The DDL for an HSQL database instance would be:
<programlisting>
<para> Irrespective of the database you are using and how a <literal>DataSource</literal> is
obtained, a standard schema must be in place. The DDL for an HSQL database instance would
be:
<programlisting>
CREATE TABLE users (
username VARCHAR(50) NOT NULL PRIMARY KEY,
password VARCHAR(50) NOT NULL,
@ -375,66 +263,49 @@
ALTER TABLE authorities ADD CONSTRAINT fk_authorities_users \
foreign key (username) REFERENCES users(username);
</programlisting>
</para>
<para>If the default schema is unsuitable for your needs,
<literal>JdbcDaoImpl</literal> provides properties that allow
customisation of the SQL statements. Please refer to the JavaDocs for
details, but note that the class is not intended for complex custom subclasses.
If you have a complex schema or would like a
custom <interfacename>UserDetails</interfacename> implementation returned,
you'd be better off writing your own
<interfacename>UserDetailsService</interfacename>. The base implementation
provided with Spring Security is intended for typical situations,
rather than catering for all possible requirements.</para>
</programlisting></para>
<para>If the default schema is unsuitable for your needs, <literal>JdbcDaoImpl</literal>
provides properties that allow customisation of the SQL statements. Please refer to the
JavaDocs for details, but note that the class is not intended for complex custom
subclasses. If you have a complex schema or would like a custom
<interfacename>UserDetails</interfacename> implementation returned, you'd be better off
writing your own <interfacename>UserDetailsService</interfacename>. The base
implementation provided with Spring Security is intended for typical situations, rather
than catering for all possible requirements.</para>
</section>
</section>
</section>
<section xml:id="concurrent-sessions">
<info><title>Concurrent Session Handling</title></info>
<para>Spring Security is able to prevent a principal from concurrently
authenticating to the same application more than a specified number of
times. Many ISVs take advantage of this to enforce licensing, whilst
network administrators like this feature because it helps prevent
people from sharing login names. You can, for example, stop user
"Batman" from logging onto the web application from two different
sessions.</para>
<para>To use concurrent session support, you'll need to add the
following to <literal>web.xml</literal>:
<programlisting><![CDATA[
<info>
<title>Concurrent Session Handling</title>
</info>
<para>Spring Security is able to prevent a principal from concurrently authenticating to the
same application more than a specified number of times. Many ISVs take advantage of this to
enforce licensing, whilst network administrators like this feature because it helps prevent
people from sharing login names. You can, for example, stop user "Batman" from logging onto
the web application from two different sessions.</para>
<para>To use concurrent session support, you'll need to add the following to
<literal>web.xml</literal>: <programlisting><![CDATA[
<listener>
<listener-class>
org.springframework.security.web.session.HttpSessionEventPublisher
</listener-class>
</listener> ]]>
</programlisting>
</para>
</programlisting></para>
<para>In addition, you will need to add the
<literal>org.springframework.security.web.authentication.concurrent.ConcurrentSessionFilter</literal>
to your <classname>FilterChainProxy</classname>. The
<classname>ConcurrentSessionFilter</classname> requires two
properties, <literal>sessionRegistry</literal>, which generally points
to an instance of <literal>SessionRegistryImpl</literal>, and
<literal>expiredUrl</literal>, which points to the page to display
when a session has expired.</para>
<literal>org.springframework.security.web.authentication.concurrent.ConcurrentSessionFilter</literal>
to your <classname>FilterChainProxy</classname>. The
<classname>ConcurrentSessionFilter</classname> requires two properties,
<literal>sessionRegistry</literal>, which generally points to an instance of
<literal>SessionRegistryImpl</literal>, and <literal>expiredUrl</literal>, which points to
the page to display when a session has expired.</para>
<para>The <literal>web.xml</literal>
<literal>HttpSessionEventPublisher</literal> causes an
<literal>ApplicationEvent</literal> to be published to the Spring
<literal>ApplicationContext</literal> every time a
<literal>HttpSession</literal> commences or terminates. This is
critical, as it allows the <classname>SessionRegistryImpl</classname> to
be notified when a session ends.</para>
<para>You will also need to wire up the
<classname>ConcurrentSessionControllerImpl</classname> and refer to it
from your <literal>ProviderManager</literal> bean:</para>
<literal>HttpSessionEventPublisher</literal> causes an <literal>ApplicationEvent</literal> to
be published to the Spring <literal>ApplicationContext</literal> every time a
<literal>HttpSession</literal> commences or terminates. This is critical, as it allows the
<classname>SessionRegistryImpl</classname> to be notified when a session ends.</para>
<para>You will also need to wire up the <classname>ConcurrentSessionControllerImpl</classname>
and refer to it from your <literal>ProviderManager</literal> bean:</para>
<para>
<programlisting><![CDATA[
<bean id="authenticationManager"
@ -453,25 +324,24 @@
class="org.springframework.security.authentication.concurrent.SessionRegistryImpl"/>
<property>
</bean>
]]></programlisting></para>
]]></programlisting>
</para>
</section>
<section xml:id="authentication-taglibs">
<info><title>Authentication Tag Libraries</title></info>
<para><literal>AuthenticationTag</literal> is used to simply output a
property of the current <interfacename>Authentication</interfacename> object to the web
page.</para>
<info>
<title>Authentication Tag Libraries</title>
</info>
<para><literal>AuthenticationTag</literal> is used to simply output a property of the current
<interfacename>Authentication</interfacename> object to the web page.</para>
<para>The following JSP fragment illustrates how to use the
<literal>AuthenticationTag</literal>:</para>
<para><programlisting>&lt;security:authentication property="principal.username"/&gt;</programlisting></para>
<para>This tag would cause the principal's name to be output. Here we
are assuming the <literal>Authentication.getPrincipal()</literal> is a
<interfacename>UserDetails</interfacename> object, which is generally the case
when using one of Spring Security's stadard <classname>AuthenticationProvider</classname>
<literal>AuthenticationTag</literal>:</para>
<para>
<programlisting>&lt;security:authentication property="principal.username"/&gt;</programlisting>
</para>
<para>This tag would cause the principal's name to be output. Here we are assuming the
<literal>Authentication.getPrincipal()</literal> is a
<interfacename>UserDetails</interfacename> object, which is generally the case when using
one of Spring Security's stadard <classname>AuthenticationProvider</classname>
implementations.</para>
</section>
</chapter>
</chapter>

View File

@ -1,450 +0,0 @@
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="ca"><info><title>Container Adapter Authentication</title></info>
<section xml:id="ca-overview">
<info><title>Overview</title></info>
<para>Very early versions of Spring Security exclusively used
Container Adapters for interfacing authentication with end users.
Whilst this worked well, it required considerable time to support
multiple container versions and the configuration itself was
relatively time-consuming for developers. For this reason the HTTP
Form Authentication and HTTP Basic Authentication approaches were
developed, and are today recommended for almost all
applications.</para>
<para>Container Adapters enable Spring Security to integrate directly
with the containers used to host end user applications. This
integration means that applications can continue to leverage the
authentication and authorization capabilities built into containers
(such as <literal>isUserInRole()</literal> and form-based or basic
authentication), whilst benefiting from the enhanced security
interception capabilities provided by Spring Security (it should be
noted that Spring Security also offers
<literal>ContextHolderAwareRequestWrapper</literal> to deliver
<literal>isUserInRole()</literal> and similar Servlet Specification
compatibility methods).</para>
<para>The integration between a container and Spring Security is
achieved through an adapter. The adapter provides a
container-compatible user authentication provider, and needs to return
a container-compatible user object.</para>
<para>The adapter is instantiated by the container and is defined in a
container-specific configuration file. The adapter then loads a Spring
application context which defines the normal authentication manager
settings, such as the authentication providers that can be used to
authenticate the request. The application context is usually named
<literal>acegisecurity.xml</literal> and is placed in a
container-specific location.</para>
<para>Spring Security currently supports Jetty, Catalina (Tomcat),
JBoss and Resin. Additional container adapters can easily be
written</para>
</section>
<section xml:id="ca-adapter"><info><title>Adapter Authentication Provider</title></info>
<para>As is always the case, the container adapter generated
<interfacename>Authentication</interfacename> object still needs to be
authenticated by an <interfacename>AuthenticationManager</interfacename> when
requested to do so by the
<classname>AbstractSecurityInterceptor</classname>. The
<interfacename>AuthenticationManager</interfacename> needs to be certain the
adapter-provided <interfacename>Authentication</interfacename> object is valid and
was actually authenticated by a trusted adapter.</para>
<para>Adapters create <interfacename>Authentication</interfacename> objects which
are immutable and implement the <literal>AuthByAdapter</literal>
interface. These objects store the hash of a key that is defined by
the adapter. This allows the <interfacename>Authentication</interfacename> object
to be validated by the <literal>AuthByAdapterProvider</literal>. This
authentication provider is defined as follows:</para>
<para><programlisting>&lt;bean id="authByAdapterProvider"
class="org.springframework.security.adapters.AuthByAdapterProvider"&gt;
&lt;property name="key"&gt;&lt;value&gt;my_password&lt;/value&gt;&lt;/property&gt;
&lt;/bean&gt; </programlisting></para>
<para>The key must match the key that is defined in the
container-specific configuration file that starts the adapter. The
<literal>AuthByAdapterProvider</literal> automatically accepts as
valid any <literal>AuthByAdapter</literal> implementation that returns
the expected hash of the key.</para>
<para>To reiterate, this means the adapter will perform the initial
authentication using providers such as
<literal>DaoAuthenticationProvider</literal>, returning an
<literal>AuthByAdapter</literal> instance that contains a hash code of
the key. Later, when an application calls a security interceptor
managed resource, the <literal>AuthByAdapter</literal> instance in the
<interfacename>SecurityContext</interfacename> in the
<classname>SecurityContextHolder</classname> will be tested by the
application's <literal>AuthByAdapterProvider</literal>. There is no
requirement for additional authentication providers such as
<literal>DaoAuthenticationProvider</literal> within the
application-specific application context, as the only type of
<interfacename>Authentication</interfacename> instance that will be presented by
the application is from the container adapter.</para>
<para>Classloader issues are frequent with containers and the use of
container adapters illustrates this further. Each container requires a
very specific configuration. The installation instructions are
provided below. Once installed, please take the time to try the sample
application to ensure your container adapter is properly
configured.</para>
<para>When using container adapters with the
<literal>DaoAuthenticationProvider</literal>, ensure you set its
<literal>forcePrincipalAsString</literal> property to
<literal>true</literal>.</para>
</section>
<section xml:id="ca-jetty"><info><title>Jetty</title></info>
<para>The following was tested with Jetty 4.2.18.</para>
<para><literal>$JETTY_HOME</literal> refers to the root of your Jetty
installation.</para>
<para>Edit your <literal>$JETTY_HOME/etc/jetty.xml</literal> file so
the <literal>&lt;Configure class&gt;</literal> section has a new
<literal>addRealm</literal> call:</para>
<para><programlisting>
&lt;Call name="addRealm"&gt;
&lt;Arg&gt;
&lt;New class="org.springframework.security.adapters.jetty.JettySpringSecurityUserRealm"&gt;
&lt;Arg&gt;Spring Powered Realm&lt;/Arg&gt;
&lt;Arg&gt;my_password&lt;/Arg&gt;
&lt;Arg&gt;etc/acegisecurity.xml&lt;/Arg&gt;
&lt;/New&gt;
&lt;/Arg&gt;
&lt;/Call&gt;
</programlisting></para>
<para>Copy <literal>acegisecurity.xml</literal> into
<literal>$JETTY_HOME/etc</literal>.</para>
<para>Copy the following files into
<literal>$JETTY_HOME/ext</literal>:<itemizedlist>
<listitem>
<para><literal>aopalliance.jar</literal></para>
</listitem>
<listitem>
<para><literal>commons-logging.jar</literal></para>
</listitem>
<listitem>
<para><literal>spring.jar</literal></para>
</listitem>
<listitem>
<para><literal>acegi-security-jetty-XX.jar</literal></para>
</listitem>
<listitem>
<para><literal>commons-codec.jar</literal></para>
</listitem>
<listitem>
<para><literal>burlap.jar</literal></para>
</listitem>
<listitem>
<para><literal>hessian.jar</literal></para>
</listitem>
</itemizedlist></para>
<para>None of the above JAR files (or
<literal>acegi-security-XX.jar</literal>) should be in your
application's <literal>WEB-INF/lib</literal>. The realm name indicated
in your <literal>web.xml</literal> does matter with Jetty. The
<literal>web.xml</literal> must express the same
<literal>&lt;realm-name&gt;</literal> as your
<literal>jetty.xml</literal> (in the example above, "Spring Powered
Realm").</para>
</section>
<section xml:id="ca-jboss"><info><title>JBoss</title></info>
<para>The following was tested with JBoss 3.2.6.</para>
<para><literal>$JBOSS_HOME</literal> refers to the root of your JBoss
installation.</para>
<para>There are two different ways of making spring context available
to the Jboss integration classes.</para>
<para>The first approach is by editing your
<literal>$JBOSS_HOME/server/your_config/conf/login-config.xml</literal>
file so that it contains a new entry under the
<literal>&lt;Policy&gt;</literal> section:</para>
<para><programlisting>
&lt;application-policy name = "SpringPoweredRealm"&gt;
&lt;authentication&gt;
&lt;login-module code = "org.springframework.security.adapters.jboss.JbossSpringSecurityLoginModule"
flag = "required"&gt;
&lt;module-option name = "appContextLocation"&gt;acegisecurity.xml&lt;/module-option&gt;
&lt;module-option name = "key"&gt;my_password&lt;/module-option&gt;
&lt;/login-module&gt;
&lt;/authentication&gt;
&lt;/application-policy&gt;
</programlisting></para>
<para>Copy <literal>acegisecurity.xml</literal> into
<literal>$JBOSS_HOME/server/your_config/conf</literal>.</para>
<para>In this configuration <literal>acegisecurity.xml</literal>
contains the spring context definition including all the
authentication manager beans. You have to bear in mind though, that
<interfacename>SecurityContext</interfacename> is created and destroyed on each
login request, so the login operation might become costly.
Alternatively, the second approach is to use Spring singleton
capabilities through
<literal>org.springframework.beans.factory.access.SingletonBeanFactoryLocator</literal>.
The required configuration for this approach is:</para>
<para><programlisting>
&lt;application-policy name = "SpringPoweredRealm"&gt;
&lt;authentication&gt;
&lt;login-module code = "org.springframework.security.adapters.jboss.JbossSpringSecurityLoginModule"
flag = "required"&gt;
&lt;module-option name = "singletonId"&gt;springRealm&lt;/module-option&gt;
&lt;module-option name = "key"&gt;my_password&lt;/module-option&gt;
&lt;module-option name = "authenticationManager"&gt;authenticationManager&lt;/module-option&gt;
&lt;/login-module&gt;
&lt;/authentication&gt;
&lt;/application-policy&gt;
</programlisting></para>
<para>In the above code fragment,
<literal>authenticationManager</literal> is a helper property that
defines the expected name of the
<interfacename>AuthenticationManager</interfacename> in case you have several
defined in the IoC container. The <literal>singletonId</literal>
property references a bean defined in a
<literal>beanRefFactory.xml</literal> file. This file needs to be
available from anywhere on the JBoss classpath, including
<literal>$JBOSS_HOME/server/your_config/conf</literal>. The
<literal>beanRefFactory.xml</literal> contains the following
declaration:</para>
<para><programlisting>
&lt;beans&gt;
&lt;bean id="springRealm" singleton="true" lazy-init="true" class="org.springframework.context.support.ClassPathXmlApplicationContext"&gt;
&lt;constructor-arg&gt;
&lt;list&gt;
&lt;value&gt;acegisecurity.xml&lt;/value&gt;
&lt;/list&gt;
&lt;/constructor-arg&gt;
&lt;/bean&gt;
&lt;/beans&gt;
</programlisting></para>
<para>Finally, irrespective of the configuration approach you need to
copy the following files into
<literal>$JBOSS_HOME/server/your_config/lib</literal>:<itemizedlist>
<listitem>
<para><literal>aopalliance.jar</literal></para>
</listitem>
<listitem>
<para><literal>spring.jar</literal></para>
</listitem>
<listitem>
<para><literal>acegi-security-jboss-XX.jar</literal></para>
</listitem>
<listitem>
<para><literal>commons-codec.jar</literal></para>
</listitem>
<listitem>
<para><literal>burlap.jar</literal></para>
</listitem>
<listitem>
<para><literal>hessian.jar</literal></para>
</listitem>
</itemizedlist></para>
<para>None of the above JAR files (or
<literal>acegi-security-XX.jar</literal>) should be in your
application's <literal>WEB-INF/lib</literal>. The realm name indicated
in your <literal>web.xml</literal> does not matter with JBoss.
However, your web application's
<literal>WEB-INF/jboss-web.xml</literal> must express the same
<literal>&lt;security-domain&gt;</literal> as your
<literal>login-config.xml</literal>. For example, to match the above
example, your <literal>jboss-web.xml</literal> would look like
this:</para>
<para><programlisting>
&lt;jboss-web&gt;
&lt;security-domain&gt;java:/jaas/SpringPoweredRealm&lt;/security-domain&gt;
&lt;/jboss-web&gt;</programlisting></para>
<para>JBoss is a widely-used container adapter (mostly due to the need
to support legacy EJBs), so please let us know if you have any
difficulties.</para>
</section>
<section xml:id="ca-resin"><info><title>Resin</title></info>
<para>The following was tested with Resin 3.0.6.</para>
<para><literal>$RESIN_HOME</literal> refers to the root of your Resin
installation.</para>
<para>Resin provides several ways to support the container adapter. In
the instructions below we have elected to maximise consistency with
other container adapter configurations. This will allow Resin users to
simply deploy the sample application and confirm correct
configuration. Developers comfortable with Resin are naturally able to
use its capabilities to package the JARs with the web application
itself, and/or support single sign-on.</para>
<para>Copy the following files into
<literal>$RESIN_HOME/lib</literal>:<itemizedlist>
<listitem>
<para><literal>aopalliance.jar</literal></para>
</listitem>
<listitem>
<para><literal>commons-logging.jar</literal></para>
</listitem>
<listitem>
<para><literal>spring.jar</literal></para>
</listitem>
<listitem>
<para><literal>acegi-security-resin-XX.jar</literal></para>
</listitem>
<listitem>
<para><literal>commons-codec.jar</literal></para>
</listitem>
<listitem>
<para><literal>burlap.jar</literal></para>
</listitem>
<listitem>
<para><literal>hessian.jar</literal></para>
</listitem>
</itemizedlist></para>
<para>Unlike the container-wide <literal>acegisecurity.xml</literal>
files used by other container adapters, each Resin web application
will contain its own
<literal>WEB-INF/resin-acegisecurity.xml</literal> file. Each web
application will also contain a <literal>resin-web.xml</literal> file
which Resin uses to start the container adapter:</para>
<para><programlisting>
&lt;web-app&gt;
&lt;authenticator&gt;
&lt;type&gt;org.springframework.security.adapters.resin.ResinAcegiAuthenticator&lt;/type&gt;
&lt;init&gt;
&lt;app-context-location&gt;WEB-INF/resin-acegisecurity.xml&lt;/app-context-location&gt;
&lt;key&gt;my_password&lt;/key&gt;
&lt;/init&gt;
&lt;/authenticator&gt;
&lt;/web-app&gt;
</programlisting></para>
<para>With the basic configuration provided above, none of the JAR
files listed (or <literal>acegi-security-XX.jar</literal>) should be
in your application's <literal>WEB-INF/lib</literal>. The realm name
indicated in your <literal>web.xml</literal> does not matter with
Resin, as the relevant authentication class is indicated by the
<literal>&lt;authenticator&gt;</literal> setting</para>
</section>
<section xml:id="ca-tomcat"><info><title>Tomcat</title></info>
<para>The following was tested with Jakarta Tomcat 4.1.30 and
5.0.19.</para>
<para><literal>$CATALINA_HOME</literal> refers to the root of your
Catalina (Tomcat) installation.</para>
<para>Edit your <literal>$CATALINA_HOME/conf/server.xml</literal> file
so the <literal>&lt;Engine&gt;</literal> section contains only one
active <literal>&lt;Realm&gt;</literal> entry. An example realm
entry:</para>
<para><programlisting> &lt;Realm
className="org.springframework.security.adapters.catalina.CatalinaSpringSecurityUserRealm"
appContextLocation="conf/acegisecurity.xml"
key="my_password" /&gt;</programlisting></para>
<para>Be sure to remove any other <literal>&lt;Realm&gt;</literal>
entry from your <literal>&lt;Engine&gt;</literal> section.</para>
<para>Copy <literal>acegisecurity.xml</literal> into
<literal>$CATALINA_HOME/conf</literal>.</para>
<para>Copy <literal>spring-security-catalina-XX.jar</literal> into
<literal>$CATALINA_HOME/server/lib</literal>.</para>
<para>Copy the following files into
<literal>$CATALINA_HOME/common/lib</literal>:</para>
<itemizedlist>
<listitem>
<para><literal>aopalliance.jar</literal></para>
</listitem>
<listitem>
<para><literal>spring.jar</literal></para>
</listitem>
<listitem>
<para><literal>commons-codec.jar</literal></para>
</listitem>
<listitem>
<para><literal>burlap.jar</literal></para>
</listitem>
<listitem>
<para><literal>hessian.jar</literal></para>
</listitem>
</itemizedlist>
<para>None of the above JAR files (or
<literal>spring-security-XX.jar</literal>) should be in your
application's <literal>WEB-INF/lib</literal>. The realm name indicated
in your <literal>web.xml</literal> does not matter with
Catalina.</para>
<para>We have received reports of problems using this Container
Adapter with Mac OS X. A work-around is to use a script such as
follows:</para>
<para><programlisting>#!/bin/sh
export CATALINA_HOME="/Library/Tomcat"
export JAVA_HOME="/Library/Java/Home"
cd /
$CATALINA_HOME/bin/startup.sh</programlisting></para>
<para>Finally, restart Tomcat.</para>
</section>
</chapter>

View File

@ -681,8 +681,8 @@
<para> We've touched on the idea that the namespace configuration automatically registers an
authentication manager bean for you. This is an instance of Spring Security's
<classname>ProviderManager</classname> class, which you may already be familiar with if
you've used the framework before. You can't use a custom
<classname>AuthenticationManager</classname> if you are using either HTTP or method security
you've used the framework before. If not, it will be covered later, in <link xlink:href="#tech-intro-authentication"/>.
You can't use a custom <classname>AuthenticationManager</classname> if you are using either HTTP or method security
through the namespace, but this should not be a problem as you have full control over the
<classname>AuthenticationProvider</classname>s that are used. </para>
<para> You may want to register additional <classname>AuthenticationProvider</classname> beans

View File

@ -86,7 +86,7 @@
<xi:include href="community.xml"/>
</part>
<part xml:id="overall-architecture">
<title>Overall Architecture</title>
<title>Architecture and Implementation</title>
<partintro>
<para>Once you are familiar with setting up and running some namespace-configuration based
applications, you may wish to develop more of an understanding of how the framework actually
@ -97,23 +97,7 @@
Security.</para>
</partintro>
<xi:include href="technical-overview.xml"/>
<!--xi:include href="supporting-infrastructure.xml"/-->
<!-- xi:include href="channel-security.xml"/ -->
</part>
<part xml:id="webapp-security" >
<title>Web Application Security</title>
<partintro>
<para>
Most Spring Security users will be using the framework in enterprise applications which
make user of the HTTP and the Servlet API. In this part we'll take a look at how Spring Security provides
authentication and access-control features for the web layer of an application. We'll look
behind the facade of the namespace and see which classes and interfaces are actually assembled to provide web-layer
security. In some situations it is necessary to use traditional bean configuration to provide full control over
the configuration, so we'll also see how to configure these classes directly without the namespace.
</para>
</partintro>
<xi:include href="supporting-infrastructure.xml"/>
<xi:include href="web-infrastructure.xml"/>
</part>
<part xml:id="authentication">
<title>Authentication</title>
@ -138,16 +122,11 @@
</partintro>
<xi:include href="common-auth-services.xml"/>
<xi:include href="dao-auth-provider.xml"/>
<xi:include href="ldap-auth-provider.xml"/>
<xi:include href="form-authentication.xml"/>
<xi:include href="basic-authentication.xml"/>
<xi:include href="digest-authentication.xml"/>
<xi:include href="remember-me-authentication.xml"/>
<xi:include href="jaas-auth-provider.xml"/>
<xi:include href="preauth.xml"/>
<xi:include href="anon-auth-provider.xml"/>
<xi:include href="x509-auth-provider.xml"/>
<xi:include href="cas-auth-provider.xml"/>
<xi:include href="runas-auth-provider.xml"/>
</part>
<part xml:id="authorization">
@ -168,6 +147,23 @@
<xi:include href="secured-objects.xml"/>
<xi:include href="domain-acls.xml"/>
</part>
<part xml:id="advanced-topics">
<title>Advanced Topics</title>
<!--
Essentially standalone features which do not have to follow on directly from earlier chapters
-->
<partintro>
<para>
In this part we cover some of the more advanced features of the framework.
</para>
</partintro>
<xi:include href="remember-me-authentication.xml"/>
<xi:include href="preauth.xml"/>
<xi:include href="ldap-auth-provider.xml"/>
<xi:include href="jaas-auth-provider.xml"/>
<xi:include href="cas-auth-provider.xml"/>
<xi:include href="x509-auth-provider.xml"/>
</part>
<xi:include href="appendix-db-schema.xml"/>
<xi:include href="appendix-namespace.xml"/>
</book>

View File

@ -1,260 +0,0 @@
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="web-infrastructure" xmlns:xlink="http://www.w3.org/1999/xlink">
<info><title>Web Security Infrastructure</title></info>
<section xml:id="filters">
<title>Spring Security Filters</title>
<para>Spring Security's web application features are implemented using standard servlet filters. It 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 <classname>HttpServletRequest</classname>s and <classname>HttpServletResponse</classname>s
and doesn't care whether the requests come from a browser, a web service client, an <classname>HttpInvoker</classname> or an AJAX application.
</para>
<para>
Spring Security maintains a filter chain internally where each of the filters has a particular responsibility and filters are added or removed
depending on which services are required. The ordering of the filters is important as there are dependencies 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 have to define any Spring beans explicitly but here may be times when you want full control over the security filter chain,
either because you are using features which aren't supported in the namespace, or you are using your own customized versions of classes.</para>
<section xml:id="delegating-filter-proxy">
<title><classname>DelegatingFilterProxy</classname></title>
<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 Security, the filter classes are also Spring beans defined in the application context and thus able
to take advantage of Spring's rich dependency-injection facilities and lifecycle interfaces. Spring's <classname>DelegatingFilterProxy</classname>
provides the link between <filename>web.xml</filename> and the application context.
</para>
<para>When using <classname>DelegatingFilterProxy</classname>, you will see something like this in the <filename>web.xml</filename> file:
<programlisting><![CDATA[
<filter>
<filter-name>myFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>myFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>]]>
</programlisting>
Notice that the filter is actually a <literal>DelegatingFilterProxy</literal>,
and not the class that will actually implement the logic of the filter. What
<classname>DelegatingFilterProxy</classname> does is delegate the
<interfacename>Filter</interfacename>'s methods through to a bean which is
obtained from the Spring application context. This enables the bean to
benefit from the Spring web application context lifecycle support and
configuration flexibility. The bean must implement
<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 <classname>DelegatingFilterProxy</classname>
for more information</para>
</section>
<section xml:id="filter-chain-proxy">
<title><classname>FilterChainProxy</classname></title>
<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
<classname>DelegatingFilterProxy</classname> entry to <filename>web.xml</filename> for each 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 would prefer to just add
a single entry to <filename>web.xml</filename> and deal entirely with 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 <literal>DelegatingFilterProxy</literal>
(just like in the example above), but the target class is <classname>org.springframework.security.web.FilterChainProxy</classname>.
The filter chain is then declared in the application context. Here's an example:
<programlisting language="xml"><![CDATA[
<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
<sec:filter-chain-map path-type="ant">
<sec:filter-chain pattern="/webServices/**" filters="
securityContextPersistenceFilterWithASCFalse,
basicProcessingFilter,
exceptionTranslationFilter,
filterSecurityInterceptor" />
<sec:filter-chain pattern="/**" filters="
securityContextPersistenceFilterWithASCTrue,
authenticationProcessingFilter,
exceptionTranslationFilter,
filterSecurityInterceptor" />
</sec:filter-chain-map>
</bean>
]]>
</programlisting>
The namespace element <literal>filter-chain-map</literal> is used to set up the security filter chain(s) which are required
within the application. It maps a particular URL pattern to a chain of filters built up from the bean names
specified in the <literal>filters</literal> element. Both regular
expressions and Ant Paths are supported, and the most specific URIs
appear first. At runtime 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> attribute
will be applied to that request. The filters will be invoked in the order
they are defined, so you have complete control over the filter chain
which is applied to a particular URL.</para>
<para>You may have noticed we have declared two
<classname>SecurityContextPersistenceFilter</classname>s in the filter
chain (<literal>ASC</literal> is short for
<literal>allowSessionCreation</literal>, a property of
<classname>SecurityContextPersistenceFilter</classname>). As web
services will never present a <literal>jsessionid</literal> on future
requests, creating <literal>HttpSession</literal>s for such user
agents would be wasteful. If you had a high-volume application which
required maximum scalability, we recommend you use the approach shown
above. For smaller applications, using a single
<classname>SecurityContextPersistenceFilter</classname> (with its
default <literal>allowSessionCreation</literal> as
<literal>true</literal>) would likely be sufficient.</para>
<para>In relation to lifecycle issues, the
<classname>FilterChainProxy</classname> will always delegate
<methodname>init(FilterConfig)</methodname> and <methodname>destroy()</methodname>
methods through to the underlaying <interfacename>Filter</interfacename>s if such
methods are called against <classname>FilterChainProxy</classname> itself.
In this case, <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 chain(s). You control the
overall choice as to whether these methods are called or not via the
<literal>targetFilterLifecycle</literal> initialization parameter of
<literal>DelegatingFilterProxy</literal>. By default this property
is <literal>false</literal> and servlet container lifecycle invocations are not delegated through
<literal>DelegatingFilterProxy</literal>.</para>
<para>
When we looked at how to set up web security using <link xlink:href="#namespace-auto-config">namespace configuration</link>,
we used a <literal>DelegatingFilterProxy</literal> with the name <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>
<section>
<title>Bypassing the Filter Chain</title>
<para>
As with the namespace, you can use the attribute <literal>filters = "none"</literal> as an alternative to supplying a filter bean list.
This will omit the request pattern from the security filter chain entirely. Note that anything matching this path will then have
no authentication or authorization services applied and will be freely accessible.
</para>
</section>
</section>
<section>
<title>Filter Ordering</title>
<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:
<orderedlist inheritnum="ignore" continuation="restarts">
<listitem>
<para><classname>ChannelProcessingFilter</classname>, because it might
need to redirect to a different protocol</para>
</listitem>
<listitem>
<para><classname>ConcurrentSessionFilter</classname>, because it
doesn't use any <classname>SecurityContextHolder</classname>
functionality but needs to update 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 setup in the
<classname>SecurityContextHolder</classname> at the beginning of a web
request, and 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 next web request)</para>
</listitem>
<listitem>
<para>Authentication processing mechanisms -
<classname>UsernamePasswordAuthenticationProcessingFilter</classname>,
<classname>CasProcessingFilter</classname>,
<classname>BasicProcessingFilter</classname> etc - so that the
<classname>SecurityContextHolder</classname> can be modified to
contain a valid <interfacename>Authentication</interfacename> request
token</para>
</listitem>
<listitem>
<para>The
<literal>SecurityContextHolderAwareRequestFilter</literal>, if you
are using it to install a Spring Security aware
<literal>HttpServletRequestWrapper</literal> into your servlet
container</para>
</listitem>
<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 enables remember-me services to take place, a
suitable remembered
<interfacename>Authentication</interfacename> object will
be put there</para>
</listitem>
<listitem>
<para><classname>AnonymousProcessingFilter</classname>, so that if no
earlier authentication processing mechanism updated the
<classname>SecurityContextHolder</classname>, an anonymous
<interfacename>Authentication</interfacename> object will be put there</para>
</listitem>
<listitem>
<para><classname>ExceptionTranslationFilter</classname>, to catch any
Spring Security exceptions so that either an HTTP error response
can be returned or an appropriate
<interfacename>AuthenticationEntryPoint</interfacename> can be launched</para>
</listitem>
<listitem>
<para><classname>FilterSecurityInterceptor</classname>, to protect web
URIs</para>
</listitem>
</orderedlist>
</para>
</section>
<section>
<title>Use with other Filter-Based Frameworks</title>
<para>If you're using SiteMesh, ensure Spring Security filters execute
before the SiteMesh filters are called. This enables the
<classname>SecurityContextHolder</classname> to be populated in time for
use by SiteMesh decorators.</para>
</section>
</section>
<section xml:id="taglib">
<info><title>Tag Libraries</title></info>
<para>Spring Security comes bundled with several JSP tag libraries which provide a range of different
services.</para>
<section xml:id="taglib-config">
<info><title>Configuration</title></info>
<para>All taglib classes are included in the core
<literal>spring-security-xx.jar</literal> file, with the
<literal>security.tld</literal> located in the JAR's
<literal>META-INF</literal> directory. This means for JSP 1.2+ web
containers you can simply include the JAR in the WAR's
<literal>WEB-INF/lib</literal> directory and it will be available. If
you're using a JSP 1.1 container, you'll need to declare the JSP
taglib in your <literal>web.xml file</literal>, and include
<literal>security.tld</literal> in the <literal>WEB-INF/lib</literal>
directory. The following fragment is added to
<literal>web.xml</literal>:
<programlisting><![CDATA[
<taglib>
<taglib-uri>http://www.springframework.org/security/tags</taglib-uri>
<taglib-location>/WEB-INF/security.tld</taglib-location>
</taglib>
]]></programlisting></para>
</section>
<section xml:id="taglib-usage">
<info><title>Usage</title></info>
<para>Now that you've configured the tag libraries, refer to the
individual reference guide sections for details on how to use them.
Note that when using the tags, you should include the taglib reference
in your JSP:
<programlisting>
&lt;%@ taglib prefix='security' uri='http://www.springframework.org/security/tags' %&gt;
</programlisting></para>
</section>
</section>
</chapter>

View File

@ -1,44 +0,0 @@
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="taglib">
<info><title>Tag Libraries</title></info>
<section xml:id="taglib-overview">
<info><title>Overview</title></info>
<para>Spring Security comes bundled with several JSP tag libraries
that eases JSP writing. The tag libraries provide a range of different
services.</para>
</section>
<section xml:id="taglib-config">
<info><title>Configuration</title></info>
<para>All taglib classes are included in the core
<literal>spring-security-xx.jar</literal> file, with the
<literal>security.tld</literal> located in the JAR's
<literal>META-INF</literal> directory. This means for JSP 1.2+ web
containers you can simply include the JAR in the WAR's
<literal>WEB-INF/lib</literal> directory and it will be available. If
you're using a JSP 1.1 container, you'll need to declare the JSP
taglib in your <literal>web.xml file</literal>, and include
<literal>security.tld</literal> in the <literal>WEB-INF/lib</literal>
directory. The following fragment is added to
<literal>web.xml</literal>:</para>
<para><programlisting>
&lt;taglib&gt;
&lt;taglib-uri&gt;http://www.springframework.org/security/tags&lt;/taglib-uri&gt;
&lt;taglib-location&gt;/WEB-INF/security.tld&lt;/taglib-location&gt;
&lt;/taglib&gt;
</programlisting></para>
</section>
<section xml:id="taglib-usage">
<info><title>Usage</title></info>
<para>Now that you've configured the tag libraries, refer to the
individual reference guide sections for details on how to use them.
Note that when using the tags, you should include the taglib reference
in your JSP: <programlisting>
&lt;%@ taglib prefix='security' uri='http://www.springframework.org/security/tags' %&gt;
</programlisting></para>
</section>
</chapter>

View File

@ -1,4 +1,5 @@
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="technical-overview">
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="technical-overview"
xmlns:xlink="http://www.w3.org/1999/xlink">
<info>
<title>Technical Overview</title>
</info>
@ -98,18 +99,25 @@ if (principal instanceof UserDetails) {
answer is that there is a special interface called
<interfacename>UserDetailsService</interfacename>. The only method on this interface
accepts a <literal>String</literal>-based username argument and returns a
<interfacename>UserDetails</interfacename>. Most authentication providers that ship with
Spring Security delegate to a <interfacename>UserDetailsService</interfacename> as part of
the authentication process. The <interfacename>UserDetailsService</interfacename> is used to
<interfacename>UserDetails</interfacename>:
<programlisting language="java">
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
</programlisting>
This is the most common approach to loading information for a user within Spring Security
and you will see it used throughout the framework whenever information on a user is
required.</para>
<para> On successful authentication, <interfacename>UserDetails</interfacename> is used to
build the <interfacename>Authentication</interfacename> object that is stored in the
<classname>SecurityContextHolder</classname>. The good news is that we provide a number of
<interfacename>UserDetailsService</interfacename> implementations, including one that uses
an in-memory map and another that uses JDBC. Most users tend to write their own, though,
with their implementations often simply sitting on top of an existing Data Access Object
(DAO) that represents their employees, customers, or other users of the enterprise
application. Remember the advantage that whatever your UserDetailsService returns can always
be obtained from the <classname>SecurityContextHolder</classname>, as per the above code
fragment.</para>
<classname>SecurityContextHolder</classname> (more on this in <link
xlink:href="#tech-intro-authentication-mgr"/> below). The good news is that we provide a
number of <interfacename>UserDetailsService</interfacename> implementations, including one
that uses an in-memory map (<classname>InMemoryDaoImpl</classname>) and another that uses
JDBC (<interfacename>JdbcDaoImpl</interfacename>). Most users tend to write their own,
though, with their implementations often simply sitting on top of an existing Data Access
Object (DAO) that represents their employees, customers, or other users of the application.
Remember the advantage that whatever your <interfacename>UserDetailsService</interfacename>
returns can always be obtained from the <classname>SecurityContextHolder</classname> using
the above code fragment. </para>
</section>
<section xml:id="tech-granted-authority">
<title>GrantedAuthority</title>
@ -222,8 +230,8 @@ if (principal instanceof UserDetails) {
the returned authentication object.</para>
</listitem>
</orderedlist>From that point on, the user is considered to be authenticated. Let's look at
some code as an
example.<programlisting language="java">import org.springframework.security.authentication.*;
some code as an example.
<programlisting language="java">import org.springframework.security.authentication.*;
import org.springframework.security.core.*;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.context.SecurityContextHolder;
@ -268,8 +276,8 @@ class SampleAuthenticationManager implements AuthenticationManager {
throw new BadCredentialsException("Bad Credentials");
}
}</programlisting>Here
we have written a little program that asks the user to enter a username and password
and performs the above sequence. The <interfacename>AuthenticationManager</interfacename> which
we have written a little program that asks the user to enter a username and password and
performs the above sequence. The <interfacename>AuthenticationManager</interfacename> which
we've implemented here will authenticate any user whose username and password are the same.
It assigns a single role to every user. The output from the above will be something
like:<programlisting>
@ -290,8 +298,8 @@ Successfully authenticated. Security context contains: \
</programlisting></para>
<para>Note that you don't normally need to write any code like this. The process will normally
occur internally, in a web authentication filter for example. We've just included the code
here to show that the question of what actually constitutes authentication in Spring Security
has quite a simple answer. A user is authenticated when the
here to show that the question of what actually constitutes authentication in Spring
Security has quite a simple answer. A user is authenticated when the
<classname>SecurityContextHolder</classname> contains a fully populated
<interfacename>Authentiation</interfacename> object.</para>
<section>
@ -314,138 +322,141 @@ Successfully authenticated. Security context contains: \
Spring Security-specific <interfacename>Authentication</interfacename> object, and put it
onto the <classname>SecurityContextHolder</classname>.</para>
</section>
<section>
<title>The <interfacename>AuthenticationManager</interfacename></title>
<para>The <interfacename>AuthenticationManager</interfacename> is just an interface, so the
implementation can be anything we choose, but how does it work in practice. What if we
need to check multiple authentication databases? The default implementation in Spring
Security is called <classname>ProviderManager</classname> and rather than handling the
authentication request itself, it delegates to a list of configured
<classname>AuthenticationProvider</classname>s, each of which is queried in turn to see
if it can perform the authentication. Each provider will either throw an exception or
return a fully populated <interfacename>Authentication</interfacename> object. Remember
our good friends, <interfacename>UserDetails</interfacename> and
<interfacename>UserDetailsService</interfacename>? If not, head back to the previous
section and refresh your memory. Most <classname>AuthenticationProvider</classname>s will
ask a <interfacename>UserDetailsService</interfacename> to provide a
<interfacename>UserDetails</interfacename> object. The resulting
<interfacename>UserDetails</interfacename> object - and particularly the
<literal>GrantedAuthority</literal>s it contains - will be used when building the fully
populated <interfacename>Authentication</interfacename> object.</para>
</section>
</section>
<section xml:id="tech-intro-authentication-mgr">
<title>The <interfacename>AuthenticationManager</interfacename></title>
<para>The <interfacename>AuthenticationManager</interfacename> is just an interface, so the
implementation can be anything we choose, but how does it work in practice. What if we need
to check multiple authentication databases? The default implementation in Spring Security is
called <classname>ProviderManager</classname> and rather than handling the authentication
request itself, it delegates to a list of configured
<classname>AuthenticationProvider</classname>s, each of which is queried in turn to see if
it can perform the authentication. Each provider will either throw an exception or return a
fully populated <interfacename>Authentication</interfacename> object. Remember our good
friends, <interfacename>UserDetails</interfacename> and
<interfacename>UserDetailsService</interfacename>? If not, head back to the previous
section and refresh your memory. The most common approach to verifying an authentication
request is to load the corresponding <interfacename>UserDetails</interfacename> and check
the loaded password against the one that has been entered by the user. This is the approach
used by the <classname>DaoAuthenticationProvider</classname>, which is most commonly used to
wrap a <interfacename>UserDetailsService</interfacename> to implement an
<interfacename>AuthenticationProvider</interfacename>. The loaded
<interfacename>UserDetails</interfacename> object - and particularly the
<literal>GrantedAuthority</literal>s it contains - will be used when building the fully
populated <interfacename>Authentication</interfacename> object which is returned from a
successful authentication and stored in the <classname>SecurityContext</classname>.</para>
</section>
</section>
<section>
<title>Authentication in a Web Application</title>
<para> Now let's explore the situation where you are using Spring Security in a web application
(without <filename>web.xml</filename> security enabled). How is a user authenticated and the
security context established?</para>
<para>Consider a typical web application's authentication process:</para>
<orderedlist inheritnum="ignore" continuation="restarts">
<listitem>
<para>You visit the home page, and click on a link.</para>
</listitem>
<listitem>
<para>A request goes to the server, and the server decides that you've asked for a protected
resource.</para>
</listitem>
<listitem>
<para>As you're not presently authenticated, the server sends back a response indicating
that you must authenticate. The response will either be an HTTP response code, or a
redirect to a particular web page.</para>
</listitem>
<listitem>
<para>Depending on the authentication mechanism, your browser will either redirect to the
specific web page so that you can fill out the form, or the browser will somehow retrieve
your identity (via a BASIC authentication dialogue box, a cookie, a X.509 certificate
etc.).</para>
</listitem>
<listitem>
<para>The browser will send back a response to the server. This will either be an HTTP POST
containing the contents of the form that you filled out, or an HTTP header containing your
authentication details.</para>
</listitem>
<listitem>
<para>Next the server will decide whether or not the presented credentials are valid. If
they're valid, the next step will happen. If they're invalid, usually your browser will be
asked to try again (so you return to step two above).</para>
</listitem>
<listitem>
<para>The original request that you made to cause the authentication process will be
retried. Hopefully you've authenticated with sufficient granted authorities to access the
protected resource. If you have sufficient access, the request will be successful.
Otherwise, you'll receive back an HTTP error code 403, which means "forbidden".</para>
</listitem>
</orderedlist>
<para>Spring Security has distinct classes responsible for most of the steps described above.
The main participants (in the order that they are used) are the
<classname>ExceptionTranslationFilter</classname>, an
<interfacename>AuthenticationEntryPoint</interfacename> and an <quote>authentication
mechanism</quote>, which is resposible for calling the
<classname>AuthenticationManager</classname> which we saw in the previous section.</para>
<section>
<title>ExceptionTranslationFilter</title>
<para><classname>ExceptionTranslationFilter</classname> is a Spring Security filter that has
responsibility for detecting any Spring Security exceptions that are thrown. Such exceptions
will generally be thrown by an <classname>AbstractSecurityInterceptor</classname>, which is
the main provider of authorization services. We will discuss
<classname>AbstractSecurityInterceptor</classname> in the next section, but for now we
just need to know that it produces Java exceptions and knows nothing about HTTP or how to go
about authenticating a principal. Instead the
<classname>ExceptionTranslationFilter</classname> offers this service, with specific
responsibility for either returning error code 403 (if the principal has been authenticated
and therefore simply lacks sufficient access - as per step seven above), or launching an
<interfacename>AuthenticationEntryPoint</interfacename> (if the principal has not been
authenticated and therefore we need to go commence step three).</para>
</section>
<section xml:id="tech-auth-entry-point">
<title>AuthenticationEntryPoint</title>
<para>The <interfacename>AuthenticationEntryPoint</interfacename> is responsible for step
three in the above list. As you can imagine, each web application will have a default
authentication strategy (well, this can be configured like nearly everything else in Spring
Security, but let's keep it simple for now). Each major authentication system will have its
own <interfacename>AuthenticationEntryPoint</interfacename> implementation, which typically
performs one of the actions described in step 3.</para>
</section>
<section>
<title>Authentication in a Web Application</title>
<para> Now let's explore the situation where you are using Spring Security in a web
application (without <filename>web.xml</filename> security enabled). How is a user
authenticated and the security context established?</para>
<para>Consider a typical web application's authentication process:</para>
<orderedlist inheritnum="ignore" continuation="restarts">
<listitem>
<para>You visit the home page, and click on a link.</para>
</listitem>
<listitem>
<para>A request goes to the server, and the server decides that you've asked for a
protected resource.</para>
</listitem>
<listitem>
<para>As you're not presently authenticated, the server sends back a response indicating
that you must authenticate. The response will either be an HTTP response code, or a
redirect to a particular web page.</para>
</listitem>
<listitem>
<para>Depending on the authentication mechanism, your browser will either redirect to the
specific web page so that you can fill out the form, or the browser will somehow
retrieve your identity (via a BASIC authentication dialogue box, a cookie, a X.509
certificate etc.).</para>
</listitem>
<listitem>
<para>The browser will send back a response to the server. This will either be an HTTP
POST containing the contents of the form that you filled out, or an HTTP header
containing your authentication details.</para>
</listitem>
<listitem>
<para>Next the server will decide whether or not the presented credentials are valid. If
they're valid, the next step will happen. If they're invalid, usually your browser will
be asked to try again (so you return to step two above).</para>
</listitem>
<listitem>
<para>The original request that you made to cause the authentication process will be
retried. Hopefully you've authenticated with sufficient granted authorities to access
the protected resource. If you have sufficient access, the request will be successful.
Otherwise, you'll receive back an HTTP error code 403, which means "forbidden".</para>
</listitem>
</orderedlist>
<para>Spring Security has distinct classes responsible for most of the steps described above.
The main participants (in the order that they are used) are the
<classname>ExceptionTranslationFilter</classname>, an
<interfacename>AuthenticationEntryPoint</interfacename> and an <quote>authentication
mechanism</quote>, which is resposible for calling the
<classname>AuthenticationManager</classname> which we saw in the previous section.</para>
<section>
<title>ExceptionTranslationFilter</title>
<para><classname>ExceptionTranslationFilter</classname> is a Spring Security filter that has
responsibility for detecting any Spring Security exceptions that are thrown. Such
exceptions will generally be thrown by an
<classname>AbstractSecurityInterceptor</classname>, which is the main provider of
authorization services. We will discuss <classname>AbstractSecurityInterceptor</classname>
in the next section, but for now we just need to know that it produces Java exceptions and
knows nothing about HTTP or how to go about authenticating a principal. Instead the
<classname>ExceptionTranslationFilter</classname> offers this service, with specific
responsibility for either returning error code 403 (if the principal has been
authenticated and therefore simply lacks sufficient access - as per step seven above), or
launching an <interfacename>AuthenticationEntryPoint</interfacename> (if the principal has
not been authenticated and therefore we need to go commence step three).</para>
</section>
<section xml:id="tech-auth-entry-point">
<title>AuthenticationEntryPoint</title>
<para>The <interfacename>AuthenticationEntryPoint</interfacename> is responsible for step
three in the above list. As you can imagine, each web application will have a default
authentication strategy (well, this can be configured like nearly everything else in
Spring Security, but let's keep it simple for now). Each major authentication system will
have its own <interfacename>AuthenticationEntryPoint</interfacename> implementation, which
typically performs one of the actions described in step 3.</para>
</section>
<section>
<title>Authentication Mechanism</title>
<para>Once your browser submits your authentication credentials (either as an HTTP form post
or HTTP header) there needs to be something on the server that <quote>collects</quote>
these authentication details. By now we're at step six in the above list. In Spring
Security we have a special name for the function of collecting authentication details from
a user agent (usually a web browser), referring to it as the <quote>authentication
mechanism</quote>. Examples are form-base login and Basic authentication. Once the
authentication details have been collected from the user agent, an
<interfacename>Authentication</interfacename>
<quote>request</quote> object is built and then presented to the
<interfacename>AuthenticationManager</interfacename>.</para>
<para>After the authentication mechanism receives back the fully-populated
<interfacename>Authentication</interfacename> object, it will deem the request valid,
put the <interfacename>Authentication</interfacename> into the
<classname>SecurityContextHolder</classname>, and cause the original request to be
retried (step seven above). If, on the other hand, the
<classname>AuthenticationManager</classname> rejected the request, the authentication
mechanism will ask the user agent to retry (step two above).</para>
</section>
<section xml:id="tech-sec-context-persistence">
<title>Storing the <interfacename>SecurityContext</interfacename> between requests</title>
<para>Depending on the type of application, there may need to be a strategy in place to
store the security context between user operations. In a typical web application, a user
logs in once and is subsequently identified by their session Id. The server caches the
principal information for the duration session. In Spring Security, the responsibility for
storing the <interfacename>SecurityContext</interfacename> between requests falls to the
<classname>SecurityContextPersistenceFilter</classname>, which by default stores the
context as an <literal>HttpSession</literal> attribute between HTTP requests. It restores
the context to the <classname>SecurityContextHolder</classname> for each request and,
crucially, clears the <classname>SecurityContextHolder</classname> when the request
completes. You shouldn't interact directly with the <literal>HttpSession</literal> for
security purposes. There is simply no justification for doing so - always use the
<classname>SecurityContextHolder</classname> instead. </para>
<para> Many other types of application (for example, a stateless RESTful web service) do not
use HTTP sessions and will re-authenticate on every request. However, it is still
important that the <classname>SecurityContextPersistenceFilter</classname> is included in
the chain to make sure that the <classname>SecurityContextHolder</classname> is cleared
after each request.</para>
</section>
<title>Authentication Mechanism</title>
<para>Once your browser submits your authentication credentials (either as an HTTP form post
or HTTP header) there needs to be something on the server that <quote>collects</quote> these
authentication details. By now we're at step six in the above list. In Spring Security we
have a special name for the function of collecting authentication details from a user agent
(usually a web browser), referring to it as the <quote>authentication mechanism</quote>.
Examples are form-base login and Basic authentication. Once the authentication details have
been collected from the user agent, an <interfacename>Authentication</interfacename>
<quote>request</quote> object is built and then presented to the
<interfacename>AuthenticationManager</interfacename>.</para>
<para>After the authentication mechanism receives back the fully-populated
<interfacename>Authentication</interfacename> object, it will deem the request valid, put
the <interfacename>Authentication</interfacename> into the
<classname>SecurityContextHolder</classname>, and cause the original request to be retried
(step seven above). If, on the other hand, the <classname>AuthenticationManager</classname>
rejected the request, the authentication mechanism will ask the user agent to retry (step
two above).</para>
</section>
<section xml:id="tech-sec-context-persistence">
<title>Storing the <interfacename>SecurityContext</interfacename> between requests</title>
<para>Depending on the type of application, there may need to be a strategy in place to store
the security context between user operations. In a typical web application, a user logs in
once and is subsequently identified by their session Id. The server caches the principal
information for the duration session. In Spring Security, the responsibility for storing the
<interfacename>SecurityContext</interfacename> between requests falls to the
<classname>SecurityContextPersistenceFilter</classname>, which by default stores the
context as an <literal>HttpSession</literal> attribute between HTTP requests. It restores
the context to the <classname>SecurityContextHolder</classname> for each request and,
crucially, clears the <classname>SecurityContextHolder</classname> when the request
completes. You shouldn't interact directly with the <literal>HttpSession</literal> for
security purposes. There is simply no justification for doing so - always use the
<classname>SecurityContextHolder</classname> instead. </para>
<para> Many other types of application (for example, a stateless RESTful web service) do not
use HTTP sessions and will re-authenticate on every request. However, it is still important
that the <classname>SecurityContextPersistenceFilter</classname> is included in the chain to
make sure that the <classname>SecurityContextHolder</classname> is cleared after each
request.</para>
</section>
</section>
<section xml:id="tech-intro-access-control">
@ -470,9 +481,9 @@ Successfully authenticated. Security context contains: \
help you protect method invocations as well as web requests. Most people are interested in
securing method invocations on their services layer. This is because the services layer is
where most business logic resides in current-generation J2EE applications. If you just need
to secure method invocations in the services layer, Spring's standard AOP (otherwise known
as AOP Alliance) will be adequate. If you need to secure domain objects directly, you will
likely find that AspectJ is worth considering.</para>
to secure method invocations in the services layer, Spring's standard AOP will be adequate.
If you need to secure domain objects directly, you will likely find that AspectJ is worth
considering.</para>
<para>You can elect to perform method authorization using AspectJ or Spring AOP, or you can
elect to perform web request authorization using filters. You can use zero, one, two or
three of these approaches together. The mainstream usage pattern is to perform some web
@ -515,11 +526,12 @@ Successfully authenticated. Security context contains: \
the invocation has returned.</para>
</listitem>
</orderedlist></para>
<section>
<section xml:id="tech-intro-config-attributes">
<title>What are Configuration Attributes?</title>
<para> A <quote>configuration attribute</quote> can be thought of as a String that has
special meaning to the classes used by <classname>AbstractSecurityInterceptor</classname>.
They may be simple role names or have more complex meaning, depending on the how
They are represented by the interface <interfacename>ConfigAttribute</interfacename> within
the framework. They may be simple role names or have more complex meaning, depending on the how
sophisticated the <interfacename>AccessDecisionManager</interfacename> implementation is.
The <classname>AbstractSecurityInterceptor</classname> is configured with a
<interfacename>SecurityMetadataSource</interfacename> which it uses to look up the
@ -550,11 +562,11 @@ Successfully authenticated. Security context contains: \
<classname>AbstractSecurityInterceptor</classname> gets one final chance to handle the
invocation. At this stage the <classname>AbstractSecurityInterceptor</classname> is
interested in possibly modifying the return object. We might want this to happen because
an authorization decision couldn't be made <quote>on the way in</quote> to a secure object invocation.
Being highly pluggable, <classname>AbstractSecurityInterceptor</classname> will pass
control to an <literal>AfterInvocationManager</literal> to actually modify the object if
needed. This class can even entirely replace the object, or throw an exception, or not
change it in any way as it chooses.</para>
an authorization decision couldn't be made <quote>on the way in</quote> to a secure object
invocation. Being highly pluggable, <classname>AbstractSecurityInterceptor</classname>
will pass control to an <literal>AfterInvocationManager</literal> to actually modify the
object if needed. This class can even entirely replace the object, or throw an exception,
or not change it in any way as it chooses.</para>
<para><classname>AbstractSecurityInterceptor</classname> and its related objects are shown
in <xref linkend="abstract-security-interceptor"/>. <figure
xml:id="abstract-security-interceptor">
@ -582,65 +594,48 @@ Successfully authenticated. Security context contains: \
</section>
<section xml:id="localization">
<title>Localization</title>
<para>Spring Security supports localization of exception messages that
end users are likely to see. If your application is designed for
English-speaking users, you don't need to do anything as by default all
Security Security messages are in English. If you need to support
other locales, everything you need to know is contained in this
section.</para>
<para>All exception messages can be localized, including messages
related to authentication failures and access being denied
(authorization failures). Exceptions and logging that is focused on
developers or system deployers (including incorrect attributes,
interface contract violations, using incorrect constructors, startup
time validation, debug-level logging) etc are not localized and
instead are hard-coded in English within Spring Security's
code.</para>
<para>Shipping in the <literal>spring-security-core-xx.jar</literal> you
will find an <literal>org.springframework.security</literal> package
that in turn contains a <literal>messages.properties</literal> file.
This should be referred to by your
<literal>ApplicationContext</literal>, as Spring Security classes
implement Spring's <literal>MessageSourceAware</literal> interface and
expect the message resolver to be dependency injected at application
context startup time. Usually all you need to do is register a bean
inside your application context to refer to the messages. An example
is shown below:</para>
<para><programlisting><![CDATA[
<para>Spring Security supports localization of exception messages that end users are likely to
see. If your application is designed for English-speaking users, you don't need to do anything
as by default all Security Security messages are in English. If you need to support other
locales, everything you need to know is contained in this section.</para>
<para>All exception messages can be localized, including messages related to authentication
failures and access being denied (authorization failures). Exceptions and logging that is
focused on developers or system deployers (including incorrect attributes, interface contract
violations, using incorrect constructors, startup time validation, debug-level logging) etc
are not localized and instead are hard-coded in English within Spring Security's code.</para>
<para>Shipping in the <literal>spring-security-core-xx.jar</literal> you will find an
<literal>org.springframework.security</literal> package that in turn contains a
<literal>messages.properties</literal> file. This should be referred to by your
<literal>ApplicationContext</literal>, as Spring Security classes implement Spring's
<literal>MessageSourceAware</literal> interface and expect the message resolver to be
dependency injected at application context startup time. Usually all you need to do is
register a bean inside your application context to refer to the messages. An example is shown
below:</para>
<para>
<programlisting><![CDATA[
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="org/springframework/security/messages"/>
</bean>
]]></programlisting></para>
<para>The <literal>messages.properties</literal> is named in
accordance with standard resource bundles and represents the default
language supported by Spring Security messages. This default file is
in English. If you do not register a message source, Spring Security
will still work correctly and fallback to hard-coded English versions
of the messages.</para>
<para>If you wish to customize the
<literal>messages.properties</literal> file, or support other
languages, you should copy the file, rename it accordingly, and
register it inside the above bean definition. There are not a large
number of message keys inside this file, so localization should not be
considered a major initiative. If you do perform localization of this
file, please consider sharing your work with the community by logging
a JIRA task and attaching your appropriately-named localized version
of <literal>messages.properties</literal>.</para>
<para>Rounding out the discussion on localization is the Spring
<literal>ThreadLocal</literal> known as
<classname>org.springframework.context.i18n.LocaleContextHolder</classname>.
You should set the <classname>LocaleContextHolder</classname> to represent
the preferred <literal>Locale</literal> of each user. Spring Security
will attempt to locate a message from the message source using the
<literal>Locale</literal> obtained from this
<literal>ThreadLocal</literal>. Please refer to the Spring Framework documentation
for further details on using <literal>LocaleContextHolder</literal>.</para>
</section>
]]></programlisting>
</para>
<para>The <literal>messages.properties</literal> is named in accordance with standard resource
bundles and represents the default language supported by Spring Security messages. This
default file is in English. If you do not register a message source, Spring Security will
still work correctly and fallback to hard-coded English versions of the messages.</para>
<para>If you wish to customize the <literal>messages.properties</literal> file, or support other
languages, you should copy the file, rename it accordingly, and register it inside the above
bean definition. There are not a large number of message keys inside this file, so
localization should not be considered a major initiative. If you do perform localization of
this file, please consider sharing your work with the community by logging a JIRA task and
attaching your appropriately-named localized version of
<literal>messages.properties</literal>.</para>
<para>Rounding out the discussion on localization is the Spring <literal>ThreadLocal</literal>
known as <classname>org.springframework.context.i18n.LocaleContextHolder</classname>. You
should set the <classname>LocaleContextHolder</classname> to represent the preferred
<literal>Locale</literal> of each user. Spring Security will attempt to locate a message
from the message source using the <literal>Locale</literal> obtained from this
<literal>ThreadLocal</literal>. Please refer to the Spring Framework documentation for
further details on using <literal>LocaleContextHolder</literal>.</para>
</section>
</chapter>

View File

@ -0,0 +1,236 @@
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="web-infrastructure"
xmlns:xlink="http://www.w3.org/1999/xlink">
<info>
<title>Web Application Infrastructure</title>
</info>
<para> Most Spring Security users will be using the framework in applications which make user of
the HTTP and the Servlet API. In this and the following chapters, we'll take a look at how
Spring Security provides authentication and access-control features for the web layer of an
application. We'll look behind the facade of the namespace and see which classes and interfaces
are actually assembled to provide web-layer security. In some situations it is necessary to use
traditional bean configuration to provide full control over the configuration, so we'll also see
how to configure these classes directly without the namespace.</para>
<section xml:id="filters">
<title>Security Filter</title>
<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
it has no strong links to any particular web technology. It deals in
<classname>HttpServletRequest</classname>s and <classname>HttpServletResponse</classname>s
and doesn't care whether the requests come from a browser, a web service client, an
<classname>HttpInvoker</classname> or an AJAX application. </para>
<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
which services are required. The ordering of the filters is important as there are
dependencies 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
have to define any Spring beans explicitly but here may be times when you want full control
over the security filter chain, either because you are using features which aren't supported
in the namespace, or you are using your own customized versions of classes.</para>
<section xml:id="delegating-filter-proxy">
<title><classname>DelegatingFilterProxy</classname></title>
<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
Security, the filter classes are also Spring beans defined in the application context and
thus able to take advantage of Spring's rich dependency-injection facilities and lifecycle
interfaces. Spring's <classname>DelegatingFilterProxy</classname> provides the link between
<filename>web.xml</filename> and the application context. </para>
<para>When using <classname>DelegatingFilterProxy</classname>, you will see something like
this in the <filename>web.xml</filename> file: <programlisting><![CDATA[
<filter>
<filter-name>myFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>myFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>]]>
</programlisting> Notice that the filter is actually a
<literal>DelegatingFilterProxy</literal>, and not the class that will actually implement
the logic of the filter. What <classname>DelegatingFilterProxy</classname> does is delegate
the <interfacename>Filter</interfacename>'s methods through to a bean which is obtained from
the Spring application context. This enables the bean to benefit from the Spring web
application context lifecycle support and configuration flexibility. The bean must implement
<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
<classname>DelegatingFilterProxy</classname> for more information</para>
</section>
<section xml:id="filter-chain-proxy">
<title><classname>FilterChainProxy</classname></title>
<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
<classname>DelegatingFilterProxy</classname> entry to <filename>web.xml</filename> for
each 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
would prefer to just add a single entry to <filename>web.xml</filename> and deal entirely
with 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
<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
filter chain is then declared in the application context with the same bean name. Here's an
example: <programlisting language="xml"><![CDATA[
<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
<sec:filter-chain-map path-type="ant">
<sec:filter-chain pattern="/webServices/**" filters="
securityContextPersistenceFilterWithASCFalse,
basicProcessingFilter,
exceptionTranslationFilter,
filterSecurityInterceptor" />
<sec:filter-chain pattern="/**" filters="
securityContextPersistenceFilterWithASCTrue,
authenticationProcessingFilter,
exceptionTranslationFilter,
filterSecurityInterceptor" />
</sec:filter-chain-map>
</bean>
]]>
</programlisting> The namespace element <literal>filter-chain-map</literal> is
used to set up the security filter chain(s) which are required within the application<footnote>
<para>Note that you'll need to include the security namespace in your application context
XML file in order to use this syntax.</para>
</footnote>. It maps a particular URL pattern to a chain of filters built up from the bean
names specified in the <literal>filters</literal> element. Both regular expressions and Ant
Paths are supported, and the most specific URIs appear first. At runtime 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>
attribute will be applied to that request. The filters will be invoked in the order they are
defined, so you have complete control over the filter chain which is applied to a particular
URL.</para>
<para>You may have noticed we have declared two
<classname>SecurityContextPersistenceFilter</classname>s in the filter chain
(<literal>ASC</literal> is short for <literal>allowSessionCreation</literal>, a property
of <classname>SecurityContextPersistenceFilter</classname>). As web services will never
present a <literal>jsessionid</literal> on future requests, creating
<literal>HttpSession</literal>s for such user agents would be wasteful. If you had a
high-volume application which required maximum scalability, we recommend you use the
approach shown above. For smaller applications, using a single
<classname>SecurityContextPersistenceFilter</classname> (with its default
<literal>allowSessionCreation</literal> as <literal>true</literal>) would likely be
sufficient.</para>
<para>In relation to lifecycle issues, the <classname>FilterChainProxy</classname> will always
delegate <methodname>init(FilterConfig)</methodname> and <methodname>destroy()</methodname>
methods through to the underlaying <interfacename>Filter</interfacename>s if such methods
are called against <classname>FilterChainProxy</classname> itself. In this case,
<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
chain(s). You control the overall choice as to whether these methods are called or not via
the <literal>targetFilterLifecycle</literal> initialization parameter of
<literal>DelegatingFilterProxy</literal>. By default this property is
<literal>false</literal> and servlet container lifecycle invocations are not delegated
through <literal>DelegatingFilterProxy</literal>.</para>
<para> When we looked at how to set up web security using <link
xlink:href="#namespace-auto-config">namespace configuration</link>, we used a
<literal>DelegatingFilterProxy</literal> with the name
<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>
<section>
<title>Bypassing the Filter Chain</title>
<para> As with the namespace, you can use the attribute <literal>filters = "none"</literal>
as an alternative to supplying a filter bean list. This will omit the request pattern from
the security filter chain entirely. Note that anything matching this path will then have
no authentication or authorization services applied and will be freely accessible. If you
want to make use of the contents of the <classname>SecurityContext</classname> contents
during a request, then it must have passed through the security filter chain. Otherwise
the <classname>SecurityContextHolder</classname> will not have been populated and the
contents will be null.</para>
</section>
</section>
<section>
<title>Filter Ordering</title>
<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: <orderedlist
inheritnum="ignore" continuation="restarts">
<listitem>
<para><classname>ChannelProcessingFilter</classname>, because it might need to redirect
to a different protocol</para>
</listitem>
<listitem>
<para><classname>ConcurrentSessionFilter</classname>, because it doesn't use any
<classname>SecurityContextHolder</classname> functionality but needs to update 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
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
next web request)</para>
</listitem>
<listitem>
<para>Authentication processing mechanisms -
<classname>UsernamePasswordAuthenticationProcessingFilter</classname>,
<classname>CasProcessingFilter</classname>,
<classname>BasicProcessingFilter</classname> etc - so that the
<classname>SecurityContextHolder</classname> can be modified to contain a valid
<interfacename>Authentication</interfacename> request token</para>
</listitem>
<listitem>
<para>The <literal>SecurityContextHolderAwareRequestFilter</literal>, if you are using
it to install a Spring Security aware <literal>HttpServletRequestWrapper</literal>
into your servlet container</para>
</listitem>
<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
enables remember-me services to take place, a suitable remembered
<interfacename>Authentication</interfacename> object will be put there</para>
</listitem>
<listitem>
<para><classname>AnonymousProcessingFilter</classname>, so that if no earlier
authentication processing mechanism updated the
<classname>SecurityContextHolder</classname>, an anonymous
<interfacename>Authentication</interfacename> object will be put there</para>
</listitem>
<listitem>
<para><classname>ExceptionTranslationFilter</classname>, to catch any Spring Security
exceptions so that either an HTTP error response can be returned or an appropriate
<interfacename>AuthenticationEntryPoint</interfacename> can be launched</para>
</listitem>
<listitem>
<para><classname>FilterSecurityInterceptor</classname>, to protect web URIs and raise
exceptions when access is denied</para>
</listitem>
</orderedlist></para>
</section>
<section>
<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
sure that the Spring Security filters come first. This enables the
<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
Wicket which uses a filter to handle its requests. </para>
</section>
</section>
<!--
<section xml:id="taglib">
<info>
<title>Tag Libraries</title>
</info>
<para>Spring Security comes bundled with several JSP tag libraries which provide a range of
different services.</para>
<section xml:id="taglib-config">
<info>
<title>Configuration</title>
</info>
<para>All taglib classes are included in the core
<literal>spring-security-taglibs-&lt;version>.jar</literal> file, with the
<literal>security.tld</literal> located in the JAR's <literal>META-INF</literal>
directory. This means for JSP 1.2+ web containers you can simply include the JAR in the
WAR's <literal>WEB-INF/lib</literal> directory and it will be available.</para>
</section>
<section xml:id="taglib-usage">
<info>
<title>Usage</title>
</info>
<para>Now that you've configured the tag libraries, refer to the individual reference guide
sections for details on how to use them. Note that when using the tags, you should include
the taglib reference in your JSP:
<programlisting>
&lt;%@ taglib prefix='security' uri='http://www.springframework.org/security/tags' %&gt;
</programlisting></para>
</section>
</section>-->
</chapter>