mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-05-31 17:22:13 +00:00
732 lines
43 KiB
XML
732 lines
43 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="ns-config"
|
|
xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<info>
|
|
<title>Security Namespace Configuration</title>
|
|
</info>
|
|
<section>
|
|
<title>Introduction</title>
|
|
<para> Namespace configuration has been available since version 2.0 of the Spring framework. It
|
|
allows you to supplement the traditional Spring beans application context syntax with elements
|
|
from additional XML schema. You can find more information in the Spring <link
|
|
xlink:href="http://static.springframework.org/spring/docs/2.5.x/reference/xsd-config.html">
|
|
Reference Documentation</link>. A namespace element can be used simply to allow a more
|
|
concise way of configuring an individual bean or, more powerfully, to define an alternative
|
|
configuration syntax which more closely matches the problem domain and hides the underlying
|
|
complexity from the user. A simple element may conceal the fact that multiple beans and
|
|
processing steps are being added to the application context. For example, adding the following
|
|
element from the security namespace to an application context will start up an embedded LDAP
|
|
server for testing use within the application: <programlisting><![CDATA[
|
|
<security:ldap-server />
|
|
]]></programlisting> This is much simpler than wiring up the equivalent Apache Directory Server
|
|
beans. The most common alternative configuration requirements are supported by attributes on
|
|
the <literal>ldap-server</literal> element and the user is isolated from worrying about which
|
|
beans they need to be set on and what the bean property names are. <footnote>
|
|
<para>You can find out more about the use of the <literal>ldap-server</literal> element in
|
|
the chapter on <link xlink:href="#ldap">LDAP</link>.</para>
|
|
</footnote>. Use of a good XML editor while editing the application context file should
|
|
provide information on the attributes and elements that are available. We would recommend that
|
|
you try out the <link xlink:href="http://www.springsource.com/products/sts">SpringSource Tool
|
|
Suite</link> as it has special features for working with standard Spring namespaces. </para>
|
|
<para> To start using the security namespace in your application context, all you need to do is
|
|
add the schema declaration to your application context file: <programlisting language="xml">
|
|
<![CDATA[
|
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
|
xmlns:security="http://www.springframework.org/schema/security"
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
|
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
|
http://www.springframework.org/schema/security
|
|
http://www.springframework.org/schema/security/spring-security-3.0.xsd">
|
|
...
|
|
</beans>
|
|
]]></programlisting> In many of the examples you will see (and in the sample) applications, we
|
|
will often use "security" as the default namespace rather than "beans", which means we can
|
|
omit the prefix on all the security namespace elements, making the context easier to read. You
|
|
may also want to do this if you have your application context divided up into separate files
|
|
and have most of your security configuration in one of them. Your security application context
|
|
file would then start like this <programlisting language="xml"><![CDATA[
|
|
<beans:beans xmlns="http://www.springframework.org/schema/security"
|
|
xmlns:beans="http://www.springframework.org/schema/beans"
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
|
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
|
http://www.springframework.org/schema/security
|
|
http://www.springframework.org/schema/security/spring-security-3.0.xsd">
|
|
...
|
|
</beans:beans>
|
|
]]></programlisting> We'll assume this syntax is being used from now on in this chapter. </para>
|
|
<section>
|
|
<title>Design of the Namespace</title>
|
|
<para> The namespace is designed to capture the most common uses of the framework and provide
|
|
a simplified and concise syntax for enabling them within an application. The design is based
|
|
around the large-scale dependencies within the framework, and can be divided up into the
|
|
following areas: <itemizedlist>
|
|
<listitem>
|
|
<para>
|
|
<emphasis>Web/HTTP Security</emphasis> - the most complex part. Sets up the filters
|
|
and related service beans used to apply the framework authentication mechanisms, to
|
|
secure URLs, render login and error pages and much more.</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
<emphasis>Business Object (Method) Security</emphasis> - options for securing the
|
|
service layer.</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
<emphasis>AuthenticationManager</emphasis> - handles authentication requests from
|
|
other parts of the framework.</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
<emphasis>AccessDecisionManager</emphasis> - provides access decisions for web and
|
|
method security. A default one will be registered, but you can also choose to use a
|
|
custom one, declared using normal Spring bean syntax.</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
<emphasis>AuthenticationProvider</emphasis>s - mechanisms against which the
|
|
authentication manager authenticates users. The namespace provides supports for
|
|
several standard options and also a means of adding custom beans declared using a
|
|
traditional syntax. </para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
<emphasis>UserDetailsService</emphasis> - closely related to authentication providers,
|
|
but often also required by other beans.</para>
|
|
</listitem>
|
|
<!-- todo: diagram and link to other sections which describe the interfaces -->
|
|
</itemizedlist></para>
|
|
<para>We'll see how these work together in the following sections.</para>
|
|
</section>
|
|
</section>
|
|
<section xml:id="ns-getting-started">
|
|
<title>Getting Started with Security Namespace Configuration</title>
|
|
<para> In this section, we'll look at how you can build up a namespace configuration to use some
|
|
of the main features of the framework. Let's assume you initially want to get up and running
|
|
as quickly as possible and add authentication support and access control to an existing web
|
|
application, with a few test logins. Then we'll look at how to change over to authenticating
|
|
against a database or other security information repository. In later sections we'll introduce
|
|
more advanced namespace configuration options. </para>
|
|
<section xml:id="ns-web-xml">
|
|
<title><literal>web.xml</literal> Configuration</title>
|
|
<para> The first thing you need to do is add the following filter declaration to your
|
|
<literal>web.xml</literal> file: <programlisting language="xml"><![CDATA[
|
|
<filter>
|
|
<filter-name>springSecurityFilterChain</filter-name>
|
|
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
|
|
</filter>
|
|
|
|
<filter-mapping>
|
|
<filter-name>springSecurityFilterChain</filter-name>
|
|
<url-pattern>/*</url-pattern>
|
|
</filter-mapping>]]>
|
|
</programlisting> This provides a hook into the Spring Security web
|
|
infrastructure. <classname>DelegatingFilterProxy</classname> is a Spring Framework class
|
|
which delegates to a filter implementation which is defined as a Spring bean in your
|
|
application context. In this case, the bean is named "springSecurityFilterChain", which is
|
|
an internal infrastructure bean created by the namespace to handle web security. Note that
|
|
you should not use this bean name yourself. Once you've added this to your
|
|
<filename>web.xml</filename>, you're ready to start editing your application context file.
|
|
Web security services are configured using the <literal><http></literal> element.
|
|
</para>
|
|
</section>
|
|
<section xml:id="ns-minimal">
|
|
<title>A Minimal <literal><http></literal> Configuration</title>
|
|
<para> All you need to enable web security to begin with is <programlisting language="xml"><![CDATA[
|
|
<http auto-config='true'>
|
|
<intercept-url pattern="/**" access="ROLE_USER" />
|
|
</http>
|
|
]]>
|
|
</programlisting> Which says that we want all URLs within our application to be secured,
|
|
requiring the role <literal>ROLE_USER</literal> to access them.</para>
|
|
<note>
|
|
<para>You can use multiple <literal><intercept-url></literal> elements to define
|
|
different access requirements for different sets of URLs, but they will be evaluated in
|
|
the order listed and the first match will be used. So you must put the most specific
|
|
matches at the top.</para>
|
|
</note>
|
|
<para> To add some users, you can define a set of test data directly in the namespace: <programlisting language="xml"><![CDATA[
|
|
<authentication-manager>
|
|
<authentication-provider>
|
|
<user-service>
|
|
<user name="jimi" password="jimispassword" authorities="ROLE_USER, ROLE_ADMIN" />
|
|
<user name="bob" password="bobspassword" authorities="ROLE_USER" />
|
|
</user-service>
|
|
</authentication-provider>
|
|
</authentication-manager>
|
|
]]>
|
|
</programlisting></para>
|
|
<sidebar>
|
|
<para>If you are familiar with pre-namespace versions of the framework, you can probably
|
|
already guess roughly what's going on here. The <http> element is responsible for
|
|
creating a <classname>FilterChainProxy</classname> and the filter beans which it uses.
|
|
Common issues like incorrect filter ordering are no longer an issue as the filter
|
|
positions are predefined.</para>
|
|
<para>The <literal><authentication-provider></literal> element creates a
|
|
<classname>DaoAuthenticationProvider</classname> bean and the
|
|
<literal><user-service></literal> element creates an
|
|
<classname>InMemoryDaoImpl</classname>. All <literal>authentication-provider</literal>
|
|
elements must be within the <literal>authentication-manager</literal> element, which
|
|
creates a <classname>ProviderManager</classname> and registers the authentication
|
|
providers with it. You can find more detailed information on the beans that are created in
|
|
the <link xlink:href="#appendix-namespace">namespace appendix</link>. </para>
|
|
</sidebar>
|
|
<para> The configuration above defines two users, their passwords and their roles within the
|
|
application (which will be used for access control). It is also possible to load user
|
|
information from a standard properties file using the <literal>properties</literal>
|
|
attribute on <literal>user-service</literal>. See the section on <link
|
|
xlink:href="#in-memory-service">in-memory authentication</link> for more details. Using
|
|
the <literal><authentication-provider></literal> element means that the user
|
|
information will be used by the authentication manager to process authentication requests. </para>
|
|
<para> At this point you should be able to start up your application and you will be required
|
|
to log in to proceed. Try it out, or try experimenting with the "tutorial" sample
|
|
application that comes with the project. The above configuration actually adds quite a few
|
|
services to the application because we have used the <literal>auto-config</literal>
|
|
attribute. For example, form-based login processing is automatically enabled. </para>
|
|
<section xml:id="ns-auto-config">
|
|
<title>What does <literal>auto-config</literal> Include?</title>
|
|
<para> The <literal>auto-config</literal> attribute, as we have used it above, is just a
|
|
shorthand syntax for: <programlisting language="xml"><![CDATA[
|
|
<http>
|
|
<form-login />
|
|
<http-basic />
|
|
<logout />
|
|
</http>
|
|
]]>
|
|
</programlisting> These other elements are responsible for setting up form-login,
|
|
basic authentication and logout handling services respectively <footnote>
|
|
<para>In versions prior to 3.0, this list also inluded remember-me functionality. This
|
|
could cause some confusing errors with some configurations and was removed in 3.0. In
|
|
3.0, the addition of an <classname>AnonymousProcessingFilter</classname> was made part
|
|
of the default <literal><http></literal> configuration, so the
|
|
<literal><anonymous /></literal> element is effectively added regardless of
|
|
whether <literal>auto-config</literal> is enabled.</para>
|
|
</footnote> . They each have attributes which can be used to alter their behaviour.
|
|
</para>
|
|
</section>
|
|
<section xml:id="ns-form-and-basic">
|
|
<title>Form and Basic Login Options</title>
|
|
<para> You might be wondering where the login form came from when you were prompted to log
|
|
in, since we made no mention of any HTML files or JSPs. In fact, since we didn't
|
|
explicitly set a URL for the login page, Spring Security generates one automatically,
|
|
based on the features that are enabled and using standard values for the URL which
|
|
processes the submitted login, the default target URL the user will be sent to and so on.
|
|
However, the namespace offers plenty of suppport to allow you to customize these options.
|
|
For example, if you want to supply your own login page, you could use: <programlisting language="xml"><![CDATA[
|
|
<http auto-config='true'>
|
|
<intercept-url pattern="/login.jsp*" filters="none"/>
|
|
<intercept-url pattern="/**" access="ROLE_USER" />
|
|
<form-login login-page='/login.jsp'/>
|
|
</http>
|
|
]]>
|
|
</programlisting> Note that you could still use <literal>auto-config</literal>. The
|
|
<literal>form-login</literal> element just overrides the default settings. Also note
|
|
that we've added an extra <literal>intercept-url</literal> element to say that any
|
|
requests for the login page should be excluded from processing by the security filters.
|
|
Otherwise the request would be matched by the pattern <literal>/**</literal> and it
|
|
wouldn't be possible to access the login page itself! If you want to use basic
|
|
authentication instead of form login, then change the configuration to <programlisting language="xml"><![CDATA[
|
|
<http auto-config='true'>
|
|
<intercept-url pattern="/**" access="ROLE_USER" />
|
|
<http-basic />
|
|
</http>
|
|
]]>
|
|
</programlisting> Basic authentication will then take precedence and will be used to
|
|
prompt for a login when a user attempts to access a protected resource. Form login is
|
|
still available in this configuration if you wish to use it, for example through a login
|
|
form embedded in another web page. </para>
|
|
<section xml:id="ns-form-target">
|
|
<title>Setting a Default Post-Login Destination</title>
|
|
<para> If a form login isn't prompted by an attempt to access a protected resource, the
|
|
<literal>default-target-url</literal> option comes into play. This is the URL the user
|
|
will be taken to after logging in, and defaults to "/". You can also configure things so
|
|
that they user <emphasis>always</emphasis> ends up at this page (regardless of whether
|
|
the login was "on-demand" or they explicitly chose to log in) by setting the
|
|
<literal>always-use-default-target</literal> attribute to "true". This is useful if
|
|
your application always requires that the user starts at a "home" page, for example: <programlisting language="xml"><![CDATA[
|
|
<http>
|
|
<intercept-url pattern='/login.htm*' filters='none'/>
|
|
<intercept-url pattern='/**' access='ROLE_USER' />
|
|
<form-login login-page='/login.htm' default-target-url='/home.htm'
|
|
always-use-default-target='true' />
|
|
</http>
|
|
]]>
|
|
</programlisting></para>
|
|
</section>
|
|
</section>
|
|
</section>
|
|
<section xml:id="ns-auth-providers">
|
|
<title>Using other Authentication Providers</title>
|
|
<para> In practice you will need a more scalable source of user information than a few names
|
|
added to the application context file. Most likely you will want to store your user
|
|
information in something like a database or an LDAP server. LDAP namespace configuration is
|
|
dealt with in the <link xlink:href="#ldap">LDAP chapter</link>, so we won't cover it here.
|
|
If you have a custom implementation of Spring Security's
|
|
<classname>UserDetailsService</classname>, called "myUserDetailsService" in your
|
|
application context, then you can authenticate against this using <programlisting language="xml"><![CDATA[
|
|
<authentication-manager>
|
|
<authentication-provider user-service-ref='myUserDetailsService'/>
|
|
</authentication-manager>
|
|
]]>
|
|
</programlisting> If you want to use a database, then you can use <programlisting language="xml"><![CDATA[
|
|
<authentication-manager>
|
|
<authentication-provider>
|
|
<jdbc-user-service data-source-ref="securityDataSource"/>
|
|
</authentication-provider>
|
|
</authentication-manager>
|
|
]]>
|
|
</programlisting> Where "securityDataSource" is the name of a
|
|
<classname>DataSource</classname> bean in the application context, pointing at a database
|
|
containing the standard Spring Security <link xlink:href="#db_schema_users_authorities">user
|
|
data tables</link>. Alternatively, you could configure a Spring Security
|
|
<classname>JdbcDaoImpl</classname> bean and point at that using the
|
|
<literal>user-service-ref</literal> attribute: <programlisting language="xml"><![CDATA[
|
|
<authentication-manager>
|
|
<authentication-provider user-service-ref='myUserDetailsService'/>
|
|
</authentication-manager>
|
|
|
|
<beans:bean id="myUserDetailsService"
|
|
class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
|
|
<beans:property name="dataSource" ref="dataSource"/>
|
|
</beans:bean>
|
|
]]>
|
|
</programlisting> You can also use standard
|
|
<interfacename>AuthenticationProvider</interfacename> beans as follows <programlisting language="xml"><![CDATA[
|
|
<authentication-manager>
|
|
<authentication-provider ref='myAuthenticationProvider'/>
|
|
</authentication-manager>
|
|
]]>
|
|
</programlisting> where <literal>myAuthenticationProvider</literal> is the name of a
|
|
bean in your application context which implements
|
|
<interfacename>AuthenticationProvider</interfacename>. See <xref linkend="ns-auth-manager"
|
|
/> for more on information on how the Spring Security
|
|
<interfacename>AuthenticationManager</interfacename> is configured using the namespace. </para>
|
|
<section>
|
|
<title>Adding a Password Encoder</title>
|
|
<para> Often your password data will be encoded using a hashing algorithm. This is supported
|
|
by the <literal><password-encoder></literal> element. With SHA encoded passwords,
|
|
the original authentication provider configuration would look like this: <programlisting language="xml"><![CDATA[
|
|
<authentication-manager>
|
|
<authentication-provider>
|
|
<password-encoder hash="sha"/>
|
|
<user-service>
|
|
<user name="jimi" password="d7e6351eaa13189a5a3641bab846c8e8c69ba39f"
|
|
authorities="ROLE_USER, ROLE_ADMIN" />
|
|
<user name="bob" password="4e7421b1b8765d8f9406d87e7cc6aa784c4ab97f"
|
|
authorities="ROLE_USER" />
|
|
</user-service>
|
|
</authentication-provider>
|
|
</authentication-manager>
|
|
]]>
|
|
</programlisting></para>
|
|
<para> When using hashed passwords, it's also a good idea to use a salt value to protect
|
|
against dictionary attacks and Spring Security supports this too. Ideally you would want
|
|
to use a randomly generated salt value for each user, but you can use any property of the
|
|
<classname>UserDetails</classname> object which is loaded by your
|
|
<classname>UserDetailsService</classname>. For example, to use the
|
|
<literal>username</literal> property, you would use <programlisting><![CDATA[
|
|
<password-encoder hash="sha">
|
|
<salt-source user-property="username"/>
|
|
</password-encoder>
|
|
]]></programlisting> You can use a custom password encoder bean by using the
|
|
<literal>ref</literal> attribute of <literal>password-encoder</literal>. This should
|
|
contain the name of a bean in the application context which is an instance of Spring
|
|
Security's <interfacename>PasswordEncoder</interfacename> interface. </para>
|
|
</section>
|
|
</section>
|
|
</section>
|
|
<section xml:id="ns-web-advanced">
|
|
<title>Advanced Web Features</title>
|
|
<section xml:id="ns-remember-me">
|
|
<title>Remember-Me Authentication</title>
|
|
<para>See the separate <link xlink:href="#remember-me">Remember-Me chapter</link> for
|
|
information on remember-me namespace configuration.</para>
|
|
</section>
|
|
<section xml:id="ns-requires-channel">
|
|
<title>Adding HTTP/HTTPS Channel Security</title>
|
|
<para>If your application supports both HTTP and HTTPS, and you require that particular URLs
|
|
can only be accessed over HTTPS, then this is directly supported using the
|
|
<literal>requires-channel</literal> attribute on <literal><intercept-url></literal>: <programlisting language="xml"><![CDATA[
|
|
<http>
|
|
<intercept-url pattern="/secure/**" access="ROLE_USER" requires-channel="https"/>
|
|
<intercept-url pattern="/**" access="ROLE_USER" requires-channel="any"/>
|
|
...
|
|
</http>]]>
|
|
</programlisting> With this configuration in place, if a user attempts to
|
|
access anything matching the "/secure/**" pattern using HTTP, they will first be redirected
|
|
to an HTTPS URL. The available options are "http", "https" or "any". Using the value "any"
|
|
means that either HTTP or HTTPS can be used. </para>
|
|
<para> If your application uses non-standard ports for HTTP and/or HTTPS, you can specify a
|
|
list of port mappings as follows: <programlisting><![CDATA[
|
|
<http>
|
|
...
|
|
<port-mappings>
|
|
<port-mapping http="9080" https="9443"/>
|
|
</port-mappings>
|
|
</http>]]>
|
|
</programlisting> You can find a more in-depth discussion of channel security
|
|
in <xref xlink:href="#channel-security"/>. </para>
|
|
</section>
|
|
<section xml:id="ns-concurrent-session">
|
|
<title>Concurrent Session Control</title>
|
|
<para> If you wish to place constraints on a single user's ability to log in to your
|
|
application, Spring Security supports this out of the box with the following simple
|
|
additions. First you need to add the following listener to your <filename>web.xml</filename>
|
|
file to keep Spring Security updated about session lifecycle events: <programlisting language="xml">
|
|
<![CDATA[
|
|
<listener>
|
|
<listener-class>
|
|
org.springframework.security.web.session.HttpSessionEventPublisher
|
|
</listener-class>
|
|
</listener>
|
|
]]></programlisting> Then add the following line to your application context: <programlisting language="xml"><![CDATA[
|
|
<http>
|
|
...
|
|
<concurrent-session-control max-sessions="1" />
|
|
</http>]]>
|
|
</programlisting> This will prevent a user from logging in multiple times - a
|
|
second login will cause the first to be invalidated. Often you would prefer to prevent a
|
|
second login, in which case you can use <programlisting language="xml"><![CDATA[
|
|
<http>
|
|
...
|
|
<concurrent-session-control max-sessions="1" exception-if-maximum-exceeded="true"/>
|
|
</http>]]>
|
|
</programlisting> The second login will then be rejected.
|
|
<!-- TODO: Link to main section in docs -->
|
|
</para>
|
|
</section>
|
|
<section xml:id="ns-openid">
|
|
<title>OpenID Login</title>
|
|
<para>The namespace supports <link xlink:href="http://openid.net/">OpenID</link> login either
|
|
instead of, or in addition to normal form-based login, with a simple change: <programlisting language="xml"><![CDATA[
|
|
<http>
|
|
<intercept-url pattern="/**" access="ROLE_USER" />
|
|
<openid-login />
|
|
</http>
|
|
]]></programlisting> You should then register yourself with an OpenID provider (such as
|
|
myopenid.com), and add the user information to your in-memory
|
|
<literal><user-service></literal>: <programlisting><![CDATA[
|
|
<user name="http://jimi.hendrix.myopenid.com/" password="notused"
|
|
authorities="ROLE_USER" />
|
|
]]></programlisting> You should be able to login using the <literal>myopenid.com</literal> site to
|
|
authenticate. </para>
|
|
</section>
|
|
<section xml:id="ns-custom-filters">
|
|
<title>Adding in Your Own Filters</title>
|
|
<para>If you've used Spring Security before, you'll know that the framework maintains a chain
|
|
of filters in order to apply its services. You may want to add your own filters to the stack
|
|
at particular locations or use a Spring Security filter for which there isn't currently a
|
|
namespace configuration option (CAS, for example). Or you might want to use a customized
|
|
version of a standard namespace filter, such as the
|
|
<literal>UsernamePasswordAuthenticationProcessingFilter</literal> which is created by the
|
|
<literal><form-login></literal> element, taking advantage of some of the extra
|
|
configuration options which are available by using the bean explicitly. How can you do this
|
|
with namespace configuration, since the filter chain is not directly exposed? </para>
|
|
<para>The order of the filters is always strictly enforced when using the namespace. When the
|
|
application context is being created, the filter beans are sorted by the namespace handling
|
|
code and the standard Spring Security filters each have an alias in the namespace and a
|
|
well-known position.<note>
|
|
<para>In previous versions, the sorting took place after the filter instances had been
|
|
created, during post-processing of the application context. In version 3.0+ the sorting
|
|
is now done at the bean metadata level, before the classes have been instantiated. This
|
|
has implications for how you add your own filters to the stack as the entire filter list
|
|
must be known during the parsing of the <literal><http></literal> element, so the
|
|
syntax has changed slightly in 3.0.</para>
|
|
</note>The filters, aliases and namespace elements/attributes which create the filters are
|
|
shown in <xref linkend="filter-stack"/>. The filters are listed in the order in which they
|
|
occur in the filter chain. <table xml:id="filter-stack">
|
|
<title>Standard Filter Aliases and Ordering</title>
|
|
<tgroup cols="3" align="left">
|
|
<thead>
|
|
<row>
|
|
<entry align="center">Alias</entry>
|
|
<entry align="center">Filter Class</entry>
|
|
<entry align="center">Namespace Element or Attribute</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry> CHANNEL_FILTER</entry>
|
|
<entry><literal>ChannelProcessingFilter</literal></entry>
|
|
<entry><literal>http/intercept-url</literal></entry>
|
|
</row>
|
|
<row>
|
|
<entry> CONCURRENT_SESSION_FILTER</entry>
|
|
<entry><literal>ConcurrentSessionFilter</literal>
|
|
</entry>
|
|
<entry><literal>http/concurrent-session-control</literal></entry>
|
|
</row>
|
|
<row>
|
|
<entry> SESSION_CONTEXT_INTEGRATION_FILTER</entry>
|
|
<entry><classname>HttpSessionContextIntegrationFilter</classname></entry>
|
|
<entry><literal>http</literal></entry>
|
|
</row>
|
|
<row>
|
|
<entry> LOGOUT_FILTER </entry>
|
|
<entry><literal>LogoutFilter</literal></entry>
|
|
<entry><literal>http/logout</literal></entry>
|
|
</row>
|
|
<row>
|
|
<entry> X509_FILTER </entry>
|
|
<entry><literal>X509PreAuthenticatedProcessigFilter</literal></entry>
|
|
<entry><literal>http/x509</literal></entry>
|
|
</row>
|
|
<row>
|
|
<entry> PRE_AUTH_FILTER </entry>
|
|
<entry><literal>AstractPreAuthenticatedProcessingFilter</literal> Subclasses</entry>
|
|
<entry>N/A</entry>
|
|
</row>
|
|
<row>
|
|
<entry> CAS_PROCESSING_FILTER </entry>
|
|
<entry><literal>CasProcessingFilter</literal></entry>
|
|
<entry>N/A</entry>
|
|
</row>
|
|
<row>
|
|
<entry> AUTHENTICATION_PROCESSING_FILTER </entry>
|
|
<entry><literal>UsernamePasswordAuthenticationProcessingFilter</literal></entry>
|
|
<entry><literal>http/form-login</literal></entry>
|
|
</row>
|
|
<row>
|
|
<entry> BASIC_PROCESSING_FILTER </entry>
|
|
<entry><literal>BasicProcessingFilter</literal></entry>
|
|
<entry><literal>http/http-basic</literal></entry>
|
|
</row>
|
|
<row>
|
|
<entry> SERVLET_API_SUPPORT_FILTER</entry>
|
|
<entry><literal>SecurityContextHolderAwareRequestFilter</literal></entry>
|
|
<entry><literal>http/@servlet-api-provision</literal></entry>
|
|
</row>
|
|
<row>
|
|
<entry> REMEMBER_ME_FILTER </entry>
|
|
<entry><classname>RememberMeProcessingFilter</classname></entry>
|
|
<entry><literal>http/remember-me</literal></entry>
|
|
</row>
|
|
<row>
|
|
<entry> ANONYMOUS_FILTER </entry>
|
|
<entry><literal>AnonymousProcessingFilter</literal></entry>
|
|
<entry><literal>http/anonymous</literal></entry>
|
|
</row>
|
|
<row>
|
|
<entry> EXCEPTION_TRANSLATION_FILTER </entry>
|
|
<entry><classname>ExceptionTranslationFilter</classname></entry>
|
|
<entry><literal>http</literal></entry>
|
|
</row>
|
|
<row>
|
|
<entry> NTLM_FILTER </entry>
|
|
<entry><literal>NtlmProcessingFilter</literal></entry>
|
|
<entry>N/A</entry>
|
|
</row>
|
|
<row>
|
|
<entry> FILTER_SECURITY_INTERCEPTOR </entry>
|
|
<entry><classname>FilterSecurityInterceptor</classname></entry>
|
|
<entry><literal>http</literal></entry>
|
|
</row>
|
|
<row>
|
|
<entry> SWITCH_USER_FILTER </entry>
|
|
<entry><literal>SwitchUserProcessingFilter</literal></entry>
|
|
<entry>N/A</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table> You can add your own filter to the stack, using the
|
|
<literal>custom-filter</literal> element and one of these names to specify the position
|
|
your filter should appear at: <programlisting language="xml"><![CDATA[
|
|
<http>
|
|
<custom-filter position="AUTHENTICATION_PROCESSING_FILTER" ref="myFilter" />
|
|
</http>
|
|
|
|
<beans:bean id="myFilter" class="com.mycompany.MySpecialAuthenticationFilter"/>
|
|
]]>
|
|
</programlisting> You can also use the <literal>after</literal> or <literal>before</literal>
|
|
attributes if you want your filter to be inserted before or after another filter in the
|
|
stack. The names "FIRST" and "LAST" can be used with the <literal>position</literal>
|
|
attribute to indicate that you want your filter to appear before or after the entire stack,
|
|
respectively. </para>
|
|
<tip>
|
|
<title>Avoiding filter position conflicts</title>
|
|
<para> If you are inserting a custom filter which may occupy the same position as one of the
|
|
standard filters created by the namespace then it's important that you don't include the
|
|
namespace versions by mistake. Avoid using the <literal>auto-config</literal> attribute
|
|
and remove any elements which create filters whose functionality you want to replace. </para>
|
|
<para> Note that you can't replace filters which are created by the use of the
|
|
<literal><http></literal> element itself -
|
|
<classname>HttpSessionContextIntegrationFilter</classname>,
|
|
<classname>ExceptionTranslationFilter</classname> or
|
|
<classname>FilterSecurityInterceptor</classname>. </para>
|
|
</tip>
|
|
<para> If you're replacing a namespace filter which requires an authentication entry point
|
|
(i.e. where the authentication process is triggered by an attempt by an unauthenticated user
|
|
to access to a secured resource), you will need to add a custom entry point bean too. </para>
|
|
<section xml:id="ns-entry-point-ref">
|
|
<title>Setting a Custom <interfacename>AuthenticationEntryPoint</interfacename></title>
|
|
<para> If you aren't using form login, OpenID or basic authentication through the namespace,
|
|
you may want to define an authentication filter and entry point using a traditional bean
|
|
syntax and link them into the namespace, as we've just seen. The corresponding
|
|
<interfacename>AuthenticationEntryPoint</interfacename> can be set using the
|
|
<literal>entry-point-ref</literal> attribute on the <literal><http></literal>
|
|
element. </para>
|
|
<para> The CAS sample application is a good example of the use of custom beans with the
|
|
namespace, including this syntax. If you aren't familiar with authentication entry points,
|
|
they are discussed in the <link xlink:href="#tech-auth-entry-point">technical
|
|
overview</link> chapter. </para>
|
|
</section>
|
|
</section>
|
|
<section xml:id="ns-session-fixation">
|
|
<title>Session Fixation Attack Protection</title>
|
|
<para>
|
|
<link xlink:href="http://en.wikipedia.org/wiki/Session_fixation">Session fixation</link>
|
|
attacks are a potential risk where it is possible for a malicious attacker to create a
|
|
session by accessing a site, then persuade another user to log in with the same session (by
|
|
sending them a link containing the session identifier as a parameter, for example). Spring
|
|
Security protects against this automatically by creating a new session when a user logs in.
|
|
If you don't require this protection, or it conflicts with some other requirement, you can
|
|
control the behaviour using the <literal>session-fixation-protection</literal> attribute on
|
|
<literal><http></literal>, which has three options <itemizedlist>
|
|
<listitem>
|
|
<para><literal>migrateSession</literal> - creates a new session and copies the existing
|
|
session attributes to the new session. This is the default.</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><literal>none</literal> - Don't do anything. The original session will be
|
|
retained.</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><literal>newSession</literal> - Create a new "clean" session, without copying the
|
|
existing session data.</para>
|
|
</listitem>
|
|
</itemizedlist></para>
|
|
</section>
|
|
</section>
|
|
<section xml:id="ns-method-security">
|
|
<title>Method Security</title>
|
|
<para>From version 2.0 onwards Spring Security has improved support substantially for adding
|
|
security to your service layer methods. It provides support for JSR-250 security as well as
|
|
the framework's native <literal>@Secured</literal> annotation. You can apply security to a
|
|
single bean, using the <literal>intercept-methods</literal> element to decorate the bean
|
|
declaration, or you can secure multiple beans across the entire service layer using the
|
|
AspectJ style pointcuts. </para>
|
|
<section xml:id="ns-global-method">
|
|
<title>The <literal><global-method-security></literal> Element</title>
|
|
<para> This element is used to enable annotation-based security in your application (by
|
|
setting the appropriate attributes on the element), and also to group together security
|
|
pointcut declarations which will be applied across your entire application context. You
|
|
should only declare one <literal><global-method-security></literal> element. The
|
|
following declaration would enable support for both Spring Security's
|
|
<literal>@Secured</literal>, and JSR-250 annotations: <programlisting><![CDATA[
|
|
<global-method-security secured-annotations="enabled" jsr250-annotations="enabled"/>
|
|
]]>
|
|
</programlisting> Adding an annotation to a method (on an class or interface) would then limit
|
|
the access to that method accordingly. Spring Security's native annotation support defines a
|
|
set of attributes for the method. These will be passed to the
|
|
<interfacename>AccessDecisionManager</interfacename> for it to make the actual decision.
|
|
This example is taken from the <link xlink:href="#tutorial-sample">tutorial sample</link>,
|
|
which is a good starting point if you want to use method security in your application:
|
|
<programlisting language="java">
|
|
public interface BankService {
|
|
|
|
@Secured("IS_AUTHENTICATED_ANONYMOUSLY")
|
|
public Account readAccount(Long id);
|
|
|
|
@Secured("IS_AUTHENTICATED_ANONYMOUSLY")
|
|
public Account[] findAccounts();
|
|
|
|
@Secured("ROLE_TELLER")
|
|
public Account post(Account account, double amount);
|
|
}
|
|
</programlisting></para>
|
|
<section xml:id="ns-protect-pointcut">
|
|
<title>Adding Security Pointcuts using <literal>protect-pointcut</literal></title>
|
|
<para> The use of <literal>protect-pointcut</literal> is particularly powerful, as it allows
|
|
you to apply security to many beans with only a simple declaration. Consider the following
|
|
example: <programlisting language="xml"><![CDATA[
|
|
<global-method-security>
|
|
<protect-pointcut expression="execution(* com.mycompany.*Service.*(..))"
|
|
access="ROLE_USER"/>
|
|
</global-method-security>
|
|
]]>
|
|
</programlisting> This will protect all methods on beans declared in the application
|
|
context whose classes are in the <literal>com.mycompany</literal> package and whose class
|
|
names end in "Service". Only users with the <literal>ROLE_USER</literal> role will be able
|
|
to invoke these methods. As with URL matching, the most specific matches must come first
|
|
in the list of pointcuts, as the first matching expression will be used. </para>
|
|
</section>
|
|
</section>
|
|
</section>
|
|
<section xml:id="ns-access-manager">
|
|
<title>The Default AccessDecisionManager</title>
|
|
<para> This section assumes you have some knowledge of the underlying architecture for
|
|
access-control within Spring Security. If you don't you can skip it and come back to it later,
|
|
as this section is only really relevant for people who need to do some customization in order
|
|
to use more than simple role based security. </para>
|
|
<para> When you use a namespace configuration, a default instance of
|
|
<interfacename>AccessDecisionManager</interfacename> is automatically registered for you and
|
|
will be used for making access decisions for method invocations and web URL access, based on
|
|
the access attributes you specify in your <literal>intercept-url</literal> and
|
|
<literal>protect-pointcut</literal> declarations (and in annotations if you are using
|
|
annotation secured methods). </para>
|
|
<para> The default strategy is to use an <classname>AffirmativeBased</classname>
|
|
<interfacename>AccessDecisionManager</interfacename> with a <classname>RoleVoter</classname>
|
|
and an <classname>AuthenticatedVoter</classname>. </para>
|
|
<section xml:id="ns-custom-access-mgr">
|
|
<title>Customizing the AccessDecisionManager</title>
|
|
<para> If you need to use a more complicated access control strategy then it is easy to set an
|
|
alternative for both method and web security. </para>
|
|
<para> For method security, you do this by setting the
|
|
<literal>access-decision-manager-ref</literal> attribute on
|
|
<literal>global-method-security</literal>to the Id of the appropriate
|
|
<interfacename>AccessDecisionManager</interfacename> bean in the application context: <programlisting language="xml"><![CDATA[
|
|
<global-method-security access-decision-manager-ref="myAccessDecisionManagerBean">
|
|
...
|
|
</global-method-security>
|
|
]]></programlisting></para>
|
|
<para> The syntax for web security is the same, but on the <literal>http</literal> element: <programlisting><![CDATA[
|
|
<http access-decision-manager-ref="myAccessDecisionManagerBean">
|
|
...
|
|
</http>
|
|
]]></programlisting></para>
|
|
</section>
|
|
</section>
|
|
<section xml:id="ns-auth-manager">
|
|
<title>The Authentication Manager and the Namespace</title>
|
|
<para> The main interface which provides authentication services in Spring Security is the
|
|
<interfacename>AuthenticationManager</interfacename>. This is usually an instance of Spring
|
|
Security's <classname>ProviderManager</classname> class, which you may already be familiar
|
|
with if you've used the framework before. If not, it will be covered later, in <link
|
|
xlink:href="#tech-intro-authentication"/>. The bean instance is registered using the
|
|
<literal>authentication-manager</literal> namespace element. 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
|
|
with the <classname>ProviderManager</classname> and you can do this using the
|
|
<literal><authentication-provider></literal> element with the <literal>ref</literal>
|
|
attribute, where the value of the attribute is the name of the provider bean you want to add.
|
|
For example: <programlisting language="xml"><![CDATA[
|
|
<authentication-manager>
|
|
<authentication-provider ref="casAuthenticationProvider"/>
|
|
</authentication-manager>
|
|
<bean id="casAuthenticationProvider"
|
|
class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
|
|
<security:custom-authentication-provider />
|
|
...
|
|
</bean>
|
|
]]></programlisting></para>
|
|
<para> Another common requirement is that another bean in the context may require a reference to
|
|
the <interfacename>AuthenticationManager</interfacename>. There is a special element which
|
|
lets you register an alias for the <interfacename>AuthenticationManager</interfacename> and
|
|
you can then use this name elsewhere in your application context. <programlisting language="xml"><![CDATA[
|
|
<security:authentication-manager alias="authenticationManager">
|
|
...
|
|
</security:authentication-manager>
|
|
|
|
<bean id="customizedFormLoginFilter"
|
|
class="com.somecompany.security.web.CustomFormLoginFilter">
|
|
<property name="authenticationManager" ref="authenticationManager"/>
|
|
...
|
|
</bean>
|
|
]]></programlisting></para>
|
|
</section>
|
|
</chapter>
|