SEC-653: More added to namespace chapter

This commit is contained in:
Luke Taylor 2008-04-09 18:02:34 +00:00
parent 78f22f777c
commit 538e295c91
3 changed files with 222 additions and 70 deletions

View File

@ -167,7 +167,7 @@
</itemizedlist>
So if we used the following configuration
<programlisting><![CDATA[
<ldap-authentication-provider user-dn-pattern="uid={0},ou=people group-search-base="ou=groups" />
<ldap-authentication-provider user-dn-pattern="uid={0},ou=people" group-search-base="ou=groups" />
]]></programlisting>
and authenticated successfully as user
<quote>ben</quote>, the subsequent loading of authorities would perform a search

View File

@ -8,12 +8,12 @@
<title>Introduction</title>
</info>
<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
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
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
@ -24,23 +24,24 @@
]]></programlisting>
This is much simpler than wiring up the equivalent Apache Directory Server beans. The most
common alterative 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.
<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
</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 the Spring portfolio namespaces.
as it has special features for working with the Spring portfolio 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>
<programlisting>
<![CDATA[
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
@ -50,10 +51,11 @@
...
</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
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><![CDATA[
<beans:beans xmlns="http://www.springframework.org/schema/security"
@ -64,44 +66,71 @@
We'll assume this syntax is being used from now on in this chapter.
</para>
<section>
<info>
<title>Design of the Namespace</title>
</info>
<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 largely based around the large-scale dependencies
within the framework, and can be divided up into the following areas:
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:
<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>
<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>
</itemizedlist>
</para>
<para>We'll see how these work together in the next section.</para>
</section>
</section>
<section>
<info><title>Example Configurations</title></info>
<title>Example Configurations</title>
<para>
In this section, we'll look at how you can build up a namespace configuration to use different features of the framework.
</para>
In this section, we'll look at how you can build up a namespace configuration to use different
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.</para>
<section>
<info><title>A Minimal Configuration</title></info>
<para>
Let's assume you 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. The first thing you need to do is add the follwing fiter declaration to your <literal>web.xml</literal>
<info><title><literal>web.xml</literal> Configuration</title></info>
<para>
The first thing you need to do is add the following fiter declaration to your
<literal>web.xml</literal>
file:
<programlisting>
<![CDATA[
<programlisting>
<![CDATA[
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
@ -111,20 +140,32 @@
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>]]>
</programlisting>
This provides a hook into the Spring Security web infrastructure. You can find more details of how this works in
<link xlink:href="#todo">TODO</link>. You're then ready to start editing your application context file.
Web security services are configured using the <literal>&lt;http&gt;</literal> element.
All you need to begin with is
<programlisting><![CDATA[
</programlisting>
This provides a hook into the Spring Security web infrastructure. You can find more details
of how this works in
<link xlink:href="#todo">TODO</link>. You're then ready to start editing your application
context file. Web security services are configured using the <literal>&lt;http&gt;</literal>
element.
</para>
</section>
<section>
<info>
<title>A Minimal <literal>&lt;http&gt;</literal>Configuration</title>
</info>
<para>
All you need to enable web security to begin with is
<programlisting><![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. To add some users, you can define a set of test data directly in the namespace:
<programlisting><![CDATA[
Which says that we want all URLs within our application to be secured, requiring the role
<literal>ROLE_USER</literal>
to access them. To add some users, you can define a set of test data directly in the
namespace:
<programlisting><![CDATA[
<authentication-provider>
<user-service>
<user name="jimi" password="jimispassword" authorities="ROLE_USER, ROLE_ADMIN" />
@ -133,22 +174,133 @@
</authentication-provider>
]]>
</programlisting>
This defines two users, their passwords and their roles within the application (which will be used for access control). The
<literal>&lt;authentication-provider&gt;</literal> element specifies that the user information will be registered with the authentication
manager and used to process authentication requests.
<sidebar><para>If you are familiar with previous versions of the framework, the <literal>&lt;authentication-provider&gt;</literal>
element creates a <literal>DaoAuthenticationProvider</literal> bean and the <literal>&lt;user-service&gt;</literal> element creates
an <classname>InMemoryDaoImpl</classname>. A <literal>ProviderManager</literal> bean is always created by the namespace processing system
and the <literal>AuthenticationProvider</literal> is automatically registered with it.</para></sidebar>
</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 applicaition that comes with the project.
This configuration actually adds quite a few services to the application automatically (mainly because we have added the <literal>auto-config</literal>
attribute. For example, form login processing and "remember-me" services are automatically enabled. You might also be wondering where the
login form came from when you were prompted to log in. This was also generated automatically, since we didn't explicitly configure a login page URL, but the namespace offers plenty
of options to allow you to custmize this kind of thing.
</para>
This defines two users, their passwords and their roles within the application (which will
be used for access control). The
<literal>&lt;authentication-provider&gt;</literal>
element specifies that the user information will be registered with the authentication
manager and used to process authentication requests.
<sidebar>
<para>If you are familiar with previous versions of the framework, you can probably
already guess roughly what's going on here. The &lt;http&gt; element is
responsible for creating a <classname>FilterChainProxy</classname> and the required
list filter beans which it uses. Common issues like filter incorrect ordering are no
longer an issue as the filter positions are predefined.</para>
<para>The <literal>&lt;authentication-provider&gt;</literal>
element creates a <classname>DaoAuthenticationProvider</classname>
bean and the <literal>&lt;user-service&gt;</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>
</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 applicaition
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
enabled. You might also be wondering where the login form came from when you were prompted
to log in. This was also generated automatically, since we didn't explicitly set a URL for the
login page, but the namespace offers plenty of options to allow you to customize this
kind of thing.
</para>
<section>
<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>
These other elements are responsible for setting up form-login, see
<link xlink:href="#anonymous">anonymous authentication</link>, basic authentication, logout handling and remember-me services
respectively. They each have attributes which can be used to alter their behaviour. For example, if you
want to supply your own login page, you could use:
<programlisting><![CDATA[
<http auto-config='true'>
<intercept-url pattern="/**" access="ROLE_USER" />
<form-login login-page='/login.jsp'/>
</http>
]]>
</programlisting>
Note that you can still use <literal>auto-config</literal>. The <literal>form-login</literal> element just overrides the
default settings. If you want to use basic authentication instead of form login, then change the configuration to
<programlisting><![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. Note that 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>
<section>
<title>Configuring other Authentication Providers</title>
<para>
In practice you will need a more scalable source of user information than a few names added to the context file.
Most likely you will want to store your user information in something like a database or an LDAP server. 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[
<authentication-provider user-service-ref='myUserDetailsService'/>
]]>
</programlisting>
If you want to use a database, then you can use
<programlisting><![CDATA[
<authentication-provider>
<jdbc-user-service data-source-ref="securityDataSource"/>
</authentication-provider>
]]>
</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>
<para>
Often your password data will be encoded using a hashing algorithm. This is supported by the <literal>&gt;password-encoder&lt;</literal>
element. With SHA-encoded passwords, the original authentication provider configuration would look like this:
<programlisting><![CDATA[
<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>
]]>
</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 ecoder 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>
</chapter>

View File

@ -131,7 +131,7 @@
for more information</para>
<para>Rather than using <literal>DelegatingFilterProxy</literal>, we
strongly recommend to use <literal>FilterChainProxy</literal> instead.
strongly recommend that you use <literal>FilterChainProxy</literal> instead.
Whilst <literal>DelegatingFilterProxy</literal> is a very useful class,
the problem is that the number of lines of code required for
<literal>&lt;filter&gt;</literal> and