2008-04-08 15:40:56 +00:00
|
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
|
|
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="namespace-config" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
|
|
<info>
|
|
|
|
<title>Security Namespace Configuration</title>
|
|
|
|
</info>
|
|
|
|
<section>
|
2008-04-11 17:18:02 +00:00
|
|
|
<title>Introduction</title>
|
2008-04-08 15:40:56 +00:00
|
|
|
<para>
|
2008-04-09 18:02:34 +00:00
|
|
|
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
|
2008-04-08 15:40:56 +00:00
|
|
|
<link xlink:href="http://static.springframework.org/spring/docs/2.5.x/reference/xsd-config.html">
|
2008-04-09 18:02:34 +00:00
|
|
|
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
|
2008-04-08 15:40:56 +00:00
|
|
|
configuration syntax which more closely matches the problem domain and hides the underlying
|
2008-04-08 20:51:30 +00:00
|
|
|
complexity from the user. A simple element may conceal the fact that multiple beans and
|
2008-04-08 15:40:56 +00:00
|
|
|
processing steps are being added to the application context. For example, adding the following
|
2008-04-08 20:51:30 +00:00
|
|
|
element from the security namespace to an application context will start up an embedded LDAP
|
2008-04-08 15:40:56 +00:00
|
|
|
server for testing use within the application:
|
|
|
|
<programlisting><![CDATA[
|
2008-04-08 20:51:30 +00:00
|
|
|
<security:ldap-server />
|
2008-04-08 15:40:56 +00:00
|
|
|
]]></programlisting>
|
2008-04-08 20:51:30 +00:00
|
|
|
This is much simpler than wiring up the equivalent Apache Directory Server beans. The most
|
2008-04-09 23:35:29 +00:00
|
|
|
common alternative configuration requirements are supported by attributes on the
|
2008-04-09 18:02:34 +00:00
|
|
|
<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.
|
2008-04-08 15:40:56 +00:00
|
|
|
<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>
|
2008-04-09 18:02:34 +00:00
|
|
|
</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
|
2008-04-08 20:51:30 +00:00
|
|
|
<link xlink:href="http://www.springsource.com/products/sts">SpringSource Tool Suite</link>
|
2008-04-09 18:02:34 +00:00
|
|
|
as it has special features for working with the Spring portfolio namespaces.
|
2008-04-08 15:40:56 +00:00
|
|
|
</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:
|
2008-04-09 18:02:34 +00:00
|
|
|
<programlisting>
|
2008-04-08 15:40:56 +00:00
|
|
|
<![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-2.0.xsd
|
|
|
|
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd">
|
|
|
|
...
|
|
|
|
</beans>
|
|
|
|
]]></programlisting>
|
2008-04-09 18:02:34 +00:00
|
|
|
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
|
2008-04-08 15:40:56 +00:00
|
|
|
start like this
|
|
|
|
<programlisting><![CDATA[
|
|
|
|
<beans:beans xmlns="http://www.springframework.org/schema/security"
|
|
|
|
xmlns:beans="http://www.springframework.org/schema/beans">
|
|
|
|
...
|
|
|
|
</beans:beans>
|
|
|
|
]]></programlisting>
|
2008-04-09 11:27:55 +00:00
|
|
|
We'll assume this syntax is being used from now on in this chapter.
|
2008-04-08 15:40:56 +00:00
|
|
|
</para>
|
2008-04-08 20:51:30 +00:00
|
|
|
<section>
|
2008-04-09 18:02:34 +00:00
|
|
|
<title>Design of the Namespace</title>
|
2008-04-08 20:51:30 +00:00
|
|
|
<para>
|
2008-04-09 18:02:34 +00:00
|
|
|
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 largely
|
|
|
|
based around the large-scale dependencies within the framework, and can be divided up into
|
|
|
|
the following areas:
|
2008-04-08 20:51:30 +00:00
|
|
|
<itemizedlist>
|
2008-04-09 18:02:34 +00:00
|
|
|
<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>
|
2008-04-08 20:51:30 +00:00
|
|
|
<!-- todo: diagram and link to other sections which describe the interfaces -->
|
2008-04-09 18:02:34 +00:00
|
|
|
</itemizedlist>
|
2008-04-08 20:51:30 +00:00
|
|
|
</para>
|
2008-04-11 17:18:02 +00:00
|
|
|
<para>We'll see how these work together in the following sections.</para>
|
2008-04-08 20:51:30 +00:00
|
|
|
</section>
|
2008-04-08 15:40:56 +00:00
|
|
|
</section>
|
2008-04-11 17:18:02 +00:00
|
|
|
<section xml:id="ns-getting-started">
|
|
|
|
<title>Getting Started with Security Namespace Cofiguration</title>
|
2008-04-09 11:27:55 +00:00
|
|
|
<para>
|
2008-04-11 17:18:02 +00:00
|
|
|
In this section, we'll look at how you can build up a namespace configuration to use some of the main
|
2008-04-09 18:02:34 +00:00
|
|
|
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
|
2008-04-11 17:18:02 +00:00
|
|
|
test logins. The 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>
|
2008-04-09 18:02:34 +00:00
|
|
|
<para>
|
2008-04-09 23:35:29 +00:00
|
|
|
The first thing you need to do is add the following filter declaration to your
|
2008-04-09 18:02:34 +00:00
|
|
|
<literal>web.xml</literal>
|
2008-04-09 11:27:55 +00:00
|
|
|
file:
|
2008-04-09 18:02:34 +00:00
|
|
|
<programlisting>
|
|
|
|
<![CDATA[
|
2008-04-09 11:27:55 +00:00
|
|
|
<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>]]>
|
2008-04-09 18:02:34 +00:00
|
|
|
</programlisting>
|
2008-04-10 14:38:41 +00:00
|
|
|
This provides a hook into the Spring Security web infrastructure. <!-- You can find more details
|
2008-04-09 18:02:34 +00:00
|
|
|
of how this works in
|
2008-04-10 14:38:41 +00:00
|
|
|
<link xlink:href="#todo">TODO</link>-->. You're then ready to start editing your application
|
2008-04-09 18:02:34 +00:00
|
|
|
context file. Web security services are configured using the <literal><http></literal>
|
|
|
|
element.
|
|
|
|
</para>
|
|
|
|
</section>
|
|
|
|
|
2008-04-11 17:18:02 +00:00
|
|
|
<section xml:id="ns-minimal">
|
|
|
|
<title>A Minimal <literal><http></literal>Configuration</title>
|
2008-04-09 18:02:34 +00:00
|
|
|
<para>
|
|
|
|
All you need to enable web security to begin with is
|
|
|
|
<programlisting><![CDATA[
|
2008-04-09 11:27:55 +00:00
|
|
|
<http auto-config='true'>
|
|
|
|
<intercept-url pattern="/**" access="ROLE_USER" />
|
|
|
|
</http>
|
|
|
|
]]>
|
|
|
|
</programlisting>
|
2008-04-09 18:02:34 +00:00
|
|
|
Which says that we want all URLs within our application to be secured, requiring the role
|
2008-04-12 16:51:10 +00:00
|
|
|
<literal>ROLE_USER</literal> to access them.</para>
|
|
|
|
<note><para>You can use multiple <literal><intercept-url></literal> elements to define
|
2008-04-12 13:33:09 +00:00
|
|
|
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>
|
2008-04-12 16:51:10 +00:00
|
|
|
<para>
|
2008-04-12 13:33:09 +00:00
|
|
|
To add some users, you can define a set of test data directly in the
|
2008-04-09 18:02:34 +00:00
|
|
|
namespace:
|
|
|
|
<programlisting><![CDATA[
|
2008-04-09 11:27:55 +00:00
|
|
|
<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>
|
|
|
|
]]>
|
|
|
|
</programlisting>
|
2008-04-09 18:02:34 +00:00
|
|
|
This defines two users, their passwords and their roles within the application (which will
|
2008-04-12 16:51:10 +00:00
|
|
|
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>.
|
2008-04-11 23:25:13 +00:00
|
|
|
The <literal><authentication-provider></literal>
|
|
|
|
element specifies that the user information will be registered with the authentication
|
|
|
|
manager and used to process authentication requests.
|
2008-04-09 18:02:34 +00:00
|
|
|
</para>
|
2008-04-12 16:51:10 +00:00
|
|
|
<sidebar>
|
|
|
|
<para>If you are familiar with previous 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>. A <literal>ProviderManager</literal>
|
|
|
|
bean is always created by the namespace processing system and the
|
|
|
|
<classname>AuthenticationProvider</classname>
|
|
|
|
is automatically registered with it.</para>
|
|
|
|
</sidebar>
|
2008-04-09 18:02:34 +00:00
|
|
|
<para>
|
|
|
|
At this point you should be able to start up your application and you will be required to
|
2008-04-09 23:35:29 +00:00
|
|
|
log in to proceed. Try it out, or try experimenting with the "tutorial" sample application
|
2008-04-09 18:02:34 +00:00
|
|
|
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 login processing and "remember-me" services are automatically
|
2008-04-11 17:18:02 +00:00
|
|
|
enabled.
|
2008-04-09 18:02:34 +00:00
|
|
|
</para>
|
2008-04-11 17:18:02 +00:00
|
|
|
<section xml:id="ns-auto-config">
|
2008-04-09 18:02:34 +00:00
|
|
|
<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><![CDATA[
|
|
|
|
<http>
|
|
|
|
<intercept-url pattern="/**" access="ROLE_USER" />
|
|
|
|
<form-login />
|
|
|
|
<anonymous />
|
|
|
|
<http-basic />
|
|
|
|
<logout />
|
|
|
|
<remember-me />
|
|
|
|
</http>
|
|
|
|
]]>
|
|
|
|
</programlisting>
|
2008-04-11 17:18:02 +00:00
|
|
|
These other elements are responsible for setting up form-login,
|
2008-04-09 18:02:34 +00:00
|
|
|
<link xlink:href="#anonymous">anonymous authentication</link>, basic authentication, logout handling and remember-me services
|
2008-04-11 17:18:02 +00:00
|
|
|
respectively. 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 ad 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><![CDATA[
|
2008-04-09 18:02:34 +00:00
|
|
|
<http auto-config='true'>
|
2008-04-09 23:35:29 +00:00
|
|
|
<intercept-url pattern="/login.jsp*" filters="none"/>
|
2008-04-09 18:02:34 +00:00
|
|
|
<intercept-url pattern="/**" access="ROLE_USER" />
|
|
|
|
<form-login login-page='/login.jsp'/>
|
|
|
|
</http>
|
|
|
|
]]>
|
2008-04-11 17:18:02 +00:00
|
|
|
</programlisting>
|
|
|
|
Note that you can 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><![CDATA[
|
2008-04-09 18:02:34 +00:00
|
|
|
<http auto-config='true'>
|
|
|
|
<intercept-url pattern="/**" access="ROLE_USER" />
|
|
|
|
<http-basic />
|
|
|
|
</http>
|
|
|
|
]]>
|
2008-04-11 17:18:02 +00:00
|
|
|
</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>
|
2008-04-09 23:35:29 +00:00
|
|
|
</section>
|
2008-04-11 17:18:02 +00:00
|
|
|
<section xml:id="ns-auth-providers">
|
|
|
|
<title>Using other Authentication Providers</title>
|
2008-04-09 23:35:29 +00:00
|
|
|
<para>
|
2008-04-11 17:18:02 +00:00
|
|
|
In practice you will need a more scalable source of user information than a few names added to the application context file.
|
2008-04-09 23:35:29 +00:00
|
|
|
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><![CDATA[
|
2008-04-09 18:02:34 +00:00
|
|
|
<authentication-provider user-service-ref='myUserDetailsService'/>
|
|
|
|
]]>
|
2008-04-09 23:35:29 +00:00
|
|
|
</programlisting>
|
|
|
|
If you want to use a database, then you can use
|
|
|
|
<programlisting><![CDATA[
|
2008-04-09 18:02:34 +00:00
|
|
|
<authentication-provider>
|
|
|
|
<jdbc-user-service data-source-ref="securityDataSource"/>
|
|
|
|
</authentication-provider>
|
|
|
|
]]>
|
2008-04-09 23:35:29 +00:00
|
|
|
</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 user data tables. Alternatively, you could configure
|
|
|
|
a Spring Security <classname>JdbcDaoImpl</classname> bean and point at that using the <literal>user-service-ref</literal>
|
|
|
|
attribute.
|
|
|
|
</para>
|
|
|
|
<section><title>Adding a Password Encoder</title>
|
2008-04-09 18:02:34 +00:00
|
|
|
<para>
|
2008-04-09 23:35:29 +00:00
|
|
|
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:
|
2008-04-09 18:02:34 +00:00
|
|
|
<programlisting><![CDATA[
|
2008-04-10 14:38:41 +00:00
|
|
|
<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>
|
2008-04-09 18:02:34 +00:00
|
|
|
]]>
|
|
|
|
</programlisting>
|
|
|
|
</para>
|
2008-04-09 23:35:29 +00:00
|
|
|
<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[
|
2008-04-10 14:38:41 +00:00
|
|
|
<password-encoder hash="sha">
|
|
|
|
<salt-source user-property="username"/>
|
|
|
|
</password-encoder>
|
2008-04-09 18:02:34 +00:00
|
|
|
]]></programlisting>
|
2008-04-09 23:35:29 +00:00
|
|
|
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>
|
2008-04-09 18:02:34 +00:00
|
|
|
</section>
|
2008-04-09 11:27:55 +00:00
|
|
|
</section>
|
2008-04-11 17:18:02 +00:00
|
|
|
</section>
|
|
|
|
<section xml:id="ns-web-advanced">
|
|
|
|
<title>Advanced Web Features</title>
|
|
|
|
|
|
|
|
<section xml:id="ns-requires-channel">
|
2008-04-10 14:38:41 +00:00
|
|
|
<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>:
|
2008-04-11 17:18:02 +00:00
|
|
|
<programlisting><![CDATA[
|
|
|
|
<http>
|
|
|
|
<intercept-url pattern="/secure/**" access="ROLE_USER" requires-channel="https"/>
|
|
|
|
<intercept-url pattern="/**" access="ROLE_USER" requires-channel="any"/>
|
|
|
|
...
|
|
|
|
</http>]]>
|
|
|
|
</programlisting>
|
2008-04-10 14:38:41 +00:00
|
|
|
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:
|
2008-04-11 17:18:02 +00:00
|
|
|
<programlisting>
|
|
|
|
<![CDATA[
|
|
|
|
<http>
|
|
|
|
...
|
|
|
|
<port-mappings>
|
|
|
|
<port-mapping http="9080" https="9443"/>
|
|
|
|
</port-mappings>
|
|
|
|
</http>]]>
|
|
|
|
</programlisting>
|
2008-04-10 14:38:41 +00:00
|
|
|
You can find a more in-depth discussion of channel security in <xref xlink:href="#channel-security"/>.
|
|
|
|
</para>
|
|
|
|
</section>
|
2008-04-11 17:18:02 +00:00
|
|
|
|
|
|
|
<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,
|
2008-04-12 15:13:22 +00:00
|
|
|
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>
|
|
|
|
<![CDATA[
|
|
|
|
<listener>
|
|
|
|
<listener-class>org.springframework.security.ui.session.HttpSessionEventPublisher</listener-class>
|
|
|
|
</listener>
|
|
|
|
]]></programlisting>
|
|
|
|
Then add the following line to your application context:
|
2008-04-11 17:18:02 +00:00
|
|
|
<programlisting><![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><![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 eiter instead of, or in addition to
|
|
|
|
normal form-based login, with a simple change:
|
|
|
|
<programlisting><![CDATA[
|
|
|
|
<http auto-config='true'>
|
|
|
|
<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 customized version of an existing filter. How can you do this with
|
|
|
|
namespace configuration, since the filter chain is not directly exposed?
|
|
|
|
</para>
|
|
|
|
<para>The order of the filters is always strictly enforced when using the namespace. Each Spring Security
|
|
|
|
filter implements the Spring <interfacename>Ordered</interfacename> interface and the filters are sorted
|
|
|
|
during initialization. The standard filters each have an alias in the namespace:
|
|
|
|
<table>
|
|
|
|
<title>Standard Filter Aliases and Ordering</title>
|
2008-04-12 13:33:09 +00:00
|
|
|
<tgroup cols="2" align="left">
|
2008-04-11 17:18:02 +00:00
|
|
|
<thead><row>
|
2008-04-12 13:33:09 +00:00
|
|
|
<entry align="center">Alias</entry><entry align="center">Filter Class</entry>
|
2008-04-11 17:18:02 +00:00
|
|
|
</row></thead>
|
|
|
|
<tbody>
|
|
|
|
<row><entry> CHANNEL_FILTER</entry><entry>ChannelProcessingFilter</entry></row>
|
|
|
|
<row><entry> CONCURRENT_SESSION_FILTER</entry><entry>ConcurrentSessionFilter</entry></row>
|
|
|
|
<row><entry> SESSION_CONTEXT_INTEGRATION_FILTER</entry><entry>HttpSessionContextIntegrationFilter</entry></row>
|
|
|
|
<row><entry> LOGOUT_FILTER </entry><entry>LogoutFilter</entry></row>
|
|
|
|
<row><entry> X509_FILTER </entry><entry>X509PreAuthenticatedProcessigFilter</entry></row>
|
|
|
|
<row><entry> PRE_AUTH_FILTER </entry><entry>Subclass of AstractPreAuthenticatedProcessingFilter</entry></row>
|
|
|
|
<row><entry> CAS_PROCESSING_FILTER </entry><entry>CasProcessingFilter</entry></row>
|
|
|
|
<row><entry> AUTHENTICATION_PROCESSING_FILTER </entry><entry>AuthenticationProcessingFilter</entry></row>
|
|
|
|
<row><entry> BASIC_PROCESSING_FILTER </entry><entry>BasicProcessingFilter</entry></row>
|
|
|
|
<row><entry> SERVLET_API_SUPPORT_FILTER</entry><entry>classname</entry></row>
|
|
|
|
<row><entry> REMEMBER_ME_FILTER </entry><entry>RememberMeProcessingFilter</entry></row>
|
|
|
|
<row><entry> ANONYMOUS_FILTER </entry><entry>AnonymousProcessingFilter</entry></row>
|
|
|
|
<row><entry> EXCEPTION_TRANSLATION_FILTER </entry><entry>ExceptionTranslationFilter</entry></row>
|
|
|
|
<row><entry> NTLM_FILTER </entry><entry>NtlmProcessingFilter</entry></row>
|
|
|
|
<row><entry> FILTER_SECURITY_INTERCEPTOR </entry><entry>FilterSecurityInterceptor</entry></row>
|
|
|
|
<row><entry> SWITCH_USER_FILTER </entry><entry>SwitchUserProcessingFilter</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><![CDATA[
|
|
|
|
<beans:bean id="myFilter" class="com.mycompany.MySpecialAuthenticationFilter">
|
|
|
|
<custom-filter position="AUTHENTICATION_PROCESSING_FILTER"/>
|
|
|
|
</beans:bean>
|
|
|
|
]]></programlisting>
|
|
|
|
You can also use the <literal>after</literal> or <literal>before</literal> attribtues if you want your filter
|
|
|
|
to be inserted before or after another filter in the stack. The names "FIRST" and "LAST" can be used to indicate
|
|
|
|
that you want your filter to appear before or after the entire stack, respectively.
|
|
|
|
</para>
|
|
|
|
</section>
|
2008-04-12 16:51:10 +00:00
|
|
|
|
|
|
|
<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>
|
|
|
|
|
2008-04-09 11:27:55 +00:00
|
|
|
</section>
|
2008-04-11 17:18:02 +00:00
|
|
|
|
|
|
|
<section xml:id="ns-method-security">
|
2008-04-12 13:33:09 +00:00
|
|
|
<title>Method Security</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Spring Security 2.0 has improved support substantially for adding security to your service layer methods. If you are
|
|
|
|
using Java 5 or greater, then support for JSR-250 security annotations is provided, 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>
|
2008-04-11 17:18:02 +00:00
|
|
|
|
2008-04-12 13:33:09 +00:00
|
|
|
<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 types of annotations:
|
|
|
|
<programlisting><![CDATA[
|
|
|
|
<global-method-security secured-annotations="enabled" jsr250-annotations="true"/>
|
|
|
|
]]>
|
|
|
|
</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><![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 xml:id="ns-global-method-access-mgr">
|
|
|
|
<title>Customizing the AccessDecisionManager</title>
|
|
|
|
<para>
|
|
|
|
The default namespace-registered AccessDecisionManager will be used automatically to
|
|
|
|
control method access. For more complex requirements you can specify another instance
|
|
|
|
using the <literal>access-decision-manager-ref</literal> attribute:
|
|
|
|
|
|
|
|
<programlisting><![CDATA[
|
|
|
|
<global-method-security access-decision-manager-ref="myAccessDecisionManagerBean">
|
|
|
|
...
|
|
|
|
</global-method-security>
|
|
|
|
]]></programlisting>
|
|
|
|
</para>
|
|
|
|
</section>
|
|
|
|
</section>
|
|
|
|
|
2008-04-11 17:18:02 +00:00
|
|
|
</section>
|
|
|
|
|
2008-04-08 15:40:56 +00:00
|
|
|
</chapter>
|