123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029 |
- <?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.springsource.org/spring/docs/3.0.x/spring-framework-reference/htmlsingle/spring-framework-reference.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 language="xml"><![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 create 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 linkend="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, you need to have
- the <literal>spring-security-config</literal> jar on your classpath. Then 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.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 content 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.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 to configure these 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 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
- <quote>springSecurityFilterChain</quote>, 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>
- <intercept-url pattern="/**" access="ROLE_USER" />
- <form-login />
- <logout />
- </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, we want to log in to
- the application using a form with username and password, and that we want a logout URL
- registered which will allow us to log out of the application.
- <literal><http></literal> element is the parent for all web-related namespace
- functionality. The <literal><intercept-url></literal> element defines a
- <literal>pattern</literal> which is matched against the URLs of incoming requests
- using an ant path style syntax<footnote>
- <para>See the section on <link linkend="request-matching">Request
- Matching</link> in the Web Application Infrastructure chapter for more details
- on how matches are actually performed.</para>
- </footnote>. You can also use regular-expression matching as an alternative (see the
- namespace appendix for more details). The <literal>access</literal> attribute
- defines the access requirements for requests matching the given pattern. With the
- default configuration, this is typically a comma-separated list of roles, one of
- which a user must have to be allowed to make the request. The prefix
- <quote>ROLE_</quote> is a marker which indicates that a simple comparison with the
- user's authorities should be made. In other words, a normal role-based check should
- be used. Access-control in Spring Security is not limited to the use of simple roles
- (hence the use of the prefix to differentiate between different types of security
- attributes). We'll see later how the interpretation can vary<footnote>
- <para>The interpretation of the comma-separated values in the
- <literal>access</literal> attribute depends on the implementation of the <link
- linkend="ns-access-manager">AccessDecisionManager</link> which is used. In
- Spring Security 3.0, the attribute can also be populated with an <link
- linkend="el-access">EL expression</link>.</para>
- </footnote>.</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. You can also add a
- <literal>method</literal> attribute to limit the match to a particular HTTP
- method (<literal>GET</literal>, <literal>POST</literal>, <literal>PUT</literal>
- etc.).</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
- <literal><http></literal> element is responsible for creating a
- <classname>FilterChainProxy</classname> and the filter beans which it uses.
- Common problems 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 children of 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 linkend="appendix-namespace">namespace appendix</link>.
- It's worth cross-checking this if you want to start understanding what the
- important classes in the framework are and how they are used, particularly if
- you want to customise things later.</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 linkend="core-services-in-memory-service">in-memory
- authentication</link> for more details on the file format. Using the
- <literal><authentication-provider></literal> element means that the user
- information will be used by the authentication manager to process authentication
- requests. You can have multiple <literal><authentication-provider></literal>
- elements to define different authentication sources and each will be consulted in
- turn.</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
- <quote>tutorial</quote> sample application that comes with the project.</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 after logging in and so on. However, the namespace offers plenty of support
- 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>
- <intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
- <intercept-url pattern="/**" access="ROLE_USER" />
- <form-login login-page='/login.jsp'/>
- </http>
- ]]>
- </programlisting> Also note
- that we've added an extra <literal>intercept-url</literal> element to say that any
- requests for the login page should be available to anonymous users <footnote>
- <para>See the chapter on <link linkend="anonymous">anonymous
- authentication</link> and also the <link linkend="authz-authenticated-voter"
- >AuthenticatedVoter</link> class for more details on how the value
- <literal>IS_AUTHENTICATED_ANONYMOUSLY</literal> is processed.</para>
- </footnote>. Otherwise the request would be matched by the pattern
- <literal>/**</literal> and it wouldn't be possible to access the login page itself!
- This is a common configuration error and will result in an infinite loop in the
- application. Spring Security will emit a warning in the log if your login page
- appears to be secured. It is also possible to have all requests matching a
- particular pattern bypass the security filter chain completely, by defining a
- separate <literal>http</literal> element for the pattern like this: <programlisting language="xml"><![CDATA[
- <http pattern="/css/**" security="none"/>
- <http pattern="/login.jsp*" security="none"/>
- <http>
- <intercept-url pattern="/**" access="ROLE_USER" />
- <form-login login-page='/login.jsp'/>
- </http>
- ]]>
- </programlisting> From Spring Security 3.1 it is now possible to use multiple
- <literal>http</literal> elements to define separate security filter chain
- configurations for different request patterns. If the <literal>pattern</literal>
- attribute is omitted from an <literal>http</literal> element, it matches all
- requests. Creating an unsecured pattern is a simple example of this syntax, where
- the pattern is mapped to an empty filter chain <footnote>
- <para>The use of multiple <literal><http></literal> elements is an important
- feature, allowing the namespace to simultaneously support both stateful and
- stateless paths within the same application, for example. The previous syntax,
- using the attribute <literal>filters="none"</literal> on an
- <literal>intercept-url</literal> element is incompatible with this change and is
- no longer supported in 3.1.</para>
- </footnote>. We'll look at this new syntax in more detail in the chapter on the
- <link linkend="filter-chains-with-ns">Security Filter Chain</link>. </para>
- <para> It's important to realise that these unsecured requests will be completely
- oblivious to any Spring Security web-related configuration or additional attributes
- such as <literal>requires-channel</literal>, so you will not be able to access
- information on the current user or call secured methods during the request. Use
- <literal>access='IS_AUTHENTICATED_ANONYMOUSLY'</literal> as an alternative if you
- still want the security filter chain to be applied.</para>
- <para>If you want to use basic authentication instead of form login, then change the
- configuration to <programlisting language="xml"><![CDATA[
- <http>
- <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 successfully logging in, and defaults to
- "/". You can also configure things so that the 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 pattern="/login.htm*" security="none"/>
- <http>
- <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>
- <para>For even more control over the destination, you can use the
- <literal>authentication-success-handler-ref</literal> attribute as an
- alternative to <literal>default-target-url</literal>. The referenced bean should
- be an instance of <interfacename>AuthenticationSuccessHandler</interfacename>.
- You'll find more on this in the <link linkend="form-login-flow-handling"
- >Core Filters</link> chapter and also in the namespace appendix, as well as
- information on how to customize the flow when authentication fails. </para>
- </section>
- </section>
- <section xml:id="ns-logout">
- <title>Logout Handling</title>
- <para>The <literal>logout</literal> element adds support for logging out by navigating
- to a particular URL. The default logout URL is <literal>/j_spring_security_logout</literal>,
- but you can set it to something else using the <literal>logout-url</literal> attribute.
- More information on other available attributes may be found in the namespace appendix.
- </para>
- </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 linkend="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 <quote>securityDataSource</quote> is the name of a
- <classname>DataSource</classname> bean in the application context, pointing at a
- database containing the standard Spring Security <link
- linkend="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>. You can use multiple
- <literal>authentication-provider</literal> elements, in which case the providers
- will be queried in the order they are declared. 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 xml:id="ns-password-encoder">
- <title>Adding a Password Encoder</title>
- <para> Passwords should always be encoded using a secure hashing algorithm designed for the purpose
- (not a standard algorithm like SHA or MD5). This is supported by the
- <literal><password-encoder></literal> element. With bcrypt
- encoded passwords, the original authentication provider configuration would look
- like this: <programlisting language="xml"><![CDATA[
- <beans:bean name="bcryptEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
- <authentication-manager>
- <authentication-provider>
- <password-encoder ref="bcryptEncoder"/>
- <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>Bcrypt is a good choice for most cases, unless you have a legacy system which forces
- you to use a different algorithm. If you are using a simple hashing algorithm or, even worse,
- storing plain text passwords, then you should consider migrating to a more secure option like bcrypt.
- </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 linkend="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
- <footnote><para>For more details on how channel-processing is implemented, see the Javadoc
- for <classname>ChannelProcessingFilter</classname> and related classes.
- </para></footnote>.
- 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 language="xml"><![CDATA[
- <http>
- ...
- <port-mappings>
- <port-mapping http="9080" https="9443"/>
- </port-mappings>
- </http>]]>
- </programlisting>
- Note that in order to be truly secure, an application should not use HTTP at all or switch
- between HTTP and HTTPS. It should start in HTTPS (with the user entering an HTTPS URL) and
- use a secure connection throughout to avoid any possibility of man-in-the-middle attacks.
- </para>
- </section>
- <section xml:id="ns-session-mgmt">
- <title>Session Management</title>
- <section>
- <title>Detecting Timeouts</title>
- <para> You can configure Spring Security to detect the submission of an invalid
- session ID and redirect the user to an appropriate URL. This is achieved through
- the <literal>session-management</literal> element: <programlisting language="xml"><![CDATA[
- <http>
- ...
- <session-management invalid-session-url="/invalidSession.htm" />
- </http>]]></programlisting>Note that if you use this mechanism to detect session timeouts, it
- may falsely report an error if the user logs out and then logs back in without
- closing the browser. This is because the session cookie is not cleared when you
- invalidate the session and will be resubmitted even if the user has logged out.
- You may be able to explicitly delete the JSESSIONID cookie on logging out, for
- example by using the following syntax in the logout handler: <programlisting language="xml"><![CDATA[
- <http>
- <logout delete-cookies="JSESSIONID" />
- </http>
- ]]></programlisting> Unfortunately this can't be guaranteed to work with every servlet container,
- so you will need to test it in your environment<footnote>
- <para>If you are running your application behind a proxy, you may also be able
- to remove the session cookie by configuring the proxy server. For example,
- using Apache HTTPD's mod_headers, the following directive would delete the
- <literal>JSESSIONID</literal> cookie by expiring it in the response to a
- logout request (assuming the application is deployed under the path
- <literal>/tutorial</literal>):
- <programlisting language="xml"> <LocationMatch "/tutorial/j_spring_security_logout">
- Header always set Set-Cookie "JSESSIONID=;Path=/tutorial;Expires=Thu, 01 Jan 1970 00:00:00 GMT"
- </LocationMatch></programlisting></para>
- </footnote>. </para>
- </section>
- <section xml:id="ns-concurrent-sessions">
- <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 lines to your application context: <programlisting language="xml"><![CDATA[
- <http>
- ...
- <session-management>
- <concurrency-control max-sessions="1" />
- </session-management>
- </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>
- ...
- <session-management>
- <concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
- </session-management>
- </http>]]>
- </programlisting>The second login will then be rejected. By
- <quote>rejected</quote>, we mean that the user will be sent to the
- <literal>authentication-failure-url</literal> if form-based login is being used.
- If the second authentication takes place through another non-interactive
- mechanism, such as <quote>remember-me</quote>, an <quote>unauthorized</quote>
- (401) error will be sent to the client. If instead you want to use an error
- page, you can add the attribute
- <literal>session-authentication-error-url</literal> to the
- <literal>session-management</literal> element. </para>
- <para>If you are using a customized authentication filter for form-based login, then
- you have to configure concurrent session control support explicitly. More
- details can be found in the <link linkend="session-mgmt">Session Management
- chapter</link>. </para>
- </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 or otherwise changing the
- session ID when a user logs in. If you don't require this protection, or it
- conflicts with some other requirement, you can control the behavior using the
- <literal>session-fixation-protection</literal> attribute on
- <literal><session-management></literal>, which has four options <itemizedlist>
- <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 (Spring Security-related attributes will
- still be copied).</para>
- </listitem>
- <listitem>
- <para><literal>migrateSession</literal> - Create a new session and copy
- all existing session attributes to the new session. This is the
- default in Servlet 3.0 or older containers.</para>
- </listitem>
- <listitem>
- <para><literal>changeSessionId</literal> - Do not create a new session.
- Instead, use the session fixation protection provided by the Servlet container
- (<literal>HttpServletRequest#changeSessionId()</literal>). This option is only
- available in Servlet 3.1 (Java EE 7) and newer containers. Specifying it in
- older containers will result in an exception. This is the default in Servlet
- 3.1 and newer containers.</para>
- </listitem>
- </itemizedlist>
- When session fixation protection occurs, it results in a
- <classname>SessionFixationProtectionEvent</classname> being published in the
- application context. If you use <literal>changeSessionId</literal>, this protection
- will <emphasis>also</emphasis> result in any
- <classname>javax.servlet.http.HttpSessionIdListener</classname>s being notified, so
- use caution if your code listens for both events. See the
- <link linkend="session-mgmt">Session Management</link> chapter for additional
- information.
- </para>
- </section>
- </section>
- <section xml:id="ns-openid">
- <title>OpenID Support</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 language="xml"><![CDATA[
- <user name="http://jimi.hendrix.myopenid.com/" authorities="ROLE_USER" />
- ]]></programlisting> You should be able to login using the <literal>myopenid.com</literal> site to
- authenticate. It is also possible to select a specific
- <interfacename>UserDetailsService</interfacename> bean for use OpenID by setting the
- <literal>user-service-ref</literal> attribute on the <literal>openid-login</literal>
- element. See the previous section on <link linkend="ns-auth-providers"
- >authentication providers</link> for more information. Note that we have omitted the
- password attribute from the above user configuration, since this set of user data is
- only being used to load the authorities for the user. A random password will be
- generate internally, preventing you from accidentally using this user data as an
- authentication source elsewhere in your configuration.</para>
- <section>
- <title>Attribute Exchange</title>
- <para>Support for OpenID <link
- xlink:href="http://openid.net/specs/openid-attribute-exchange-1_0.html"
- >attribute exchange</link>. As an example, the following configuration would
- attempt to retrieve the email and full name from the OpenID provider, for use by
- the application:<programlisting language="xml"><![CDATA[
- <openid-login>
- <attribute-exchange>
- <openid-attribute name="email" type="http://axschema.org/contact/email" required="true"/>
- <openid-attribute name="name" type="http://axschema.org/namePerson"/>
- </attribute-exchange>
- </openid-login>]]></programlisting>The <quote>type</quote> of each OpenID attribute is a URI,
- determined by a particular schema, in this case <link
- xlink:href="http://axschema.org/">http://axschema.org/</link>. If an attribute
- must be retrieved for successful authentication, the <literal>required</literal>
- attribute can be set. The exact schema and attributes supported will depend on
- your OpenID provider. The attribute values are returned as part of the
- authentication process and can be accessed afterwards using the following code:
- <programlisting language="java">
- OpenIDAuthenticationToken token =
- (OpenIDAuthenticationToken)SecurityContextHolder.getContext().getAuthentication();
- List<OpenIDAttribute> attributes = token.getAttributes();</programlisting>The
- <classname>OpenIDAttribute</classname> contains the attribute type and the
- retrieved value (or values in the case of multi-valued attributes). We'll see
- more about how the <classname>SecurityContextHolder</classname> class is used
- when we look at core Spring Security components in the <link
- linkend="core-components">technical overview</link> chapter. Multiple
- attribute exchange configurations are also be supported, if you wish to use
- multiple identity providers. You can supply multiple
- <literal>attribute-exchange</literal> elements, using an
- <literal>identifier-matcher</literal> attribute on each. This contains a regular
- expression which will be matched against the OpenID identifier supplied by the
- user. See the OpenID sample application in the codebase for an example
- configuration, providing different attribute lists for the Google, Yahoo and
- MyOpenID providers.</para>
- </section>
- </section>
- <section xml:id="ns-headers">
- <title>Response Headers</title>
- <para>A lot of different attacks to hijack content, sessions or connections are available and lately
- browsers (optionally) can help to prevent those attacks. To enable these features we need to send some
- additional headers to the client. Spring Security allows for easy configuration for several headers.
- <programlisting language="xml"><![CDATA[
- <http ...>
- ...
- <headers/>
- </http>]]>
- </programlisting>
- </para>
- <para>Specifying the single headers element adds all the explicitly supported headers
- with their default settings. If you only want select headers to be added,
- you can add one or more of the child elements as shown below.
- <programlisting language="xml"><![CDATA[
- <http ...>
- ...
- <headers>
- <!-- Add Cache-Control, Pragma, and Expires headers -->
- <cache-control/>
- <!-- Add X-Content-Type-Options with value of nosniff -->
- <content-type-options/>
- <!-- Add custom headers -->
- <header name="foo" value="bar"/>
- <-- Adds HTTP Strict Transport Security (HSTS) for secure requests -->
- <hsts/>
- <!-- Add X-Frame-Options with a value of DENY -->
- <frame-options/>
- <!-- Adds X-XSS-Protection with value of 1; mode=block-->
- <xss-protection/>
- </headers>
- </http>]]>
- </programlisting>
- </para>
- <para>For additional information on how to customize the headers element refer to the <link linkend="headers">Security Headers</link>
- section of the reference.</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 <classname>UsernamePasswordAuthenticationFilter</classname> 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">
- <colspec colnum="1" colname="col1" colwidth="2*"/>
- <colspec colnum="2" colname="col2" colwidth="2*"/>
- <colspec colnum="3" colname="col3" colwidth="1*"/>
- <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@requires-channel</literal></entry>
- </row>
- <row>
- <entry> SECURITY_CONTEXT_FILTER</entry>
- <entry><classname>SecurityContextPersistenceFilter</classname></entry>
- <entry><literal>http</literal></entry>
- </row>
- <row>
- <entry> CONCURRENT_SESSION_FILTER</entry>
- <entry><literal>ConcurrentSessionFilter</literal> </entry>
- <entry><literal>session-management/concurrency-control</literal></entry>
- </row>
- <row>
- <entry>HEADERS_FILTER</entry>
- <entry><literal>HeaderWriterFilter</literal> </entry>
- <entry><literal>http/headers</literal></entry>
- </row>
- <row>
- <entry>CSRF_FILTER</entry>
- <entry><literal>CsrfFilter</literal> </entry>
- <entry><literal>http/csrf</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>X509AuthenticationFilter</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_FILTER </entry>
- <entry><literal>CasAuthenticationFilter</literal></entry>
- <entry>N/A</entry>
- </row>
- <row>
- <entry> FORM_LOGIN_FILTER </entry>
- <entry><literal>UsernamePasswordAuthenticationFilter</literal></entry>
- <entry><literal>http/form-login</literal></entry>
- </row>
- <row>
- <entry> BASIC_AUTH_FILTER </entry>
- <entry><literal>BasicAuthenticationFilter</literal></entry>
- <entry><literal>http/http-basic</literal></entry>
- </row>
- <row>
- <entry> SERVLET_API_SUPPORT_FILTER</entry>
- <entry><literal>SecurityContextHolderAwareRequestFilter</literal></entry>
- <entry><literal>http/@servlet-api-provision</literal></entry>
- </row>
- <row>
- <entry>JAAS_API_SUPPORT_FILTER</entry>
- <entry><literal>JaasApiIntegrationFilter</literal></entry>
- <entry><literal>http/@jaas-api-provision</literal></entry>
- </row>
- <row>
- <entry> REMEMBER_ME_FILTER </entry>
- <entry><classname>RememberMeAuthenticationFilter</classname></entry>
- <entry><literal>http/remember-me</literal></entry>
- </row>
- <row>
- <entry> ANONYMOUS_FILTER </entry>
- <entry><literal>AnonymousAuthenticationFilter</literal></entry>
- <entry><literal>http/anonymous</literal></entry>
- </row>
- <row>
- <entry> SESSION_MANAGEMENT_FILTER</entry>
- <entry><literal>SessionManagementFilter</literal></entry>
- <entry><literal>session-management</literal></entry>
- </row>
- <row>
- <entry>EXCEPTION_TRANSLATION_FILTER </entry>
- <entry><classname>ExceptionTranslationFilter</classname></entry>
- <entry><literal>http</literal></entry>
- </row>
- <row>
- <entry> FILTER_SECURITY_INTERCEPTOR </entry>
- <entry><classname>FilterSecurityInterceptor</classname></entry>
- <entry><literal>http</literal></entry>
- </row>
- <row>
- <entry> SWITCH_USER_FILTER </entry>
- <entry><literal>SwitchUserFilter</literal></entry>
- <entry>N/A</entry>
- </row>
- </tbody>
- </tgroup>
- </table> You can add your own filter to the stack, using the
- <literal>custom-filter</literal> element and one of these names to specify the
- position your filter should appear at: <programlisting language="xml"><![CDATA[
- <http>
- <custom-filter position="FORM_LOGIN_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. 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>SecurityContextPersistenceFilter</classname>,
- <classname>ExceptionTranslationFilter</classname> or
- <classname>FilterSecurityInterceptor</classname>. Some other filters are added
- by default, but you can disable them. An <classname>AnonymousAuthenticationFilter</classname>
- is added by default and unless you have
- <link linkend="ns-session-fixation">session-fixation protection</link>
- disabled, a <classname>SessionManagementFilter</classname> will also be added
- to the filter chain.
- </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
- linkend="tech-intro-auth-entry-point">technical overview</link> chapter.
- </para>
- </section>
- </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 annotation
- security as well as the framework's original <literal>@Secured</literal> annotation.
- From 3.0 you can also make use of new <link linkend="el-access">expression-based
- annotations</link>. 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 Spring Security's <literal>@Secured</literal>: <programlisting language="xml"><![CDATA[
- <global-method-security secured-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:
- <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>Support
- for JSR-250 annotations can be enabled using <programlisting language="xml"><![CDATA[
- <global-method-security jsr250-annotations="enabled" />
- ]]>
- </programlisting>These are standards-based and allow simple role-based constraints to
- be applied but do not have the power Spring Security's native annotations. To use
- the new expression-based syntax, you would use <programlisting language="xml"><![CDATA[
- <global-method-security pre-post-annotations="enabled" />
- ]]></programlisting>and the equivalent Java code would
- be<programlisting language="java">
- public interface BankService {
- @PreAuthorize("isAnonymous()")
- public Account readAccount(Long id);
- @PreAuthorize("isAnonymous()")
- public Account[] findAccounts();
- @PreAuthorize("hasAuthority('ROLE_TELLER')")
- public Account post(Account account, double amount);
- }
- </programlisting>Expression-based
- annotations are a good choice if you need to define simple rules that go beyond
- checking the role names against the user's list of authorities. <note>
- <para>The annotated methods will only be secured for instances which are defined as
- Spring beans (in the same application context in which method-security is
- enabled). If you want to secure instances which are not created by Spring (using
- the <literal>new</literal> operator, for example) then you need to use AspectJ.
- </para>
- </note>
- <note>
- <para>
- You can enable more than one type of annotation in the same application, but
- only one type should be used for any interface or class as the behaviour will not
- be well-defined otherwise. If two annotations are found which apply to a particular
- method, then only one of them will be applied.
- </para>
- </note> </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. Security
- annotations take precedence over pointcuts.
- </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>. You
- can find out more about these in the chapter on <link linkend="authz-arch"
- >authorization</link>.</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 <literal>id</literal> 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 language="xml"><![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
- the <link linkend="tech-intro-authentication">technical overview chapter</link>. 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">
- ...
- </bean>
- ]]></programlisting></para>
- <para> Another common requirement is that another bean in the context may require a
- reference to the <interfacename>AuthenticationManager</interfacename>. You can easily
- register an alias for the <interfacename>AuthenticationManager</interfacename> and 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>
|