Manual formatting.
This commit is contained in:
		
							parent
							
								
									ae8027fa47
								
							
						
					
					
						commit
						90caf1bb37
					
				|  | @ -8,17 +8,17 @@ | ||||||
|             <title>Overview</title> |             <title>Overview</title> | ||||||
|         </info> |         </info> | ||||||
|         <para>It's generally considered good security practice to adopt a |         <para>It's generally considered good security practice to adopt a | ||||||
|                 <quote>deny-by-default</quote> where you explicitly specify what is allowed and |             <quote>deny-by-default</quote> where you explicitly specify what is allowed and disallow | ||||||
|             disallow everything else. Defining what is accessible to unauthenticated users is a |             everything else. Defining what is accessible to unauthenticated users is a similar | ||||||
|             similar situation, particularly for web applications. Many sites require that users must |             situation, particularly for web applications. Many sites require that users must be | ||||||
|             be authenticated for anything other than a few URLs (for example the home and login |             authenticated for anything other than a few URLs (for example the home and login pages). | ||||||
|             pages). In this case it is easiest to define access configuration attributes for these |             In this case it is easiest to define access configuration attributes for these specific | ||||||
|             specific URLs rather than have for every secured resource. Put differently, sometimes it |             URLs rather than have for every secured resource. Put differently, sometimes it is nice | ||||||
|             is nice to say <literal>ROLE_SOMETHING</literal> is required by default and only allow |             to say <literal>ROLE_SOMETHING</literal> is required by default and only allow certain | ||||||
|             certain exceptions to this rule, such as for login, logout and home pages of an |             exceptions to this rule, such as for login, logout and home pages of an application. You | ||||||
|             application. You could also omit these pages from the filter chain entirely, thus |             could also omit these pages from the filter chain entirely, thus bypassing the access | ||||||
|             bypassing the access control checks, but this may be undesirable for other reasons, |             control checks, but this may be undesirable for other reasons, particularly if the pages | ||||||
|             particularly if the pages behave differently for authenticated users.</para> |             behave differently for authenticated users.</para> | ||||||
|         <para>This is what we mean by anonymous authentication. Note that there is no real |         <para>This is what we mean by anonymous authentication. Note that there is no real | ||||||
|             conceptual difference between a user who is <quote>anonymously authenticated</quote> and |             conceptual difference between a user who is <quote>anonymously authenticated</quote> and | ||||||
|             an unauthenticated user. Spring Security's anonymous authentication just gives you a |             an unauthenticated user. Spring Security's anonymous authentication just gives you a | ||||||
|  | @ -44,18 +44,17 @@ | ||||||
|         <para>Three classes that together provide the anonymous authentication feature. |         <para>Three classes that together provide the anonymous authentication feature. | ||||||
|             <literal>AnonymousAuthenticationToken</literal> is an implementation of |             <literal>AnonymousAuthenticationToken</literal> is an implementation of | ||||||
|             <interfacename>Authentication</interfacename>, and stores the |             <interfacename>Authentication</interfacename>, and stores the | ||||||
|                 <interfacename>GrantedAuthority</interfacename>s which apply to the anonymous |             <interfacename>GrantedAuthority</interfacename>s which apply to the anonymous principal. | ||||||
|             principal. There is a corresponding <literal>AnonymousAuthenticationProvider</literal>, |             There is a corresponding <literal>AnonymousAuthenticationProvider</literal>, which is | ||||||
|             which is chained into the <literal>ProviderManager</literal> so that |             chained into the <literal>ProviderManager</literal> so that | ||||||
|             <literal>AnonymousAuthenticationToken</literal>s are accepted. Finally, there is an |             <literal>AnonymousAuthenticationToken</literal>s are accepted. Finally, there is an | ||||||
|                 <classname>AnonymousAuthenticationFilter</classname>, which is chained after the |             <classname>AnonymousAuthenticationFilter</classname>, which is chained after the normal | ||||||
|             normal authentication mechanisms and automatically adds an |             authentication mechanisms and automatically adds an | ||||||
|             <literal>AnonymousAuthenticationToken</literal> to the |             <literal>AnonymousAuthenticationToken</literal> to the | ||||||
|             <classname>SecurityContextHolder</classname> if there is no existing |             <classname>SecurityContextHolder</classname> if there is no existing | ||||||
|                 <interfacename>Authentication</interfacename> held there. The definition of the |             <interfacename>Authentication</interfacename> held there. The definition of the filter | ||||||
|             filter and authentication provider appears as follows:</para> |             and authentication provider appears as follows:</para> | ||||||
|         <para> |         <para> <programlisting> | ||||||
|             <programlisting> |  | ||||||
| <![CDATA[ | <![CDATA[ | ||||||
| <bean id="anonymousAuthFilter" | <bean id="anonymousAuthFilter" | ||||||
|     class="org.springframework.security.web.authentication.AnonymousAuthenticationFilter"> |     class="org.springframework.security.web.authentication.AnonymousAuthenticationFilter"> | ||||||
|  | @ -67,32 +66,30 @@ | ||||||
|     class="org.springframework.security.authentication.AnonymousAuthenticationProvider"> |     class="org.springframework.security.authentication.AnonymousAuthenticationProvider"> | ||||||
|   <property name="key" value="foobar"/> |   <property name="key" value="foobar"/> | ||||||
| </bean>]]> | </bean>]]> | ||||||
|     </programlisting> |     </programlisting> </para> | ||||||
|         </para> |  | ||||||
|         <para>The <literal>key</literal> is shared between the filter and authentication provider, |         <para>The <literal>key</literal> is shared between the filter and authentication provider, | ||||||
|             so that tokens created by the former are accepted by the latter<footnote><para>The use |             so that tokens created by the former are accepted by the latter<footnote> | ||||||
|                     of the <literal>key</literal> property should not be regarded as providing any |             <para>The use of the <literal>key</literal> property should not be regarded as providing | ||||||
|                     real security here. It is merely a book-keeping exercise. If you are sharing a |                 any real security here. It is merely a book-keeping exercise. If you are sharing a | ||||||
|                 <classname>ProviderManager</classname> which contains an |                 <classname>ProviderManager</classname> which contains an | ||||||
|                         <classname>AnonymousAuthenticationProvider</classname> in a scenario where |                 <classname>AnonymousAuthenticationProvider</classname> in a scenario where it is | ||||||
|                     it is possible for an authenticating client to construct the |                 possible for an authenticating client to construct the | ||||||
|                         <interfacename>Authentication</interfacename> object (such as with RMI |                 <interfacename>Authentication</interfacename> object (such as with RMI invocations), | ||||||
|                     invocations), then a malicious client could submit an |                 then a malicious client could submit an | ||||||
|                         <classname>AnonymousAuthenticationToken</classname> which it had created |                 <classname>AnonymousAuthenticationToken</classname> which it had created itself | ||||||
|                     itself (with chosen username and authority list). If the <literal>key</literal> |                 (with chosen username and authority list). If the <literal>key</literal> is | ||||||
|                     is guessable or can be found out, then the token would be accepted by the |                 guessable or can be found out, then the token would be accepted by the anonymous | ||||||
|                     anonymous provider. This isn't a problem with normal usage but if you are using |                 provider. This isn't a problem with normal usage but if you are using RMI you would | ||||||
|                     RMI you would be best to use a customized <classname>ProviderManager</classname> |                 be best to use a customized <classname>ProviderManager</classname> which omits the | ||||||
|                     which omits the anonymous provider rather than sharing the one you use for your |                 anonymous provider rather than sharing the one you use for your HTTP authentication | ||||||
|                     HTTP authentication mechanisms.</para></footnote>. The |                 mechanisms.</para> | ||||||
|                 <literal>userAttribute</literal> is expressed in the form of |             </footnote>. The <literal>userAttribute</literal> is expressed in the form of | ||||||
|             <literal>usernameInTheAuthenticationToken,grantedAuthority[,grantedAuthority]</literal>. |             <literal>usernameInTheAuthenticationToken,grantedAuthority[,grantedAuthority]</literal>. | ||||||
|             This is the same syntax as used after the equals sign for |             This is the same syntax as used after the equals sign for | ||||||
|             <literal>InMemoryDaoImpl</literal>'s <literal>userMap</literal> property.</para> |             <literal>InMemoryDaoImpl</literal>'s <literal>userMap</literal> property.</para> | ||||||
|         <para>As explained earlier, the benefit of anonymous authentication is that all URI patterns |         <para>As explained earlier, the benefit of anonymous authentication is that all URI patterns | ||||||
|             can have security applied to them. For example:</para> |             can have security applied to them. For example:</para> | ||||||
|         <para> |         <para> <programlisting> | ||||||
|             <programlisting> |  | ||||||
| <![CDATA[ | <![CDATA[ | ||||||
| <bean id="filterSecurityInterceptor" | <bean id="filterSecurityInterceptor" | ||||||
|     class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor"> |     class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor"> | ||||||
|  | @ -108,8 +105,7 @@ | ||||||
|     </security:filter-security-metadata-source>" + |     </security:filter-security-metadata-source>" + | ||||||
|   </property> |   </property> | ||||||
| </bean>]]> | </bean>]]> | ||||||
|     </programlisting> |     </programlisting> </para> | ||||||
|         </para> |  | ||||||
|     </section> |     </section> | ||||||
|     <section xml:id="anonymous-auth-trust-resolver"> |     <section xml:id="anonymous-auth-trust-resolver"> | ||||||
|         <title><interfacename>AuthenticationTrustResolver</interfacename></title> |         <title><interfacename>AuthenticationTrustResolver</interfacename></title> | ||||||
|  | @ -131,12 +127,12 @@ | ||||||
|             which is effectively the same thing when defining access controls. This is an example of |             which is effectively the same thing when defining access controls. This is an example of | ||||||
|             the use of the <classname>AuthenticatedVoter</classname> which we will see in the <link |             the use of the <classname>AuthenticatedVoter</classname> which we will see in the <link | ||||||
|             xlink:href="#authz-authenticated-voter">authorization chapter</link>. It uses an |             xlink:href="#authz-authenticated-voter">authorization chapter</link>. It uses an | ||||||
|                 <interfacename>AuthenticationTrustResolver</interfacename> to process this |             <interfacename>AuthenticationTrustResolver</interfacename> to process this particular | ||||||
|             particular configuration attribute and grant access to anonymous users. The |             configuration attribute and grant access to anonymous users. The | ||||||
|                 <classname>AuthenticatedVoter</classname> approach is more powerful, since it allows |             <classname>AuthenticatedVoter</classname> approach is more powerful, since it allows you | ||||||
|             you to differentiate between anonymous, remember-me and fully-authenticated users. If |             to differentiate between anonymous, remember-me and fully-authenticated users. If you | ||||||
|             you don't need this functionality though, then you can stick with |             don't need this functionality though, then you can stick with | ||||||
|                 <literal>ROLE_ANONYMOUS</literal>, which will be processed by Spring Security's |             <literal>ROLE_ANONYMOUS</literal>, which will be processed by Spring Security's standard | ||||||
|             standard <classname>RoleVoter</classname>. </para> |             <classname>RoleVoter</classname>. </para> | ||||||
|     </section> |     </section> | ||||||
| </chapter> | </chapter> | ||||||
|  |  | ||||||
|  | @ -4,16 +4,17 @@ | ||||||
|     <info> |     <info> | ||||||
|         <title>Security Database Schema</title> |         <title>Security Database Schema</title> | ||||||
|     </info> |     </info> | ||||||
|   <para> There are various database schema used by the framework and this appendix provides a single |     <para> There are various database schema used by the framework and this appendix provides a | ||||||
|     reference point to them all. You only need to provide the tables for the areas of functonality |         single reference point to them all. You only need to provide the tables for the areas of | ||||||
|     you require. </para> |         functonality you require. </para> | ||||||
|     <para> DDL statements are given for the HSQLDB database. You can use these as a guideline for |     <para> DDL statements are given for the HSQLDB database. You can use these as a guideline for | ||||||
|         defining the schema for the database you are using. </para> |         defining the schema for the database you are using. </para> | ||||||
|     <section> |     <section> | ||||||
|         <title>User Schema</title> |         <title>User Schema</title> | ||||||
|     <para> The standard JDBC implementation of the <interfacename>UserDetailsService</interfacename> |         <para> The standard JDBC implementation of the | ||||||
|         (<classname>JdbcDaoImpl</classname>) requires tables to load the password, account status |             <interfacename>UserDetailsService</interfacename> (<classname>JdbcDaoImpl</classname>) | ||||||
|       (enabled or disabled) and a list of authorities (roles) for the user. |             requires tables to load the password, account status (enabled or disabled) and a list of | ||||||
|  |             authorities (roles) for the user. | ||||||
|             <programlisting xml:id="db_schema_users_authorities"> |             <programlisting xml:id="db_schema_users_authorities"> | ||||||
|   create table users( |   create table users( | ||||||
|       username varchar_ignorecase(50) not null primary key, |       username varchar_ignorecase(50) not null primary key, | ||||||
|  | @ -67,33 +68,35 @@ create table persistent_logins ( | ||||||
|         <para>There are four tables used by the Spring Security <link xlink:href="#domain-acls" |         <para>There are four tables used by the Spring Security <link xlink:href="#domain-acls" | ||||||
|             >ACL</link> implementation. <orderedlist> |             >ACL</link> implementation. <orderedlist> | ||||||
|             <listitem> |             <listitem> | ||||||
|           <para><literal>acl_sid</literal> stores the security identities recognised by the ACL |                 <para><literal>acl_sid</literal> stores the security identities recognised by the | ||||||
|             system. These can be unique principals or authorities which may apply to multiple |                     ACL system. These can be unique principals or authorities which may apply to | ||||||
|             principals.</para> |                     multiple principals.</para> | ||||||
|             </listitem> |             </listitem> | ||||||
|             <listitem> |             <listitem> | ||||||
|           <para><literal>acl_class</literal> defines the domain object types to which ACLs apply. |                 <para><literal>acl_class</literal> defines the domain object types to which ACLs | ||||||
|             The <literal>class</literal> column stores the Java class name of the object. </para> |                     apply. The <literal>class</literal> column stores the Java class name of the | ||||||
|  |                     object. </para> | ||||||
|             </listitem> |             </listitem> | ||||||
|             <listitem> |             <listitem> | ||||||
|           <para><literal>acl_object_identity</literal> stores the object identity definitions of |                 <para><literal>acl_object_identity</literal> stores the object identity definitions | ||||||
|             specific domai objects.</para> |                     of specific domai objects.</para> | ||||||
|             </listitem> |             </listitem> | ||||||
|             <listitem> |             <listitem> | ||||||
|           <para><literal>acl_entry</literal> stores the ACL permissions which apply to a specific |                 <para><literal>acl_entry</literal> stores the ACL permissions which apply to a | ||||||
|             object identity and security identity.</para> |                     specific object identity and security identity.</para> | ||||||
|             </listitem> |             </listitem> | ||||||
|             </orderedlist></para> |             </orderedlist></para> | ||||||
|         <para>It is assumed that the database will auto-generate the primary keys for each of the |         <para>It is assumed that the database will auto-generate the primary keys for each of the | ||||||
|       identities. The <literal>JdbcMutableAclService</literal> has to be able to retrieve these when |             identities. The <literal>JdbcMutableAclService</literal> has to be able to retrieve | ||||||
|       it has created a new row in the <literal>acl_sid</literal> or <literal>acl_class</literal> |             these when it has created a new row in the <literal>acl_sid</literal> or | ||||||
|       tables. It has two properties which define the SQL needed to retrieve these values |             <literal>acl_class</literal> tables. It has two properties which define the SQL needed | ||||||
|         <literal>classIdentityQuery</literal> and <literal>sidIdentityQuery</literal>. Both of these |             to retrieve these values <literal>classIdentityQuery</literal> and | ||||||
|       default to <literal>call identity()</literal></para> |             <literal>sidIdentityQuery</literal>. Both of these default to <literal>call | ||||||
|  |             identity()</literal></para> | ||||||
|         <section> |         <section> | ||||||
|             <title>Hypersonic SQL</title> |             <title>Hypersonic SQL</title> | ||||||
|       <para>The default schema works with the embedded HSQLDB database that is used in unit tests |             <para>The default schema works with the embedded HSQLDB database that is used in unit | ||||||
|         within the |                 tests within the | ||||||
|                 framework.<programlisting xml:id="dbschema-acl-hsql"> |                 framework.<programlisting xml:id="dbschema-acl-hsql"> | ||||||
| create table acl_sid ( | create table acl_sid ( | ||||||
|   id bigint generated by default as identity(start with 100) not null primary key, |   id bigint generated by default as identity(start with 100) not null primary key, | ||||||
|  | @ -168,11 +171,11 @@ create table acl_entry( | ||||||
|   constraint foreign_fk_4 foreign key(acl_object_identity) |   constraint foreign_fk_4 foreign key(acl_object_identity) | ||||||
|       references acl_object_identity(id), |       references acl_object_identity(id), | ||||||
|   constraint foreign_fk_5 foreign key(sid) references acl_sid(id)); |   constraint foreign_fk_5 foreign key(sid) references acl_sid(id)); | ||||||
| </programlisting> | </programlisting> </para> | ||||||
|         </para> |  | ||||||
|                 <para>You will have to set the <literal>classIdentityQuery</literal> and |                 <para>You will have to set the <literal>classIdentityQuery</literal> and | ||||||
|                     <literal>sidIdentityQuery</literal> properties of |                     <literal>sidIdentityQuery</literal> properties of | ||||||
|             <classname>JdbcMutableAclService</classname> to the following values, respectively: <itemizedlist> |                     <classname>JdbcMutableAclService</classname> to the following values, | ||||||
|  |                     respectively: <itemizedlist> | ||||||
|                     <listitem> |                     <listitem> | ||||||
|                         <para><literal>select currval(pg_get_serial_sequence('acl_class', |                         <para><literal>select currval(pg_get_serial_sequence('acl_class', | ||||||
|                             'id'))</literal></para> |                             'id'))</literal></para> | ||||||
|  |  | ||||||
|  | @ -4,37 +4,37 @@ | ||||||
|     <info> |     <info> | ||||||
|         <title>The Security Namespace</title> |         <title>The Security Namespace</title> | ||||||
|     </info> |     </info> | ||||||
|   <para> This appendix provides a reference to the elements available in the security namespace and |     <para> This appendix provides a reference to the elements available in the security namespace | ||||||
|     information on the underlying beans they create (a knowledge of the individual classes and how |         and information on the underlying beans they create (a knowledge of the individual classes | ||||||
|     they work together is assumed - you can find more information in the project Javadoc and |         and how they work together is assumed - you can find more information in the project Javadoc | ||||||
|     elsewhere in this document). If you haven't used the namespace before, please read the <link |         and elsewhere in this document). If you haven't used the namespace before, please read the | ||||||
|       xlink:href="#ns-config">introductory chapter</link> on namespace configuration, as this is |         <link xlink:href="#ns-config">introductory chapter</link> on namespace configuration, as | ||||||
|     intended as a supplement to the information there. Using a good quality XML editor while editing |         this is intended as a supplement to the information there. Using a good quality XML editor | ||||||
|     a configuration based on the schema is recommended as this will provide contextual information |         while editing a configuration based on the schema is recommended as this will provide | ||||||
|     on which elements and attributes are available as well as comments explaining their purpose. The |         contextual information on which elements and attributes are available as well as comments | ||||||
|     namespace is written in <link xlink:href="http://www.relaxng.org/">RELAX NG</link> Compact |         explaining their purpose. The namespace is written in <link | ||||||
|     format and later converted into an XSD schema. If you are familiar with this format, you may |         xlink:href="http://www.relaxng.org/">RELAX NG</link> Compact format and later converted into | ||||||
|     wish to examine the <link |         an XSD schema. If you are familiar with this format, you may wish to examine the <link | ||||||
|         xlink:href="https://src.springsource.org/svn/spring-security/trunk/config/src/main/resources/org/springframework/security/config/spring-security-3.0.rnc" |         xlink:href="https://src.springsource.org/svn/spring-security/trunk/config/src/main/resources/org/springframework/security/config/spring-security-3.0.rnc" | ||||||
|         >schema file</link> directly.</para> |         >schema file</link> directly.</para> | ||||||
|     <section xml:id="nsa-http"> |     <section xml:id="nsa-http"> | ||||||
|         <title>Web Application Security - the <literal><http></literal> Element</title> |         <title>Web Application Security - the <literal><http></literal> Element</title> | ||||||
|     <para> The <literal><http></literal> element encapsulates the security configuration for |         <para> The <literal><http></literal> element encapsulates the security configuration | ||||||
|       the web layer of your application. It creates a <classname>FilterChainProxy</classname> bean |             for the web layer of your application. It creates a | ||||||
|       named "springSecurityFilterChain" which maintains the stack of security filters which make up |             <classname>FilterChainProxy</classname> bean named "springSecurityFilterChain" which | ||||||
|       the web security configuration <footnote> |             maintains the stack of security filters which make up the web security configuration <footnote> | ||||||
|         <para>See the <link xlink:href="#ns-web-xml"> introductory chapter</link> for how to set up |             <para>See the <link xlink:href="#ns-web-xml"> introductory chapter</link> for how to set | ||||||
|           the mapping from your <literal>web.xml</literal></para> |                 up the mapping from your <literal>web.xml</literal></para> | ||||||
|             </footnote>. Some core filters are always created and others will be added to the stack |             </footnote>. Some core filters are always created and others will be added to the stack | ||||||
|       depending on the attributes child elements which are present. The positions of the standard |             depending on the attributes child elements which are present. The positions of the | ||||||
|       filters are fixed (see <link xlink:href="#filter-stack">the filter order table</link> in the |             standard filters are fixed (see <link xlink:href="#filter-stack">the filter order | ||||||
|       namespace introduction), removing a common source of errors with previous versions of the |             table</link> in the namespace introduction), removing a common source of errors with | ||||||
|       framework when users had to configure the filter chain explicitly in |             previous versions of the framework when users had to configure the filter chain | ||||||
|         the<classname>FilterChainProxy</classname> bean. You can, of course, still do this if you |             explicitly in the<classname>FilterChainProxy</classname> bean. You can, of course, still | ||||||
|       need full control of the configuration. </para> |             do this if you need full control of the configuration. </para> | ||||||
|         <para> All filters which require a reference to the |         <para> All filters which require a reference to the | ||||||
|         <interfacename>AuthenticationManager</interfacename> will be automatically injected with the |             <interfacename>AuthenticationManager</interfacename> will be automatically injected with | ||||||
|       internal instance created by the namespace configuration (see the <link |             the internal instance created by the namespace configuration (see the <link | ||||||
|             xlink:href="#ns-auth-manager"> introductory chapter</link> for more on the |             xlink:href="#ns-auth-manager"> introductory chapter</link> for more on the | ||||||
|             <interfacename>AuthenticationManager</interfacename>). </para> |             <interfacename>AuthenticationManager</interfacename>). </para> | ||||||
|         <para> The <literal><http></literal> namespace block always creates an |         <para> The <literal><http></literal> namespace block always creates an | ||||||
|  | @ -48,48 +48,53 @@ | ||||||
|                 properties on the core filters. </para> |                 properties on the core filters. </para> | ||||||
|             <section xml:id="nsa-servlet-api-provision"> |             <section xml:id="nsa-servlet-api-provision"> | ||||||
|                 <title><literal>servlet-api-provision</literal></title> |                 <title><literal>servlet-api-provision</literal></title> | ||||||
|         <para> Provides versions of <literal>HttpServletRequest</literal> security methods such as |                 <para> Provides versions of <literal>HttpServletRequest</literal> security methods | ||||||
|             <literal>isUserInRole()</literal> and <literal>getPrincipal()</literal> which are |                     such as <literal>isUserInRole()</literal> and <literal>getPrincipal()</literal> | ||||||
|           implemented by adding a <classname>SecurityContextHolderAwareRequestFilter</classname> |                     which are implemented by adding a | ||||||
|           bean to the stack. Defaults to "true". </para> |                     <classname>SecurityContextHolderAwareRequestFilter</classname> bean to the | ||||||
|  |                     stack. Defaults to "true". </para> | ||||||
|             </section> |             </section> | ||||||
|             <section xml:id="nsa-path-type"> |             <section xml:id="nsa-path-type"> | ||||||
|         <title><literal>path-type</literal></title> |                 <title><literal>request-matcher</literal></title> | ||||||
|         <para> Controls whether URL patterns are interpreted as ant paths (the default) or regular |                 <para> Defines the <interfacename>RequestMatcher</interfacename> strategy used in | ||||||
|           expressions. In practice this sets a particular <interfacename>UrlMatcher</interfacename> |                     the <classname>FilterChainProxy</classname> and the beans created by the | ||||||
|           instance on the <classname>FilterChainProxy</classname>. </para> |                     <literal>intercept-url</literal> to match incoming requests. Options are | ||||||
|       </section> |                     currently <literal>ant</literal>, <literal>regex</literal> and | ||||||
|       <section xml:id="nsa-lowercase-comparisons"> |                     <literal>ciRegex</literal>, for ant, regular-expression and case-insensitive | ||||||
|         <title><literal>lowercase-comparisons</literal></title> |                     regular-expression repsectively. A separate instance is created for each | ||||||
|         <para> Whether test URLs should be converted to lower case prior to comparing with defined |                     <literal>intercept-url</literal> element using its <literal>pattern</literal> | ||||||
|           path patterns. If unspecified, defaults to "true" </para> |                     and <literal>method</literal> attributes (see below). Ant paths are matched | ||||||
|  |                     using an <classname>AntPathRequestMatcher</classname> and regular expressions | ||||||
|  |                     are matched using a <classname>RegexRequestMatcher</classname>. See the Javadoc | ||||||
|  |                     for these classes for more details. Ant paths are the default strategy.</para> | ||||||
|             </section> |             </section> | ||||||
|             <section xml:id="nsa-realm"> |             <section xml:id="nsa-realm"> | ||||||
|                 <title><literal>realm</literal></title> |                 <title><literal>realm</literal></title> | ||||||
|         <para> Sets the realm name used for basic authentication (if enabled). Corresponds to the |                 <para> Sets the realm name used for basic authentication (if enabled). Corresponds | ||||||
|             <literal>realmName</literal> property on |                     to the <literal>realmName</literal> property on | ||||||
|                     <classname>BasicAuthenticationEntryPoint</classname>. </para> |                     <classname>BasicAuthenticationEntryPoint</classname>. </para> | ||||||
|             </section> |             </section> | ||||||
|             <section xml:id="nsa-entry-point-ref"> |             <section xml:id="nsa-entry-point-ref"> | ||||||
|                 <title><literal>entry-point-ref</literal></title> |                 <title><literal>entry-point-ref</literal></title> | ||||||
|         <para> Normally the <interfacename>AuthenticationEntryPoint</interfacename> used will be set |                 <para> Normally the <interfacename>AuthenticationEntryPoint</interfacename> used | ||||||
|           depending on which authentication mechanisms have been configured. This attribute allows |                     will be set depending on which authentication mechanisms have been configured. | ||||||
|           this behaviour to be overridden by defining a customized |                     This attribute allows this behaviour to be overridden by defining a customized | ||||||
|             <interfacename>AuthenticationEntryPoint</interfacename> bean which will start the |                     <interfacename>AuthenticationEntryPoint</interfacename> bean which will start | ||||||
|           authentication process. </para> |                     the authentication process. </para> | ||||||
|             </section> |             </section> | ||||||
|             <section xml:id="nsa-access-decision-manager-ref"> |             <section xml:id="nsa-access-decision-manager-ref"> | ||||||
|                 <title><literal>access-decision-manager-ref</literal></title> |                 <title><literal>access-decision-manager-ref</literal></title> | ||||||
|                 <para> Optional attribute specifying the ID of the |                 <para> Optional attribute specifying the ID of the | ||||||
|             <interfacename>AccessDecisionManager</interfacename> implementation which should be used |                     <interfacename>AccessDecisionManager</interfacename> implementation which should | ||||||
|           for authorizing HTTP requests. By default an <classname>AffirmativeBased</classname> |                     be used for authorizing HTTP requests. By default an | ||||||
|           implementation is used for with a <classname>RoleVoter</classname> and an |                     <classname>AffirmativeBased</classname> implementation is used for with a | ||||||
|  |                     <classname>RoleVoter</classname> and an | ||||||
|                     <classname>AuthenticatedVoter</classname>. </para> |                     <classname>AuthenticatedVoter</classname>. </para> | ||||||
|             </section> |             </section> | ||||||
|             <section xml:id="nsa-access-denied-page"> |             <section xml:id="nsa-access-denied-page"> | ||||||
|                 <title><literal>access-denied-page</literal></title> |                 <title><literal>access-denied-page</literal></title> | ||||||
|         <para> Deprecated in favour of the <literal>access-denied-handler</literal> child element. |                 <para> Deprecated in favour of the <literal>access-denied-handler</literal> child | ||||||
|         </para> |                     element. </para> | ||||||
|             </section> |             </section> | ||||||
|             <section xml:id="nsa-once-per-request"> |             <section xml:id="nsa-once-per-request"> | ||||||
|                 <title><literal>once-per-request</literal></title> |                 <title><literal>once-per-request</literal></title> | ||||||
|  | @ -98,17 +103,18 @@ | ||||||
|             </section> |             </section> | ||||||
|             <section xml:id="create-session"> |             <section xml:id="create-session"> | ||||||
|                 <title><literal>create-session</literal></title> |                 <title><literal>create-session</literal></title> | ||||||
|         <para> Controls the eagerness with which an HTTP session is created. If not set, defaults to |                 <para> Controls the eagerness with which an HTTP session is created. If not set, | ||||||
|           "ifRequired". Other options are "always" and "never". The setting of this attribute affect |                     defaults to "ifRequired". Other options are "always" and "never". The setting of | ||||||
|           the <literal>allowSessionCreation</literal> and |                     this attribute affect the <literal>allowSessionCreation</literal> and | ||||||
|                     <literal>forceEagerSessionCreation</literal> properties of |                     <literal>forceEagerSessionCreation</literal> properties of | ||||||
|                     <classname>HttpSessionContextIntegrationFilter</classname>. |                     <classname>HttpSessionContextIntegrationFilter</classname>. | ||||||
|             <literal>allowSessionCreation</literal> will always be true unless this attribute is set |                     <literal>allowSessionCreation</literal> will always be true unless this | ||||||
|           to "never". <literal>forceEagerSessionCreation</literal> is "false" unless it is set to |                     attribute is set to "never". <literal>forceEagerSessionCreation</literal> is | ||||||
|           "always". So the default configuration allows session creation but does not force it. The |                     "false" unless it is set to "always". So the default configuration allows | ||||||
|           exception is if concurrent session control is enabled, when |                     session creation but does not force it. The exception is if concurrent session | ||||||
|             <literal>forceEagerSessionCreation</literal> will be set to true, regardless of what the |                     control is enabled, when <literal>forceEagerSessionCreation</literal> will be | ||||||
|           setting is here. Using "never" would then cause an exception during the initialization of |                     set to true, regardless of what the setting is here. Using "never" would then | ||||||
|  |                     cause an exception during the initialization of | ||||||
|                     <classname>HttpSessionContextIntegrationFilter</classname>. </para> |                     <classname>HttpSessionContextIntegrationFilter</classname>. </para> | ||||||
|             </section> |             </section> | ||||||
|         </section> |         </section> | ||||||
|  | @ -117,89 +123,93 @@ | ||||||
|             <para> This element allows you to set the <literal>errorPage</literal> property for the |             <para> This element allows you to set the <literal>errorPage</literal> property for the | ||||||
|                 default <interfacename>AccessDeniedHandler</interfacename> used by the |                 default <interfacename>AccessDeniedHandler</interfacename> used by the | ||||||
|                 <classname>ExceptionTranslationFilter</classname>, (using the |                 <classname>ExceptionTranslationFilter</classname>, (using the | ||||||
|           <literal>error-page</literal> attribute, or to supply your own implementation using the |                 <literal>error-page</literal> attribute, or to supply your own implementation using | ||||||
|           <literal>ref</literal> attribute. This is discussed in more detail in the section on <link |                 the <literal>ref</literal> attribute. This is discussed in more detail in the | ||||||
|           xlink:href="#access-denied-handler">the |                 section on <link xlink:href="#access-denied-handler">the | ||||||
|                 <classname>ExceptionTranslationFilter</classname></link>.</para> |                 <classname>ExceptionTranslationFilter</classname></link>.</para> | ||||||
|         </section> |         </section> | ||||||
|         <section> |         <section> | ||||||
|             <title>The <literal><intercept-url></literal> Element</title> |             <title>The <literal><intercept-url></literal> Element</title> | ||||||
|             <para> This element is used to define the set of URL patterns that the application is |             <para> This element is used to define the set of URL patterns that the application is | ||||||
|         interested in and to configure how they should be handled. It is used to construct the |                 interested in and to configure how they should be handled. It is used to construct | ||||||
|           <interfacename>FilterInvocationSecurityMetadataSource</interfacename> used by the |                 the <interfacename>FilterInvocationSecurityMetadataSource</interfacename> used by | ||||||
|           <classname>FilterSecurityInterceptor</classname> and to exclude particular patterns from |                 the <classname>FilterSecurityInterceptor</classname> and to exclude particular | ||||||
|         the filter chain entirely (by setting the attribute <literal>filters="none"</literal>). It |                 patterns from the filter chain entirely (by setting the attribute | ||||||
|         is also responsible for configuring a <classname>ChannelAuthenticationFilter</classname> if |                 <literal>filters="none"</literal>). It is also responsible for configuring a | ||||||
|         particular URLs need to be accessed by HTTPS, for example. When matching the specified |                 <classname>ChannelAuthenticationFilter</classname> if particular URLs need to be | ||||||
|         patterns against an incoming request, the matching is done in the order in which the |                 accessed by HTTPS, for example. When matching the specified patterns against an | ||||||
|         elements are declared. So the most specific matches patterns should come first and the most |                 incoming request, the matching is done in the order in which the elements are | ||||||
|  |                 declared. So the most specific matches patterns should come first and the most | ||||||
|                 general should come last.</para> |                 general should come last.</para> | ||||||
|             <section xml:id="nsa-pattern"> |             <section xml:id="nsa-pattern"> | ||||||
|                 <title><literal>pattern</literal></title> |                 <title><literal>pattern</literal></title> | ||||||
|                 <para> The pattern which defines the URL path. The content will depend on the |                 <para> The pattern which defines the URL path. The content will depend on the | ||||||
|             <literal>path-type</literal> attribute from the containing http element, so will default |                     <literal>path-type</literal> attribute from the containing http element, so will | ||||||
|           to ant path syntax. </para> |                     default to ant path syntax. </para> | ||||||
|             </section> |             </section> | ||||||
|             <section xml:id="nsa-method"> |             <section xml:id="nsa-method"> | ||||||
|                 <title><literal>method</literal></title> |                 <title><literal>method</literal></title> | ||||||
|         <para> The HTTP Method which will be used in combination with the pattern to match an |                 <para> The HTTP Method which will be used in combination with the pattern to match | ||||||
|           incoming request. If omitted, any method will match. If an identical pattern is specified |                     an incoming request. If omitted, any method will match. If an identical pattern | ||||||
|           with and without a method, the method-specific match will take precedence.</para> |                     is specified with and without a method, the method-specific match will take | ||||||
|  |                     precedence.</para> | ||||||
|             </section> |             </section> | ||||||
|             <section xml:id="nsa-access"> |             <section xml:id="nsa-access"> | ||||||
|                 <title><literal>access</literal></title> |                 <title><literal>access</literal></title> | ||||||
|                 <para> Lists the access attributes which will be stored in the |                 <para> Lists the access attributes which will be stored in the | ||||||
|             <interfacename>FilterInvocationSecurityMetadataSource</interfacename> for the defined URL |                     <interfacename>FilterInvocationSecurityMetadataSource</interfacename> for the | ||||||
|           pattern/method combination. This should be a comma-separated list of the security |                     defined URL pattern/method combination. This should be a comma-separated list of | ||||||
|           configuration attributes (such as role names). </para> |                     the security configuration attributes (such as role names). </para> | ||||||
|             </section> |             </section> | ||||||
|             <section xml:id="nsa-requires-channel"> |             <section xml:id="nsa-requires-channel"> | ||||||
|                 <title><literal>requires-channel</literal></title> |                 <title><literal>requires-channel</literal></title> | ||||||
|         <para> Can be <quote>http</quote> or <quote>https</quote> depending on whether a particular |                 <para> Can be <quote>http</quote> or <quote>https</quote> depending on whether a | ||||||
|           URL pattern should be accessed over HTTP or HTTPS respectively. Alternatively the value |                     particular URL pattern should be accessed over HTTP or HTTPS respectively. | ||||||
|             <quote>any</quote> can be used when there is no preference. If this attribute is present |                     Alternatively the value <quote>any</quote> can be used when there is no | ||||||
|           on any <literal><intercept-url></literal> element, then a |                     preference. If this attribute is present on any | ||||||
|             <classname>ChannelAuthenticationFilter</classname> will be added to the filter stack and |                     <literal><intercept-url></literal> element, then a | ||||||
|           its additional dependencies added to the application |                     <classname>ChannelAuthenticationFilter</classname> will be added to the filter | ||||||
|  |                     stack and its additional dependencies added to the application | ||||||
|                     context.<!--See the chapter on <link |                     context.<!--See the chapter on <link | ||||||
|             xlink:href="#channel-security-config">channel security</link> for an example |             xlink:href="#channel-security-config">channel security</link> for an example | ||||||
|           configuration using traditional beans. --></para> |           configuration using traditional beans. --></para> | ||||||
|         <para> If a <literal><port-mappings></literal> configuration is added, this will be |                 <para> If a <literal><port-mappings></literal> configuration is added, this | ||||||
|           used to by the <classname>SecureChannelProcessor</classname> and |                     will be used to by the <classname>SecureChannelProcessor</classname> and | ||||||
|             <classname>InsecureChannelProcessor</classname> beans to determine the ports used for |                     <classname>InsecureChannelProcessor</classname> beans to determine the ports | ||||||
|           redirecting to HTTP/HTTPS. </para> |                     used for redirecting to HTTP/HTTPS. </para> | ||||||
|             </section> |             </section> | ||||||
|             <section> |             <section> | ||||||
|                 <title><literal>filters</literal></title> |                 <title><literal>filters</literal></title> | ||||||
|         <para>Can only take the value <quote>none</quote>. This will cause any matching request to |                 <para>Can only take the value <quote>none</quote>. This will cause any matching | ||||||
|           bypass the Spring Security filter chain entirely. None of the rest of the |                     request to bypass the Spring Security filter chain entirely. None of the rest of | ||||||
|             <literal><http></literal> configuration will have any effect on the request and there |                     the <literal><http></literal> configuration will have any effect on the | ||||||
|           will be no security context available for its duration. Access to secured methods during |                     request and there will be no security context available for its duration. Access | ||||||
|           the request will fail.</para> |                     to secured methods during the request will fail.</para> | ||||||
|             </section> |             </section> | ||||||
|         </section> |         </section> | ||||||
|         <section> |         <section> | ||||||
|             <title>The <literal><port-mappings></literal> Element</title> |             <title>The <literal><port-mappings></literal> Element</title> | ||||||
|       <para> By default, an instance of <classname>PortMapperImpl</classname> will be added to the |             <para> By default, an instance of <classname>PortMapperImpl</classname> will be added to | ||||||
|         configuration for use in redirecting to secure and insecure URLs. This element can |                 the configuration for use in redirecting to secure and insecure URLs. This element | ||||||
|         optionally be used to override the default mappings which that class defines. Each child |                 can optionally be used to override the default mappings which that class defines. | ||||||
|           <literal><port-mapping></literal> element defines a pair of HTTP:HTTPS ports. The |                 Each child <literal><port-mapping></literal> element defines a pair of | ||||||
|         default mappings are 80:443 and 8080:8443. An example of overriding these can be found in |                 HTTP:HTTPS ports. The default mappings are 80:443 and 8080:8443. An example of | ||||||
|         the <link xlink:href="#ns-requires-channel">namespace introduction</link>. </para> |                 overriding these can be found in the <link xlink:href="#ns-requires-channel" | ||||||
|  |                 >namespace introduction</link>. </para> | ||||||
|         </section> |         </section> | ||||||
|         <section xml:id="nsa-form-login"> |         <section xml:id="nsa-form-login"> | ||||||
|             <title>The <literal><form-login></literal> Element</title> |             <title>The <literal><form-login></literal> Element</title> | ||||||
|             <para> Used to add an <classname>UsernamePasswordAuthenticationFilter</classname> to the |             <para> Used to add an <classname>UsernamePasswordAuthenticationFilter</classname> to the | ||||||
|                 filter stack and an <classname>LoginUrlAuthenticationEntryPoint</classname> to the |                 filter stack and an <classname>LoginUrlAuthenticationEntryPoint</classname> to the | ||||||
|         application context to provide authentication on demand. This will always take precedence |                 application context to provide authentication on demand. This will always take | ||||||
|         over other namespace-created entry points. If no attributes are supplied, a login page will |                 precedence over other namespace-created entry points. If no attributes are supplied, | ||||||
|         be generated automatically at the URL "/spring-security-login" <footnote> |                 a login page will be generated automatically at the URL "/spring-security-login" <footnote> | ||||||
|                 <para>This feature is really just provided for convenience and is not intended for |                 <para>This feature is really just provided for convenience and is not intended for | ||||||
|             production (where a view technology will have been chosen and can be used to render a |                     production (where a view technology will have been chosen and can be used to | ||||||
|             customized login page). The class |                     render a customized login page). The class | ||||||
|               <classname>DefaultLoginPageGeneratingFilter</classname> is responsible for rendering |                     <classname>DefaultLoginPageGeneratingFilter</classname> is responsible for | ||||||
|             the login page and will provide login forms for both normal form login and/or OpenID if |                     rendering the login page and will provide login forms for both normal form login | ||||||
|             required.</para> |                     and/or OpenID if required.</para> | ||||||
|                 </footnote> The behaviour can be customized using the following attributes. </para> |                 </footnote> The behaviour can be customized using the following attributes. </para> | ||||||
|             <section> |             <section> | ||||||
|                 <title><literal>login-page</literal></title> |                 <title><literal>login-page</literal></title> | ||||||
|  | @ -211,108 +221,117 @@ | ||||||
|             <section> |             <section> | ||||||
|                 <title><literal>login-processing-url</literal></title> |                 <title><literal>login-processing-url</literal></title> | ||||||
|                 <para> Maps to the <literal>filterProcessesUrl</literal> property of |                 <para> Maps to the <literal>filterProcessesUrl</literal> property of | ||||||
|             <classname>UsernamePasswordAuthenticationFilter</classname>. The default value is |                     <classname>UsernamePasswordAuthenticationFilter</classname>. The default value | ||||||
|           "/j_spring_security_check". </para> |                     is "/j_spring_security_check". </para> | ||||||
|             </section> |             </section> | ||||||
|             <section> |             <section> | ||||||
|                 <title><literal>default-target-url</literal></title> |                 <title><literal>default-target-url</literal></title> | ||||||
|                 <para>Maps to the <literal>defaultTargetUrl</literal> property of |                 <para>Maps to the <literal>defaultTargetUrl</literal> property of | ||||||
|             <classname>UsernamePasswordAuthenticationFilter</classname>. If not set, the default |                     <classname>UsernamePasswordAuthenticationFilter</classname>. If not set, the | ||||||
|           value is "/" (the application root). A user will be taken to this URL after logging in, |                     default value is "/" (the application root). A user will be taken to this URL | ||||||
|           provided they were not asked to login while attempting to access a secured resource, when |                     after logging in, provided they were not asked to login while attempting to | ||||||
|           they will be taken to the originally requested URL. </para> |                     access a secured resource, when they will be taken to the originally requested | ||||||
|  |                     URL. </para> | ||||||
|             </section> |             </section> | ||||||
|             <section> |             <section> | ||||||
|                 <title><literal>always-use-default-target</literal></title> |                 <title><literal>always-use-default-target</literal></title> | ||||||
|                 <para> If set to "true", the user will always start at the value given by |                 <para> If set to "true", the user will always start at the value given by | ||||||
|             <literal>default-target-url</literal>, regardless of how they arrived at the login page. |                     <literal>default-target-url</literal>, regardless of how they arrived at the | ||||||
|           Maps to the <literal>alwaysUseDefaultTargetUrl</literal> property of |                     login page. Maps to the <literal>alwaysUseDefaultTargetUrl</literal> property of | ||||||
|             <classname>UsernamePasswordAuthenticationFilter</classname>. Default value is "false". |                     <classname>UsernamePasswordAuthenticationFilter</classname>. Default value is | ||||||
|         </para> |                     "false". </para> | ||||||
|             </section> |             </section> | ||||||
|             <section> |             <section> | ||||||
|                 <title><literal>authentication-failure-url</literal></title> |                 <title><literal>authentication-failure-url</literal></title> | ||||||
|                 <para> Maps to the <literal>authenticationFailureUrl</literal> property of |                 <para> Maps to the <literal>authenticationFailureUrl</literal> property of | ||||||
|             <classname>UsernamePasswordAuthenticationFilter</classname>. Defines the URL the browser |                     <classname>UsernamePasswordAuthenticationFilter</classname>. Defines the URL the | ||||||
|           will be redirected to on login failure. Defaults to "/spring_security_login?login_error", |                     browser will be redirected to on login failure. Defaults to | ||||||
|           which will be automatically handled by the automatic login page generator, re-rendering |                     "/spring_security_login?login_error", which will be automatically handled by the | ||||||
|           the login page with an error message. </para> |                     automatic login page generator, re-rendering the login page with an error | ||||||
|  |                     message. </para> | ||||||
|             </section> |             </section> | ||||||
|             <section> |             <section> | ||||||
|                 <title><literal>authentication-success-handler-ref</literal></title> |                 <title><literal>authentication-success-handler-ref</literal></title> | ||||||
|         <para>This can be used as an alternative to <literal>default-target-url</literal> and |                 <para>This can be used as an alternative to <literal>default-target-url</literal> | ||||||
|             <literal>always-use-default-target</literal>, giving you full control over the |                     and <literal>always-use-default-target</literal>, giving you full control over | ||||||
|           navigation flow after a successful authentication. The value should be he name of an |                     the navigation flow after a successful authentication. The value should be he | ||||||
|             <interfacename>AuthenticationSuccessHandler</interfacename> bean in the application |                     name of an <interfacename>AuthenticationSuccessHandler</interfacename> bean in | ||||||
|           context. </para> |                     the application context. </para> | ||||||
|             </section> |             </section> | ||||||
|             <section> |             <section> | ||||||
|                 <title><literal>authentication-failure-handler-ref</literal></title> |                 <title><literal>authentication-failure-handler-ref</literal></title> | ||||||
|         <para>Can be used as an alternative to <literal>authentication-failure-url</literal>, giving |                 <para>Can be used as an alternative to | ||||||
|           you full control over the navigation flow after an authentication failure. The value |                     <literal>authentication-failure-url</literal>, giving you full control over the | ||||||
|           should be he name of an <interfacename>AuthenticationFailureHandler</interfacename> bean |                     navigation flow after an authentication failure. The value should be he name of | ||||||
|           in the application context. </para> |                     an <interfacename>AuthenticationFailureHandler</interfacename> bean in the | ||||||
|  |                     application context. </para> | ||||||
|             </section> |             </section> | ||||||
|         </section> |         </section> | ||||||
|         <section xml:id="nsa-http-basic"> |         <section xml:id="nsa-http-basic"> | ||||||
|             <title>The <literal><http-basic></literal> Element</title> |             <title>The <literal><http-basic></literal> Element</title> | ||||||
|             <para> Adds a <classname>BasicAuthenticationFilter</classname> and |             <para> Adds a <classname>BasicAuthenticationFilter</classname> and | ||||||
|           <classname>BasicAuthenticationEntryPoint</classname> to the configuration. The latter will |                 <classname>BasicAuthenticationEntryPoint</classname> to the configuration. The | ||||||
|         only be used as the configuration entry point if form-based login is not enabled. </para> |                 latter will only be used as the configuration entry point if form-based login is not | ||||||
|  |                 enabled. </para> | ||||||
|         </section> |         </section> | ||||||
|         <section xml:id="nsa-remember-me"> |         <section xml:id="nsa-remember-me"> | ||||||
|             <title>The <literal><remember-me></literal> Element</title> |             <title>The <literal><remember-me></literal> Element</title> | ||||||
|       <para> Adds the <classname>RememberMeAuthenticationFilter</classname> to the stack. This in |             <para> Adds the <classname>RememberMeAuthenticationFilter</classname> to the stack. This | ||||||
|         turn will be configured with either a <classname>TokenBasedRememberMeServices</classname>, a |                 in turn will be configured with either a | ||||||
|           <classname>PersistentTokenBasedRememberMeServices</classname> or a user-specified bean |                 <classname>TokenBasedRememberMeServices</classname>, a | ||||||
|         implementing <interfacename>RememberMeServices</interfacename> depending on the attribute |                 <classname>PersistentTokenBasedRememberMeServices</classname> or a user-specified | ||||||
|         settings. </para> |                 bean implementing <interfacename>RememberMeServices</interfacename> depending on the | ||||||
|  |                 attribute settings. </para> | ||||||
|             <section> |             <section> | ||||||
|                 <title><literal>data-source-ref</literal></title> |                 <title><literal>data-source-ref</literal></title> | ||||||
|         <para> If this is set, <classname>PersistentTokenBasedRememberMeServices</classname> will be |                 <para> If this is set, <classname>PersistentTokenBasedRememberMeServices</classname> | ||||||
|           used and configured with a <classname>JdbcTokenRepositoryImpl</classname> instance. |                     will be used and configured with a | ||||||
|         </para> |                     <classname>JdbcTokenRepositoryImpl</classname> instance. </para> | ||||||
|             </section> |             </section> | ||||||
|             <section> |             <section> | ||||||
|                 <title><literal>token-repository-ref</literal></title> |                 <title><literal>token-repository-ref</literal></title> | ||||||
|         <para> Configures a <classname>PersistentTokenBasedRememberMeServices</classname> but allows |                 <para> Configures a <classname>PersistentTokenBasedRememberMeServices</classname> | ||||||
|           the use of a custom <interfacename>PersistentTokenRepository</interfacename> bean. </para> |                     but allows the use of a custom | ||||||
|  |                     <interfacename>PersistentTokenRepository</interfacename> bean. </para> | ||||||
|             </section> |             </section> | ||||||
|             <section> |             <section> | ||||||
|                 <title><literal>services-ref</literal></title> |                 <title><literal>services-ref</literal></title> | ||||||
|         <para> Allows complete control of the <interfacename>RememberMeServices</interfacename> |                 <para> Allows complete control of the | ||||||
|           implementation that will be used by the filter. The value should be the Id of a bean in |                     <interfacename>RememberMeServices</interfacename> implementation that will be | ||||||
|           the application context which implements this interface. </para> |                     used by the filter. The value should be the Id of a bean in the application | ||||||
|  |                     context which implements this interface. </para> | ||||||
|             </section> |             </section> | ||||||
|             <section> |             <section> | ||||||
|                 <title><literal>token-repository-ref</literal></title> |                 <title><literal>token-repository-ref</literal></title> | ||||||
|         <para> Configures a <classname>PersistentTokenBasedRememberMeServices</classname> but allows |                 <para> Configures a <classname>PersistentTokenBasedRememberMeServices</classname> | ||||||
|           the use of a custom <interfacename>PersistentTokenRepository</interfacename> bean. </para> |                     but allows the use of a custom | ||||||
|  |                     <interfacename>PersistentTokenRepository</interfacename> bean. </para> | ||||||
|             </section> |             </section> | ||||||
|             <section> |             <section> | ||||||
|                 <title>The <literal>key</literal> Attribute</title> |                 <title>The <literal>key</literal> Attribute</title> | ||||||
|         <para>Maps to the "key" property of <classname>AbstractRememberMeServices</classname>. |                 <para>Maps to the "key" property of | ||||||
|           Should be set to a unique value to ensure that remember-me cookies are only valid within |                     <classname>AbstractRememberMeServices</classname>. Should be set to a unique | ||||||
|           the one application <footnote> |                     value to ensure that remember-me cookies are only valid within the one | ||||||
|  |                     application <footnote> | ||||||
|                     <para>This doesn't affect the use of |                     <para>This doesn't affect the use of | ||||||
|                 <classname>PersistentTokenBasedRememberMeServices</classname>, where the tokens are |                         <classname>PersistentTokenBasedRememberMeServices</classname>, where the | ||||||
|               stored on the server side.</para> |                         tokens are stored on the server side.</para> | ||||||
|                     </footnote>. </para> |                     </footnote>. </para> | ||||||
|             </section> |             </section> | ||||||
|             <section> |             <section> | ||||||
|                 <title><literal>token-validity-seconds</literal></title> |                 <title><literal>token-validity-seconds</literal></title> | ||||||
|                 <para> Maps to the <literal>tokenValiditySeconds</literal> property of |                 <para> Maps to the <literal>tokenValiditySeconds</literal> property of | ||||||
|             <classname>AbstractRememberMeServices</classname>. Specifies the period in seconds for |                     <classname>AbstractRememberMeServices</classname>. Specifies the period in | ||||||
|           which the remember-me cookie should be valid. By default it will be valid for 14 days. |                     seconds for which the remember-me cookie should be valid. By default it will be | ||||||
|         </para> |                     valid for 14 days. </para> | ||||||
|             </section> |             </section> | ||||||
|             <section> |             <section> | ||||||
|                 <title><literal>user-service-ref</literal></title> |                 <title><literal>user-service-ref</literal></title> | ||||||
|                 <para> The remember-me services implementations require access to a |                 <para> The remember-me services implementations require access to a | ||||||
|             <interfacename>UserDetailsService</interfacename>, so there has to be one defined in the |                     <interfacename>UserDetailsService</interfacename>, so there has to be one | ||||||
|           application context. If there is only one, it will be selected and used automatically by |                     defined in the application context. If there is only one, it will be selected | ||||||
|           the namespace configuration. If there are multiple instances, you can specify a bean Id |                     and used automatically by the namespace configuration. If there are multiple | ||||||
|           explicitly using this attribute. </para> |                     instances, you can specify a bean Id explicitly using this attribute. </para> | ||||||
|             </section> |             </section> | ||||||
|         </section> |         </section> | ||||||
|         <section xml:id="nsa-session-mgmt"> |         <section xml:id="nsa-session-mgmt"> | ||||||
|  | @ -321,26 +340,29 @@ | ||||||
|                 <classname>SessionManagementFilter</classname> to the filter stack.</para> |                 <classname>SessionManagementFilter</classname> to the filter stack.</para> | ||||||
|             <section xml:id="session-fixation-protection"> |             <section xml:id="session-fixation-protection"> | ||||||
|                 <title><literal>session-fixation-protection</literal></title> |                 <title><literal>session-fixation-protection</literal></title> | ||||||
|         <para> Indicates whether an existing session should be invalidated when a user authenticates |                 <para> Indicates whether an existing session should be invalidated when a user | ||||||
|           and a new session started. If set to "none" no change will be made. "newSession" will |                     authenticates and a new session started. If set to "none" no change will be | ||||||
|           create a new empty session. "migrateSession" will create a new session and copy the |                     made. "newSession" will create a new empty session. "migrateSession" will create | ||||||
|           session attributes to the new session. Defaults to "migrateSession".</para> |                     a new session and copy the session attributes to the new session. Defaults to | ||||||
|  |                     "migrateSession".</para> | ||||||
|                 <para> If session fixation protection is enabled, the |                 <para> If session fixation protection is enabled, the | ||||||
|                     <classname>SessionManagementFilter</classname> is inected with a appropriately |                     <classname>SessionManagementFilter</classname> is inected with a appropriately | ||||||
|           configured <classname>DefaultSessionAuthenticationStrategy</classname>. See the Javadoc |                     configured <classname>DefaultSessionAuthenticationStrategy</classname>. See the | ||||||
|           for this class for more details. </para> |                     Javadoc for this class for more details. </para> | ||||||
|             </section> |             </section> | ||||||
|         </section> |         </section> | ||||||
|         <section xml:id="nsa-concurrent-session-control"> |         <section xml:id="nsa-concurrent-session-control"> | ||||||
|             <title>The <literal><concurrency-control></literal> Element</title> |             <title>The <literal><concurrency-control></literal> Element</title> | ||||||
|       <para> Adds support for concurrent session control, allowing limits to be placed on the number |             <para> Adds support for concurrent session control, allowing limits to be placed on the | ||||||
|         of active sessions a user can have. A <classname>ConcurrentSessionFilter</classname> will be |                 number of active sessions a user can have. A | ||||||
|         created, and a <classname>ConcurrentSessionControlStrategy</classname> will be used with the |                 <classname>ConcurrentSessionFilter</classname> will be created, and a | ||||||
|           <classname>SessionManagementFilter</classname>. If a <literal>form-login</literal> element |                 <classname>ConcurrentSessionControlStrategy</classname> will be used with the | ||||||
|         has been declared, the strategy object will also be injected into the created authentication |                 <classname>SessionManagementFilter</classname>. If a <literal>form-login</literal> | ||||||
|         filter. An instance of <interfacename>SessionRegistry</interfacename> (a |                 element has been declared, the strategy object will also be injected into the | ||||||
|           <classname>SessionRegistryImpl</classname> instance unless the user wishes to use a custom |                 created authentication filter. An instance of | ||||||
|         bean) will be created for use by the strategy.</para> |                 <interfacename>SessionRegistry</interfacename> (a | ||||||
|  |                 <classname>SessionRegistryImpl</classname> instance unless the user wishes to use a | ||||||
|  |                 custom bean) will be created for use by the strategy.</para> | ||||||
|             <section> |             <section> | ||||||
|                 <title>The <literal>max-sessions</literal> attribute</title> |                 <title>The <literal>max-sessions</literal> attribute</title> | ||||||
|                 <para>Maps to the <literal>maximumSessions</literal> property of |                 <para>Maps to the <literal>maximumSessions</literal> property of | ||||||
|  | @ -348,87 +370,92 @@ | ||||||
|             </section> |             </section> | ||||||
|             <section> |             <section> | ||||||
|                 <title>The <literal>expired-url</literal> attribute</title> |                 <title>The <literal>expired-url</literal> attribute</title> | ||||||
|         <para> The URL a user will be redirected to if they attempt to use a session which has been |                 <para> The URL a user will be redirected to if they attempt to use a session which | ||||||
|           "expired" by the concurrent session controller because the user has exceeded the number of |                     has been "expired" by the concurrent session controller because the user has | ||||||
|           allowed sessions and has logged in again elsewhere. Should be set unless |                     exceeded the number of allowed sessions and has logged in again elsewhere. | ||||||
|             <literal>exception-if-maximum-exceeded</literal> is set. If no value is supplied, an |                     Should be set unless <literal>exception-if-maximum-exceeded</literal> is set. If | ||||||
|           expiry message will just be written directly back to the response. </para> |                     no value is supplied, an expiry message will just be written directly back to | ||||||
|  |                     the response. </para> | ||||||
|             </section> |             </section> | ||||||
|             <section> |             <section> | ||||||
|                 <title>The <literal>error-if-maximum-exceeded</literal> attribute</title> |                 <title>The <literal>error-if-maximum-exceeded</literal> attribute</title> | ||||||
|         <para>If set to "true" a <exceptionname>SessionAuthenticationException</exceptionname> will |                 <para>If set to "true" a | ||||||
|           be raised when a user attempts to exceed the maximum allowed number of sessions. The |                     <exceptionname>SessionAuthenticationException</exceptionname> will be raised | ||||||
|  |                     when a user attempts to exceed the maximum allowed number of sessions. The | ||||||
|                     default behaviour is to expire the original session. </para> |                     default behaviour is to expire the original session. </para> | ||||||
|             </section> |             </section> | ||||||
|             <section> |             <section> | ||||||
|                 <title>The <literal>session-registry-alias</literal> and |                 <title>The <literal>session-registry-alias</literal> and | ||||||
|                     <literal>session-registry-ref</literal> attributes</title> |                     <literal>session-registry-ref</literal> attributes</title> | ||||||
|                 <para> The user can supply their own <interfacename>SessionRegistry</interfacename> |                 <para> The user can supply their own <interfacename>SessionRegistry</interfacename> | ||||||
|           implementation using the <literal>session-registry-ref</literal> attribute. The other |                     implementation using the <literal>session-registry-ref</literal> attribute. The | ||||||
|           concurrent session control beans will be wired up to use it. </para> |                     other concurrent session control beans will be wired up to use it. </para> | ||||||
|         <para> It can also be useful to have a reference to the internal session registry for use in |                 <para> It can also be useful to have a reference to the internal session registry | ||||||
|           your own beans or an admin interface. You can expose the interal bean using the |                     for use in your own beans or an admin interface. You can expose the interal bean | ||||||
|             <literal>session-registry-alias</literal> attribute, giving it a name that you can use |                     using the <literal>session-registry-alias</literal> attribute, giving it a name | ||||||
|           elsewhere in your configuration. </para> |                     that you can use elsewhere in your configuration. </para> | ||||||
|             </section> |             </section> | ||||||
|         </section> |         </section> | ||||||
|         <section xml:id="nsa-anonymous"> |         <section xml:id="nsa-anonymous"> | ||||||
|             <title>The <literal><anonymous></literal> Element</title> |             <title>The <literal><anonymous></literal> Element</title> | ||||||
|             <para> Adds an <classname>AnonymousAuthenticationFilter</classname> to the stack and an |             <para> Adds an <classname>AnonymousAuthenticationFilter</classname> to the stack and an | ||||||
|           <classname>AnonymousAuthenticationProvider</classname>. Required if you are using the |                 <classname>AnonymousAuthenticationProvider</classname>. Required if you are using | ||||||
|           <literal>IS_AUTHENTICATED_ANONYMOUSLY</literal> attribute. </para> |                 the <literal>IS_AUTHENTICATED_ANONYMOUSLY</literal> attribute. </para> | ||||||
|         </section> |         </section> | ||||||
|         <section xml:id="nsa-x509"> |         <section xml:id="nsa-x509"> | ||||||
|             <title>The <literal><x509></literal> Element</title> |             <title>The <literal><x509></literal> Element</title> | ||||||
|             <para> Adds support for X.509 authentication. An |             <para> Adds support for X.509 authentication. An | ||||||
|                 <classname>X509AuthenticationFilter</classname> will be added to the stack and an |                 <classname>X509AuthenticationFilter</classname> will be added to the stack and an | ||||||
|           <classname>Http403ForbiddenEntryPoint</classname> bean will be created. The latter will |                 <classname>Http403ForbiddenEntryPoint</classname> bean will be created. The latter | ||||||
|         only be used if no other authentication mechanisms are in use (it's only functionality is to |                 will only be used if no other authentication mechanisms are in use (it's only | ||||||
|         return an HTTP 403 error code). A |                 functionality is to return an HTTP 403 error code). A | ||||||
|           <classname>PreAuthenticatedAuthenticationProvider</classname> will also be created which |                 <classname>PreAuthenticatedAuthenticationProvider</classname> will also be created | ||||||
|         delegates the loading of user authorities to a |                 which delegates the loading of user authorities to a | ||||||
|                 <interfacename>UserDetailsService</interfacename>. </para> |                 <interfacename>UserDetailsService</interfacename>. </para> | ||||||
|             <section> |             <section> | ||||||
|                 <title>The <literal>subject-principal-regex</literal> attribute</title> |                 <title>The <literal>subject-principal-regex</literal> attribute</title> | ||||||
|         <para> Defines a regular expression which will be used to extract the username from the |                 <para> Defines a regular expression which will be used to extract the username from | ||||||
|           certificate (for use with the <interfacename>UserDetailsService</interfacename>). </para> |                     the certificate (for use with the | ||||||
|  |                     <interfacename>UserDetailsService</interfacename>). </para> | ||||||
|             </section> |             </section> | ||||||
|             <section> |             <section> | ||||||
|                 <title>The <literal>user-service-ref</literal> attribute</title> |                 <title>The <literal>user-service-ref</literal> attribute</title> | ||||||
|         <para> Allows a specific <interfacename>UserDetailsService</interfacename> to be used with |                 <para> Allows a specific <interfacename>UserDetailsService</interfacename> to be | ||||||
|           X.509 in the case where multiple instances are configured. If not set, an attempt will be |                     used with X.509 in the case where multiple instances are configured. If not set, | ||||||
|           made to locate a suitable instance automatically and use that. </para> |                     an attempt will be made to locate a suitable instance automatically and use | ||||||
|  |                     that. </para> | ||||||
|             </section> |             </section> | ||||||
|         </section> |         </section> | ||||||
|         <section xml:id="nsa-openid-login"> |         <section xml:id="nsa-openid-login"> | ||||||
|             <title>The <literal><openid-login></literal> Element</title> |             <title>The <literal><openid-login></literal> Element</title> | ||||||
|             <para> Similar to <literal><form-login></literal> and has the same attributes. The |             <para> Similar to <literal><form-login></literal> and has the same attributes. The | ||||||
|                 default value for <literal>login-processing-url</literal> is |                 default value for <literal>login-processing-url</literal> is | ||||||
|         "/j_spring_openid_security_check". An <classname>OpenIDAuthenticationFilter</classname> and |                 "/j_spring_openid_security_check". An | ||||||
|  |                 <classname>OpenIDAuthenticationFilter</classname> and | ||||||
|                 <classname>OpenIDAuthenticationProvider</classname> will be registered. The latter |                 <classname>OpenIDAuthenticationProvider</classname> will be registered. The latter | ||||||
|         requires a reference to a <interfacename>UserDetailsService</interfacename>. Again, this can |                 requires a reference to a <interfacename>UserDetailsService</interfacename>. Again, | ||||||
|         be specified by Id, using the <literal>user-service-ref</literal> attribute, or will be |                 this can be specified by Id, using the <literal>user-service-ref</literal> | ||||||
|         located automatically in the application context. </para> |                 attribute, or will be located automatically in the application context. </para> | ||||||
|         </section> |         </section> | ||||||
|         <section xml:id="nsa-logout"> |         <section xml:id="nsa-logout"> | ||||||
|             <title>The <literal><logout></literal> Element</title> |             <title>The <literal><logout></literal> Element</title> | ||||||
|       <para> Adds a <classname>LogoutFilter</classname> to the filter stack. This is configured with |             <para> Adds a <classname>LogoutFilter</classname> to the filter stack. This is | ||||||
|         a <classname>SecurityContextLogoutHandler</classname>. </para> |                 configured with a <classname>SecurityContextLogoutHandler</classname>. </para> | ||||||
|             <section> |             <section> | ||||||
|                 <title>The <literal>logout-url</literal> attribute</title> |                 <title>The <literal>logout-url</literal> attribute</title> | ||||||
|         <para> The URL which will cause a logout (i.e. which will be processed by the filter). |                 <para> The URL which will cause a logout (i.e. which will be processed by the | ||||||
|           Defaults to "/j_spring_security_logout". </para> |                     filter). Defaults to "/j_spring_security_logout". </para> | ||||||
|             </section> |             </section> | ||||||
|             <section> |             <section> | ||||||
|                 <title>The <literal>logout-success-url</literal> attribute</title> |                 <title>The <literal>logout-success-url</literal> attribute</title> | ||||||
|         <para> The destination URL which the user will be taken to after logging out. Defaults to |                 <para> The destination URL which the user will be taken to after logging out. | ||||||
|           "/". </para> |                     Defaults to "/". </para> | ||||||
|             </section> |             </section> | ||||||
|             <section> |             <section> | ||||||
|                 <title>The <literal>invalidate-session</literal> attribute</title> |                 <title>The <literal>invalidate-session</literal> attribute</title> | ||||||
|                 <para> Maps to the <literal>invalidateHttpSession</literal> of the |                 <para> Maps to the <literal>invalidateHttpSession</literal> of the | ||||||
|             <classname>SecurityContextLogoutHandler</classname>. Defaults to "true", so the session |                     <classname>SecurityContextLogoutHandler</classname>. Defaults to "true", so the | ||||||
|           will be invalidated on logout. </para> |                     session will be invalidated on logout. </para> | ||||||
|             </section> |             </section> | ||||||
|         </section> |         </section> | ||||||
|         <section> |         <section> | ||||||
|  | @ -436,59 +463,65 @@ | ||||||
|             <para>This element is used to add a filter to the filter chain. It doesn't create any |             <para>This element is used to add a filter to the filter chain. It doesn't create any | ||||||
|                 additional beans but is used to select a bean of type |                 additional beans but is used to select a bean of type | ||||||
|                 <interfacename>javax.servlet.Filter</interfacename> which is already defined in the |                 <interfacename>javax.servlet.Filter</interfacename> which is already defined in the | ||||||
|         appllication context and add that at a particular position in the filter chain maintained by |                 appllication context and add that at a particular position in the filter chain | ||||||
|         Spring Security. Full details can be found in the namespace chapter.</para> |                 maintained by Spring Security. Full details can be found in the namespace | ||||||
|  |                 chapter.</para> | ||||||
|         </section> |         </section> | ||||||
|     </section> |     </section> | ||||||
|     <section> |     <section> | ||||||
|         <title>Authentication Services</title> |         <title>Authentication Services</title> | ||||||
|     <para> Before Spring Security 3.0, an <interfacename>AuthenticationManager</interfacename> was |         <para> Before Spring Security 3.0, an <interfacename>AuthenticationManager</interfacename> | ||||||
|       automatically registered internally. Now you must register one explicitly using the |             was automatically registered internally. Now you must register one explicitly using the | ||||||
|             <literal><authentication-manager></literal> element. This creates an instance of |             <literal><authentication-manager></literal> element. This creates an instance of | ||||||
|       Spring Security's <classname>ProviderManager</classname> class, which needs to be configured |             Spring Security's <classname>ProviderManager</classname> class, which needs to be | ||||||
|       with a list of one or more <interfacename>AuthenticationProvider</interfacename> instances. |             configured with a list of one or more | ||||||
|       These can either be created using syntax elements provided by the namespace, or they can be |             <interfacename>AuthenticationProvider</interfacename> instances. These can either be | ||||||
|       standard bean definitions, marked for addition to the list using the |             created using syntax elements provided by the namespace, or they can be standard bean | ||||||
|  |             definitions, marked for addition to the list using the | ||||||
|             <literal>authentication-provider</literal> element. </para> |             <literal>authentication-provider</literal> element. </para> | ||||||
|         <section> |         <section> | ||||||
|             <title>The <literal><authentication-manager></literal> Element</title> |             <title>The <literal><authentication-manager></literal> Element</title> | ||||||
|             <para> Every Spring Security application which uses the namespace must have include this |             <para> Every Spring Security application which uses the namespace must have include this | ||||||
|                 element somewhere. It is responsible for registering the |                 element somewhere. It is responsible for registering the | ||||||
|                 <interfacename>AuthenticationManager</interfacename> which provides authentication |                 <interfacename>AuthenticationManager</interfacename> which provides authentication | ||||||
|         services to the application. It also allows you to define an alias name for the internal |                 services to the application. It also allows you to define an alias name for the | ||||||
|         instance for use in your own configuration. Its use is described in the  |                 internal instance for use in your own configuration. Its use is described in the | ||||||
|           <link xlink:href="#ns-auth-manager">namespace introduction</link>. All elements which create |                 <link xlink:href="#ns-auth-manager">namespace introduction</link>. All elements | ||||||
|           <interfacename>AuthenticationProvider</interfacename> instances should be children of this |                 which create <interfacename>AuthenticationProvider</interfacename> instances should | ||||||
|         element.</para> |                 be children of this element.</para> | ||||||
|             <section> |             <section> | ||||||
|                 <title>The <literal><authentication-provider></literal> Element</title> |                 <title>The <literal><authentication-provider></literal> Element</title> | ||||||
|         <para> Unless used with a <literal>ref</literal> attribute, this element is shorthand for configuring a |                 <para> Unless used with a <literal>ref</literal> attribute, this element is | ||||||
|             <link xlink:href="#core-services-dao-provider"><classname>DaoAuthenticationProvider</classname></link>. |                     shorthand for configuring a <link xlink:href="#core-services-dao-provider" | ||||||
|  |                     ><classname>DaoAuthenticationProvider</classname></link>. | ||||||
|                     <classname>DaoAuthenticationProvider</classname> loads user information from a |                     <classname>DaoAuthenticationProvider</classname> loads user information from a | ||||||
|             <interfacename>UserDetailsService</interfacename> and compares the username/password |                     <interfacename>UserDetailsService</interfacename> and compares the | ||||||
|           combination with the values supplied at login. The |                     username/password combination with the values supplied at login. The | ||||||
|             <interfacename>UserDetailsService</interfacename> instance can be defined either by |                     <interfacename>UserDetailsService</interfacename> instance can be defined either | ||||||
|           using an available namespace element (<literal>jdbc-user-service</literal> or by using the |                     by using an available namespace element (<literal>jdbc-user-service</literal> or | ||||||
|             <literal>user-service-ref</literal> attribute to point to a bean defined elsewhere in |                     by using the <literal>user-service-ref</literal> attribute to point to a bean | ||||||
|           the application context). You can find examples of these variations in the <link |                     defined elsewhere in the application context). You can find examples of these | ||||||
|             xlink:href="#ns-auth-providers">namespace introduction</link>. </para> |                     variations in the <link xlink:href="#ns-auth-providers">namespace | ||||||
|  |                     introduction</link>. </para> | ||||||
|                 <section> |                 <section> | ||||||
|                     <title>The <literal><password-encoder></literal> Element</title> |                     <title>The <literal><password-encoder></literal> Element</title> | ||||||
|           <para>Authentication providers can optionally be configured to use a password encoder as |                     <para>Authentication providers can optionally be configured to use a password | ||||||
|             described in the <link xlink:href="#ns-password-encoder">namespace introduction</link>. |                         encoder as described in the <link xlink:href="#ns-password-encoder" | ||||||
|             This will result in the bean being injected with the appropriate |                         >namespace introduction</link>. This will result in the bean being injected | ||||||
|               <interfacename>PasswordEncoder</interfacename> instance, potentially with an |                         with the appropriate <interfacename>PasswordEncoder</interfacename> | ||||||
|             accompanying <interfacename>SaltSource</interfacename> bean to provide salt values for |                         instance, potentially with an accompanying | ||||||
|  |                         <interfacename>SaltSource</interfacename> bean to provide salt values for | ||||||
|                         hashing. </para> |                         hashing. </para> | ||||||
|                 </section> |                 </section> | ||||||
|             </section> |             </section> | ||||||
|             <section> |             <section> | ||||||
|                 <title>Using <literal><authentication-provider></literal> to refer to an |                 <title>Using <literal><authentication-provider></literal> to refer to an | ||||||
|                     <interfacename>AuthenticationProvider</interfacename> Bean</title> |                     <interfacename>AuthenticationProvider</interfacename> Bean</title> | ||||||
|         <para> If you have written your own <interfacename>AuthenticationProvider</interfacename> |                 <para> If you have written your own | ||||||
|           implementation (or want to configure one of Spring Security's own implementations as a |                     <interfacename>AuthenticationProvider</interfacename> implementation (or want to | ||||||
|           traditional bean for some reason, then you can use the following syntax to add it to the |                     configure one of Spring Security's own implementations as a traditional bean for | ||||||
|           internal <classname>ProviderManager</classname>'s list: <programlisting><![CDATA[ |                     some reason, then you can use the following syntax to add it to the internal | ||||||
|  |                     <classname>ProviderManager</classname>'s list: <programlisting><![CDATA[ | ||||||
|   <security:authentication-manager> |   <security:authentication-manager> | ||||||
|     <security:authentication-provider ref="myAuthenticationProvider" /> |     <security:authentication-provider ref="myAuthenticationProvider" /> | ||||||
|   </security:authentication-manager> |   </security:authentication-manager> | ||||||
|  | @ -501,132 +534,144 @@ | ||||||
|         <title>Method Security</title> |         <title>Method Security</title> | ||||||
|         <section> |         <section> | ||||||
|             <title>The <literal><global-method-security></literal> Element</title> |             <title>The <literal><global-method-security></literal> Element</title> | ||||||
|       <para> This element is the primary means of adding support for securing methods on Spring |             <para> This element is the primary means of adding support for securing methods on | ||||||
|         Security beans. Methods can be secured by the use of annotations (defined at the interface |                 Spring Security beans. Methods can be secured by the use of annotations (defined at | ||||||
|         or class level) or by defining a set of pointcuts as child elements, using AspectJ syntax. </para> |                 the interface or class level) or by defining a set of pointcuts as child elements, | ||||||
|       <para> Method security uses the same <interfacename>AccessDecisionManager</interfacename> |                 using AspectJ syntax. </para> | ||||||
|         configuration as web security, but this can be overridden as explained above <xref |             <para> Method security uses the same | ||||||
|  |                 <interfacename>AccessDecisionManager</interfacename> configuration as web security, | ||||||
|  |                 but this can be overridden as explained above <xref | ||||||
|                 xlink:href="#nsa-access-decision-manager-ref"/>, using the same attribute. </para> |                 xlink:href="#nsa-access-decision-manager-ref"/>, using the same attribute. </para> | ||||||
|             <section> |             <section> | ||||||
|         <title>The <literal>secured-annotations</literal> and <literal>jsr250-annotations</literal> |                 <title>The <literal>secured-annotations</literal> and | ||||||
|           Attributes</title> |                     <literal>jsr250-annotations</literal> Attributes</title> | ||||||
|                 <para> Setting these to "true" will enable support for Spring Security's own |                 <para> Setting these to "true" will enable support for Spring Security's own | ||||||
|             <literal>@Secured</literal> annotations and JSR-250 annotations, respectively. They are |                     <literal>@Secured</literal> annotations and JSR-250 annotations, respectively. | ||||||
|           both disabled by default. Use of JSR-250 annotations also adds a |                     They are both disabled by default. Use of JSR-250 annotations also adds a | ||||||
|                     <classname>Jsr250Voter</classname> to the |                     <classname>Jsr250Voter</classname> to the | ||||||
|             <interfacename>AccessDecisionManager</interfacename>, so you need to make sure you do |                     <interfacename>AccessDecisionManager</interfacename>, so you need to make sure | ||||||
|           this if you are using a custom implementation and want to use these annotations. </para> |                     you do this if you are using a custom implementation and want to use these | ||||||
|  |                     annotations. </para> | ||||||
|             </section> |             </section> | ||||||
|             <section> |             <section> | ||||||
|                 <title>Securing Methods using <literal><protect-pointcut></literal></title> |                 <title>Securing Methods using <literal><protect-pointcut></literal></title> | ||||||
|         <para> Rather than defining security attributes on an individual method or class basis using |                 <para> Rather than defining security attributes on an individual method or class | ||||||
|           the <literal>@Secured</literal> annotation, you can define cross-cutting security |                     basis using the <literal>@Secured</literal> annotation, you can define | ||||||
|           constraints across whole sets of methods and interfaces in your service layer using the |                     cross-cutting security constraints across whole sets of methods and interfaces | ||||||
|             <literal><protect-pointcut></literal> element. This has two attributes: <itemizedlist> |                     in your service layer using the <literal><protect-pointcut></literal> | ||||||
|  |                     element. This has two attributes: <itemizedlist> | ||||||
|                     <listitem> |                     <listitem> | ||||||
|                         <para><literal>expression</literal> - the pointcut expression</para> |                         <para><literal>expression</literal> - the pointcut expression</para> | ||||||
|                     </listitem> |                     </listitem> | ||||||
|                     <listitem> |                     <listitem> | ||||||
|                         <para><literal>access</literal> - the security attributes which apply</para> |                         <para><literal>access</literal> - the security attributes which apply</para> | ||||||
|                     </listitem> |                     </listitem> | ||||||
|           </itemizedlist> You can find an example in the <link xlink:href="#ns-protect-pointcut" |                     </itemizedlist> You can find an example in the <link | ||||||
|             >namespace introduction</link>. </para> |                     xlink:href="#ns-protect-pointcut">namespace introduction</link>. </para> | ||||||
|             </section> |             </section> | ||||||
|             <section xml:id="nsa-custom-after-invocation"> |             <section xml:id="nsa-custom-after-invocation"> | ||||||
|                 <title>The <literal><after-invocation-provider></literal> Element</title> |                 <title>The <literal><after-invocation-provider></literal> Element</title> | ||||||
|                 <para> This element can be used to decorate an |                 <para> This element can be used to decorate an | ||||||
|                     <interfacename>AfterInvocationProvider</interfacename> for use by the security |                     <interfacename>AfterInvocationProvider</interfacename> for use by the security | ||||||
|           interceptor maintained by the <literal><global-method-security></literal> namespace. |                     interceptor maintained by the <literal><global-method-security></literal> | ||||||
|           You can define zero or more of these within the <literal>global-method-security</literal> |                     namespace. You can define zero or more of these within the | ||||||
|           element, each with a <literal>ref</literal> attribute pointing to an |                     <literal>global-method-security</literal> element, each with a | ||||||
|  |                     <literal>ref</literal> attribute pointing to an | ||||||
|                     <interfacename>AfterInvocationProvider</interfacename> bean instance within your |                     <interfacename>AfterInvocationProvider</interfacename> bean instance within your | ||||||
|                     application context. </para> |                     application context. </para> | ||||||
|             </section> |             </section> | ||||||
|         </section> |         </section> | ||||||
|         <section> |         <section> | ||||||
|             <title>LDAP Namespace Options</title> |             <title>LDAP Namespace Options</title> | ||||||
|       <para> LDAP is covered in some details in <link xlink:href="#ldap">its own chapter</link>. We |             <para> LDAP is covered in some details in <link xlink:href="#ldap">its own | ||||||
|         will expand on that here with some explanation of how the namespace options map to Spring |                 chapter</link>. We will expand on that here with some explanation of how the | ||||||
|         beans. The LDAP implementation uses Spring LDAP extensively, so some familiarity with that |                 namespace options map to Spring beans. The LDAP implementation uses Spring LDAP | ||||||
|         project's API may be useful. </para> |                 extensively, so some familiarity with that project's API may be useful. </para> | ||||||
|             <section> |             <section> | ||||||
|                 <title>Defining the LDAP Server using the <literal><ldap-server></literal> |                 <title>Defining the LDAP Server using the <literal><ldap-server></literal> | ||||||
|                     Element</title> |                     Element</title> | ||||||
|         <para> This element sets up a Spring LDAP <interfacename>ContextSource</interfacename> for |                 <para> This element sets up a Spring LDAP | ||||||
|           use by the other LDAP beans, defining the location of the LDAP server and other |                     <interfacename>ContextSource</interfacename> for use by the other LDAP beans, | ||||||
|           information (such as a username and password, if it doesn't allow anonymous access) for |                     defining the location of the LDAP server and other information (such as a | ||||||
|           connecting to it. It can also be used to create an embedded server for testing. Details of |                     username and password, if it doesn't allow anonymous access) for connecting to | ||||||
|           the syntax for both options are covered in the <link xlink:href="#ldap-server">LDAP |                     it. It can also be used to create an embedded server for testing. Details of the | ||||||
|             chapter</link>. The actual <interfacename>ContextSource</interfacename> implementation |                     syntax for both options are covered in the <link xlink:href="#ldap-server">LDAP | ||||||
|           is <classname>DefaultSpringSecurityContextSource</classname> which extends Spring LDAP's |                     chapter</link>. The actual <interfacename>ContextSource</interfacename> | ||||||
|             <classname>LdapContextSource</classname> class. The <literal>manager-dn</literal> and |                     implementation is <classname>DefaultSpringSecurityContextSource</classname> | ||||||
|             <literal>manager-password</literal> attributes map to the latter's |                     which extends Spring LDAP's <classname>LdapContextSource</classname> class. The | ||||||
|             <literal>userDn</literal> and <literal>password</literal> properties respectively. </para> |                     <literal>manager-dn</literal> and <literal>manager-password</literal> attributes | ||||||
|         <para> If you only have one server defined in your application context, the other LDAP |                     map to the latter's <literal>userDn</literal> and <literal>password</literal> | ||||||
|           namespace-defined beans will use it automatically. Otherwise, you can give the element an |                     properties respectively. </para> | ||||||
|           "id" attribute and refer to it from other namespace beans using the |                 <para> If you only have one server defined in your application context, the other | ||||||
|             <literal>server-ref</literal> attribute. This is actually the bean Id of the |                     LDAP namespace-defined beans will use it automatically. Otherwise, you can give | ||||||
|             <literal>ContextSource</literal> instance, if you want to use it in other traditional |                     the element an "id" attribute and refer to it from other namespace beans using | ||||||
|           Spring beans. </para> |                     the <literal>server-ref</literal> attribute. This is actually the bean Id of the | ||||||
|  |                     <literal>ContextSource</literal> instance, if you want to use it in other | ||||||
|  |                     traditional Spring beans. </para> | ||||||
|             </section> |             </section> | ||||||
|             <section> |             <section> | ||||||
|                 <title>The <literal><ldap-provider></literal> Element</title> |                 <title>The <literal><ldap-provider></literal> Element</title> | ||||||
|                 <para> This element is shorthand for the creation of an |                 <para> This element is shorthand for the creation of an | ||||||
|             <classname>LdapAuthenticationProvider</classname> instance. By default this will be |                     <classname>LdapAuthenticationProvider</classname> instance. By default this will | ||||||
|           configured with a <classname>BindAuthenticator</classname> instance and a |                     be configured with a <classname>BindAuthenticator</classname> instance and a | ||||||
|             <classname>DefaultAuthoritiesPopulator</classname>. As with all namespace authentication |                     <classname>DefaultAuthoritiesPopulator</classname>. As with all namespace | ||||||
|           providers, it must be included as a child of the |                     authentication providers, it must be included as a child of the | ||||||
|                     <literal>authentication-provider</literal> element.</para> |                     <literal>authentication-provider</literal> element.</para> | ||||||
|                 <section> |                 <section> | ||||||
|                     <title>The <literal>user-dn-pattern</literal> Attribute</title> |                     <title>The <literal>user-dn-pattern</literal> Attribute</title> | ||||||
|           <para> If your users are at a fixed location in the directory (i.e. you can work out the |                     <para> If your users are at a fixed location in the directory (i.e. you can work | ||||||
|             DN directly from the username without doing a directory search), you can use this |                         out the DN directly from the username without doing a directory search), you | ||||||
|             attribute to map directly to the DN. It maps directly to the |                         can use this attribute to map directly to the DN. It maps directly to the | ||||||
|                         <literal>userDnPatterns</literal> property of |                         <literal>userDnPatterns</literal> property of | ||||||
|                         <classname>AbstractLdapAuthenticator</classname>. </para> |                         <classname>AbstractLdapAuthenticator</classname>. </para> | ||||||
|                 </section> |                 </section> | ||||||
|                 <section> |                 <section> | ||||||
|           <title>The <literal>user-search-base</literal> and <literal>user-search-filter</literal> |                     <title>The <literal>user-search-base</literal> and | ||||||
|             Attributes</title> |                         <literal>user-search-filter</literal> Attributes</title> | ||||||
|           <para> If you need to perform a search to locate the user in the directory, then you can |                     <para> If you need to perform a search to locate the user in the directory, then | ||||||
|             set these attributes to control the search. The <classname>BindAuthenticator</classname> |                         you can set these attributes to control the search. The | ||||||
|             will be configured with a <classname>FilterBasedLdapUserSearch</classname> and the |                         <classname>BindAuthenticator</classname> will be configured with a | ||||||
|             attribute values map directly to the first two arguments of that bean's constructor. If |                         <classname>FilterBasedLdapUserSearch</classname> and the attribute values | ||||||
|             these attributes aren't set and no <literal>user-dn-pattern</literal> has been supplied |                         map directly to the first two arguments of that bean's constructor. If these | ||||||
|             as an alternative, then the default search values of |                         attributes aren't set and no <literal>user-dn-pattern</literal> has been | ||||||
|  |                         supplied as an alternative, then the default search values of | ||||||
|                         <literal>user-search-filter="(uid={0})"</literal> and |                         <literal>user-search-filter="(uid={0})"</literal> and | ||||||
|                         <literal>user-search-base=""</literal> will be used. </para> |                         <literal>user-search-base=""</literal> will be used. </para> | ||||||
|                 </section> |                 </section> | ||||||
|                 <section> |                 <section> | ||||||
|           <title><literal>group-search-filter</literal>, <literal>group-search-base</literal>, |                     <title><literal>group-search-filter</literal>, | ||||||
|  |                         <literal>group-search-base</literal>, | ||||||
|                         <literal>group-role-attribute</literal> and <literal>role-prefix</literal> |                         <literal>group-role-attribute</literal> and <literal>role-prefix</literal> | ||||||
|                         Attributes</title> |                         Attributes</title> | ||||||
|                     <para> The value of <literal>group-search-base</literal> is mapped to the |                     <para> The value of <literal>group-search-base</literal> is mapped to the | ||||||
|                         <literal>groupSearchBase</literal> constructor argument of |                         <literal>groupSearchBase</literal> constructor argument of | ||||||
|               <classname>DefaultAuthoritiesPopulator</classname> and defaults to "ou=groups". The |                         <classname>DefaultAuthoritiesPopulator</classname> and defaults to | ||||||
|             default filter value is "(uniqueMember={0})", which assumes that the entry is of type |                         "ou=groups". The default filter value is "(uniqueMember={0})", which assumes | ||||||
|             "groupOfUniqueNames". <literal>group-role-attribute</literal> maps to the |                         that the entry is of type "groupOfUniqueNames". | ||||||
|               <literal>groupRoleAttribute</literal> attribute and defaults to "cn". Similarly |                         <literal>group-role-attribute</literal> maps to the | ||||||
|               <literal>role-prefix</literal> maps to <literal>rolePrefix</literal> and defaults to |                         <literal>groupRoleAttribute</literal> attribute and defaults to "cn". | ||||||
|             "ROLE_". </para> |                         Similarly <literal>role-prefix</literal> maps to | ||||||
|  |                         <literal>rolePrefix</literal> and defaults to "ROLE_". </para> | ||||||
|                 </section> |                 </section> | ||||||
|                 <section> |                 <section> | ||||||
|                     <title>The <literal><password-compare></literal> Element</title> |                     <title>The <literal><password-compare></literal> Element</title> | ||||||
|           <para> This is used as child element to <literal><ldap-provider></literal> and |                     <para> This is used as child element to <literal><ldap-provider></literal> | ||||||
|             switches the authentication strategy from <classname>BindAuthenticator</classname> to |                         and switches the authentication strategy from | ||||||
|               <classname>PasswordComparisonAuthenticator</classname>. This can optionally be |                         <classname>BindAuthenticator</classname> to | ||||||
|             supplied with a <literal>hash</literal> attribute or with a child |                         <classname>PasswordComparisonAuthenticator</classname>. This can optionally | ||||||
|               <literal><password-encoder></literal> element to hash the password before |                         be supplied with a <literal>hash</literal> attribute or with a child | ||||||
|             submitting it to the directory for comparison. </para> |                         <literal><password-encoder></literal> element to hash the password | ||||||
|  |                         before submitting it to the directory for comparison. </para> | ||||||
|                 </section> |                 </section> | ||||||
|             </section> |             </section> | ||||||
|             <section> |             <section> | ||||||
|                 <title>The <literal><ldap-user-service></literal> Element</title> |                 <title>The <literal><ldap-user-service></literal> Element</title> | ||||||
|         <para> This element configures an LDAP <interfacename>UserDetailsService</interfacename>. |                 <para> This element configures an LDAP | ||||||
|           The class used is <classname>LdapUserDetailsService</classname> which is a combination of |                     <interfacename>UserDetailsService</interfacename>. The class used is | ||||||
|           a <classname>FilterBasedLdapUserSearch</classname> and a |                     <classname>LdapUserDetailsService</classname> which is a combination of a | ||||||
|             <classname>DefaultAuthoritiesPopulator</classname>. The attributes it supports have the |                     <classname>FilterBasedLdapUserSearch</classname> and a | ||||||
|           same usage as in <literal><ldap-provider></literal>. </para> |                     <classname>DefaultAuthoritiesPopulator</classname>. The attributes it supports | ||||||
|  |                     have the same usage as in <literal><ldap-provider></literal>. </para> | ||||||
|             </section> |             </section> | ||||||
|         </section> |         </section> | ||||||
|     </section> |     </section> | ||||||
|  |  | ||||||
|  | @ -7,11 +7,12 @@ | ||||||
|         <info> |         <info> | ||||||
|             <title>Authorities</title> |             <title>Authorities</title> | ||||||
|         </info> |         </info> | ||||||
|     <para>As we saw in the <link xlink:href="#tech-granted-authority">technical overview</link>, all |         <para>As we saw in the <link xlink:href="#tech-granted-authority">technical overview</link>, | ||||||
|         <interfacename>Authentication</interfacename> implementations store a list of |             all <interfacename>Authentication</interfacename> implementations store a list of | ||||||
|             <interfacename>GrantedAuthority</interfacename> objects. These represent the authorities |             <interfacename>GrantedAuthority</interfacename> objects. These represent the authorities | ||||||
|       that have been granted to the principal. The <interfacename>GrantedAuthority</interfacename> |             that have been granted to the principal. The | ||||||
|       objects are inserted into the <interfacename>Authentication</interfacename> object by the |             <interfacename>GrantedAuthority</interfacename> objects are inserted into the | ||||||
|  |             <interfacename>Authentication</interfacename> object by the | ||||||
|             <interfacename>AuthenticationManager</interfacename> and are later read by |             <interfacename>AuthenticationManager</interfacename> and are later read by | ||||||
|             <interfacename>AccessDecisionManager</interfacename>s when making authorization |             <interfacename>AccessDecisionManager</interfacename>s when making authorization | ||||||
|             decisions.</para> |             decisions.</para> | ||||||
|  | @ -22,74 +23,79 @@ | ||||||
|             <interfacename>AccessDecisionManager</interfacename>s to obtain a precise |             <interfacename>AccessDecisionManager</interfacename>s to obtain a precise | ||||||
|             <literal>String</literal> representation of the |             <literal>String</literal> representation of the | ||||||
|             <interfacename>GrantedAuthority</interfacename>. By returning a representation as a |             <interfacename>GrantedAuthority</interfacename>. By returning a representation as a | ||||||
|         <literal>String</literal>, a <interfacename>GrantedAuthority</interfacename> can be easily |             <literal>String</literal>, a <interfacename>GrantedAuthority</interfacename> can be | ||||||
|         <quote>read</quote> by most <interfacename>AccessDecisionManager</interfacename>s. If a |             easily <quote>read</quote> by most | ||||||
|  |             <interfacename>AccessDecisionManager</interfacename>s. If a | ||||||
|             <interfacename>GrantedAuthority</interfacename> cannot be precisely represented as a |             <interfacename>GrantedAuthority</interfacename> cannot be precisely represented as a | ||||||
|         <literal>String</literal>, the <interfacename>GrantedAuthority</interfacename> is considered |             <literal>String</literal>, the <interfacename>GrantedAuthority</interfacename> is | ||||||
|         <quote>complex</quote> and <literal>getAuthority()</literal> must return |             considered <quote>complex</quote> and <literal>getAuthority()</literal> must return | ||||||
|             <literal>null</literal>.</para> |             <literal>null</literal>.</para> | ||||||
|     <para>An example of a <quote>complex</quote> |         <para>An example of a <quote>complex</quote> <interfacename>GrantedAuthority</interfacename> | ||||||
|       <interfacename>GrantedAuthority</interfacename> would be an implementation that stores a list |             would be an implementation that stores a list of operations and authority thresholds | ||||||
|       of operations and authority thresholds that apply to different customer account numbers. |             that apply to different customer account numbers. Representing this complex | ||||||
|       Representing this complex <interfacename>GrantedAuthority</interfacename> as a |             <interfacename>GrantedAuthority</interfacename> as a <literal>String</literal> would be | ||||||
|         <literal>String</literal> would be quite difficult, and as a result the |             quite difficult, and as a result the <literal>getAuthority()</literal> method should | ||||||
|         <literal>getAuthority()</literal> method should return <literal>null</literal>. This will |             return <literal>null</literal>. This will indicate to any | ||||||
|       indicate to any <interfacename>AccessDecisionManager</interfacename> that it will need to |             <interfacename>AccessDecisionManager</interfacename> that it will need to specifically | ||||||
|       specifically support the <interfacename>GrantedAuthority</interfacename> implementation in |             support the <interfacename>GrantedAuthority</interfacename> implementation in order to | ||||||
|       order to understand its contents.</para> |             understand its contents.</para> | ||||||
|         <para>Spring Security includes one concrete <interfacename>GrantedAuthority</interfacename> |         <para>Spring Security includes one concrete <interfacename>GrantedAuthority</interfacename> | ||||||
|             implementation, <literal>GrantedAuthorityImpl</literal>. This allows any user-specified |             implementation, <literal>GrantedAuthorityImpl</literal>. This allows any user-specified | ||||||
|             <literal>String</literal> to be converted into a |             <literal>String</literal> to be converted into a | ||||||
|             <interfacename>GrantedAuthority</interfacename>. All |             <interfacename>GrantedAuthority</interfacename>. All | ||||||
|         <classname>AuthenticationProvider</classname>s included with the security architecture use |             <classname>AuthenticationProvider</classname>s included with the security architecture | ||||||
|         <literal>GrantedAuthorityImpl</literal> to populate the |             use <literal>GrantedAuthorityImpl</literal> to populate the | ||||||
|             <interfacename>Authentication</interfacename> object.</para> |             <interfacename>Authentication</interfacename> object.</para> | ||||||
|     </section> |     </section> | ||||||
|     <section xml:id="authz-pre-invocation"> |     <section xml:id="authz-pre-invocation"> | ||||||
|         <info> |         <info> | ||||||
|             <title>Pre-Invocation Handling</title> |             <title>Pre-Invocation Handling</title> | ||||||
|         </info> |         </info> | ||||||
|     <para> As we've also seen in the <link xlink:href="#secure-objects">Technical Overview</link> |         <para> As we've also seen in the <link xlink:href="#secure-objects">Technical | ||||||
|       chapter, Spring Security provides interceptors which control access to secure objects such as |             Overview</link> chapter, Spring Security provides interceptors which control access to | ||||||
|       method invocations or web requests. A pre-invocation decision on whether the invocation is |             secure objects such as method invocations or web requests. A pre-invocation decision on | ||||||
|       allowed to proceed is made by the <interfacename>AccessDecisionManager</interfacename>. </para> |             whether the invocation is allowed to proceed is made by the | ||||||
|  |             <interfacename>AccessDecisionManager</interfacename>. </para> | ||||||
|         <section xml:id="authz-access-decision-manager"> |         <section xml:id="authz-access-decision-manager"> | ||||||
|             <title>The AccessDecisionManager</title> |             <title>The AccessDecisionManager</title> | ||||||
|             <para>The <interfacename>AccessDecisionManager</interfacename> is called by the |             <para>The <interfacename>AccessDecisionManager</interfacename> is called by the | ||||||
|           <classname>AbstractSecurityInterceptor</classname> and is responsible for making final |                 <classname>AbstractSecurityInterceptor</classname> and is responsible for making | ||||||
|         access control decisions. The <interfacename>AccessDecisionManager</interfacename> interface |                 final access control decisions. The | ||||||
|         contains three methods: |                 <interfacename>AccessDecisionManager</interfacename> interface contains three | ||||||
|  |                 methods: | ||||||
|                 <programlisting> |                 <programlisting> | ||||||
|  void decide(Authentication authentication, Object secureObject, |  void decide(Authentication authentication, Object secureObject, | ||||||
|      List<ConfigAttribute> config) throws AccessDeniedException; |      List<ConfigAttribute> config) throws AccessDeniedException; | ||||||
|  boolean supports(ConfigAttribute attribute); |  boolean supports(ConfigAttribute attribute); | ||||||
|  boolean supports(Class clazz); |  boolean supports(Class clazz); | ||||||
|       </programlisting> |       </programlisting> | ||||||
|         The <interfacename>AccessDecisionManager</interfacename>'s <methodname>decide</methodname> |                 The <interfacename>AccessDecisionManager</interfacename>'s | ||||||
|         method is passed all the relevant information it needs in order to make an authorization |                 <methodname>decide</methodname> method is passed all the relevant information it | ||||||
|         decision. In particular, passing the secure <literal>Object</literal> enables those |                 needs in order to make an authorization decision. In particular, passing the secure | ||||||
|         arguments contained in the actual secure object invocation to be inspected. For example, |                 <literal>Object</literal> enables those arguments contained in the actual secure | ||||||
|         let's assume the secure object was a <classname>MethodInvocation</classname>. It would be |                 object invocation to be inspected. For example, let's assume the secure object was a | ||||||
|         easy to query the <classname>MethodInvocation</classname> for any |                 <classname>MethodInvocation</classname>. It would be easy to query the | ||||||
|           <literal>Customer</literal> argument, and then implement some sort of security logic in |                 <classname>MethodInvocation</classname> for any <literal>Customer</literal> | ||||||
|         the <interfacename>AccessDecisionManager</interfacename> to ensure the principal is |                 argument, and then implement some sort of security logic in the | ||||||
|  |                 <interfacename>AccessDecisionManager</interfacename> to ensure the principal is | ||||||
|                 permitted to operate on that customer. Implementations are expected to throw an |                 permitted to operate on that customer. Implementations are expected to throw an | ||||||
|                 <literal>AccessDeniedException</literal> if access is denied.</para> |                 <literal>AccessDeniedException</literal> if access is denied.</para> | ||||||
|             <para>The <literal>supports(ConfigAttribute)</literal> method is called by the |             <para>The <literal>supports(ConfigAttribute)</literal> method is called by the | ||||||
|           <classname>AbstractSecurityInterceptor</classname> at startup time to determine if the |                 <classname>AbstractSecurityInterceptor</classname> at startup time to determine if | ||||||
|           <interfacename>AccessDecisionManager</interfacename> can process the passed |                 the <interfacename>AccessDecisionManager</interfacename> can process the passed | ||||||
|                 <literal>ConfigAttribute</literal>. The <literal>supports(Class)</literal> method is |                 <literal>ConfigAttribute</literal>. The <literal>supports(Class)</literal> method is | ||||||
|                 called by a security interceptor implementation to ensure the configured |                 called by a security interceptor implementation to ensure the configured | ||||||
|           <interfacename>AccessDecisionManager</interfacename> supports the type of secure object |                 <interfacename>AccessDecisionManager</interfacename> supports the type of secure | ||||||
|         that the security interceptor will present.</para> |                 object that the security interceptor will present.</para> | ||||||
|         </section> |         </section> | ||||||
|         <section xml:id="authz-voting-based"> |         <section xml:id="authz-voting-based"> | ||||||
|             <title>Voting-Based AccessDecisionManager Implementations</title> |             <title>Voting-Based AccessDecisionManager Implementations</title> | ||||||
|             <para>Whilst users can implement their own |             <para>Whilst users can implement their own | ||||||
|                 <interfacename>AccessDecisionManager</interfacename> to control all aspects of |                 <interfacename>AccessDecisionManager</interfacename> to control all aspects of | ||||||
|                 authorization, Spring Security includes several |                 authorization, Spring Security includes several | ||||||
|           <interfacename>AccessDecisionManager</interfacename> implementations that are based on |                 <interfacename>AccessDecisionManager</interfacename> implementations that are based | ||||||
|         voting. <xref linkend="authz-access-voting"/> illustrates the relevant classes.</para> |                 on voting. <xref linkend="authz-access-voting"/> illustrates the relevant | ||||||
|  |                 classes.</para> | ||||||
|             <figure xml:id="authz-access-voting"> |             <figure xml:id="authz-access-voting"> | ||||||
|                 <title>Voting Decision Manager</title> |                 <title>Voting Decision Manager</title> | ||||||
|                 <mediaobject> |                 <mediaobject> | ||||||
|  | @ -99,87 +105,92 @@ | ||||||
|                     </imageobject> |                     </imageobject> | ||||||
|                 </mediaobject> |                 </mediaobject> | ||||||
|             </figure> |             </figure> | ||||||
|       <para>Using this approach, a series of <interfacename>AccessDecisionVoter</interfacename> |             <para>Using this approach, a series of | ||||||
|         implementations are polled on an authorization decision. The |                 <interfacename>AccessDecisionVoter</interfacename> implementations are polled on an | ||||||
|           <interfacename>AccessDecisionManager</interfacename> then decides whether or not to throw |                 authorization decision. The <interfacename>AccessDecisionManager</interfacename> | ||||||
|         an <literal>AccessDeniedException</literal> based on its assessment of the votes.</para> |                 then decides whether or not to throw an <literal>AccessDeniedException</literal> | ||||||
|       <para>The <interfacename>AccessDecisionVoter</interfacename> interface has three methods: |                 based on its assessment of the votes.</para> | ||||||
|  |             <para>The <interfacename>AccessDecisionVoter</interfacename> interface has three | ||||||
|  |                 methods: | ||||||
|                 <programlisting> |                 <programlisting> | ||||||
| int vote(Authentication authentication, Object object, List<ConfigAttribute> config); | int vote(Authentication authentication, Object object, List<ConfigAttribute> config); | ||||||
| boolean supports(ConfigAttribute attribute); | boolean supports(ConfigAttribute attribute); | ||||||
| boolean supports(Class clazz); | boolean supports(Class clazz); | ||||||
| </programlisting> | </programlisting> | ||||||
|         Concrete implementations return an <literal>int</literal>, with possible values being |                 Concrete implementations return an <literal>int</literal>, with possible values | ||||||
|         reflected in the <interfacename>AccessDecisionVoter</interfacename> static fields |                 being reflected in the <interfacename>AccessDecisionVoter</interfacename> static | ||||||
|           <literal>ACCESS_ABSTAIN</literal>, <literal>ACCESS_DENIED</literal> and |                 fields <literal>ACCESS_ABSTAIN</literal>, <literal>ACCESS_DENIED</literal> and | ||||||
|                 <literal>ACCESS_GRANTED</literal>. A voting implementation will return |                 <literal>ACCESS_GRANTED</literal>. A voting implementation will return | ||||||
|           <literal>ACCESS_ABSTAIN</literal> if it has no opinion on an authorization decision. If it |                 <literal>ACCESS_ABSTAIN</literal> if it has no opinion on an authorization decision. | ||||||
|         does have an opinion, it must return either <literal>ACCESS_DENIED</literal> or |                 If it does have an opinion, it must return either <literal>ACCESS_DENIED</literal> | ||||||
|           <literal>ACCESS_GRANTED</literal>.</para> |                 or <literal>ACCESS_GRANTED</literal>.</para> | ||||||
|       <para>There are three concrete <interfacename>AccessDecisionManager</interfacename>s provided |             <para>There are three concrete <interfacename>AccessDecisionManager</interfacename>s | ||||||
|         with Spring Security that tally the votes. The <literal>ConsensusBased</literal> |                 provided with Spring Security that tally the votes. The | ||||||
|         implementation will grant or deny access based on the consensus of non-abstain votes. |                 <literal>ConsensusBased</literal> implementation will grant or deny access based on | ||||||
|         Properties are provided to control behavior in the event of an equality of votes or if all |                 the consensus of non-abstain votes. Properties are provided to control behavior in | ||||||
|         votes are abstain. The <literal>AffirmativeBased</literal> implementation will grant access |                 the event of an equality of votes or if all votes are abstain. The | ||||||
|         if one or more <literal>ACCESS_GRANTED</literal> votes were received (i.e. a deny vote will |                 <literal>AffirmativeBased</literal> implementation will grant access if one or more | ||||||
|         be ignored, provided there was at least one grant vote). Like the |                 <literal>ACCESS_GRANTED</literal> votes were received (i.e. a deny vote will be | ||||||
|           <literal>ConsensusBased</literal> implementation, there is a parameter that controls the |                 ignored, provided there was at least one grant vote). Like the | ||||||
|         behavior if all voters abstain. The <literal>UnanimousBased</literal> provider expects |                 <literal>ConsensusBased</literal> implementation, there is a parameter that controls | ||||||
|         unanimous <literal>ACCESS_GRANTED</literal> votes in order to grant access, ignoring |                 the behavior if all voters abstain. The <literal>UnanimousBased</literal> provider | ||||||
|         abstains. It will deny access if there is any <literal>ACCESS_DENIED</literal> vote. Like |                 expects unanimous <literal>ACCESS_GRANTED</literal> votes in order to grant access, | ||||||
|         the other implementations, there is a parameter that controls the behaviour if all voters |                 ignoring abstains. It will deny access if there is any | ||||||
|         abstain.</para> |                 <literal>ACCESS_DENIED</literal> vote. Like the other implementations, there is a | ||||||
|  |                 parameter that controls the behaviour if all voters abstain.</para> | ||||||
|             <para>It is possible to implement a custom |             <para>It is possible to implement a custom | ||||||
|           <interfacename>AccessDecisionManager</interfacename> that tallies votes differently. For |                 <interfacename>AccessDecisionManager</interfacename> that tallies votes differently. | ||||||
|         example, votes from a particular <interfacename>AccessDecisionVoter</interfacename> might |                 For example, votes from a particular | ||||||
|         receive additional weighting, whilst a deny vote from a particular voter may have a veto |                 <interfacename>AccessDecisionVoter</interfacename> might receive additional | ||||||
|         effect.</para> |                 weighting, whilst a deny vote from a particular voter may have a veto effect.</para> | ||||||
|             <section xml:id="authz-role-voter"> |             <section xml:id="authz-role-voter"> | ||||||
|                 <title><classname>RoleVoter</classname></title> |                 <title><classname>RoleVoter</classname></title> | ||||||
|         <para> The most commonly used <interfacename>AccessDecisionVoter</interfacename> provided |                 <para> The most commonly used <interfacename>AccessDecisionVoter</interfacename> | ||||||
|           with Spring Security is the simple <classname>RoleVoter</classname>, which treats |                     provided with Spring Security is the simple <classname>RoleVoter</classname>, | ||||||
|           configuration attributes as simple role names and votes to grant access if the user has |                     which treats configuration attributes as simple role names and votes to grant | ||||||
|           been assigned that role.</para> |                     access if the user has been assigned that role.</para> | ||||||
|         <para>It will vote if any <interfacename>ConfigAttribute</interfacename> begins with the |                 <para>It will vote if any <interfacename>ConfigAttribute</interfacename> begins with | ||||||
|           prefix <literal>ROLE_</literal>. It will vote to grant access if there is a |                     the prefix <literal>ROLE_</literal>. It will vote to grant access if there is a | ||||||
|                     <interfacename>GrantedAuthority</interfacename> which returns a |                     <interfacename>GrantedAuthority</interfacename> which returns a | ||||||
|             <literal>String</literal> representation (via the <literal>getAuthority()</literal> |                     <literal>String</literal> representation (via the | ||||||
|           method) exactly equal to one or more <literal>ConfigAttributes</literal> starting with the |                     <literal>getAuthority()</literal> method) exactly equal to one or more | ||||||
|           prefix <literal>ROLE_</literal>. If there is no exact match of any |                     <literal>ConfigAttributes</literal> starting with the prefix | ||||||
|  |                     <literal>ROLE_</literal>. If there is no exact match of any | ||||||
|                     <literal>ConfigAttribute</literal> starting with <literal>ROLE_</literal>, the |                     <literal>ConfigAttribute</literal> starting with <literal>ROLE_</literal>, the | ||||||
|                     <literal>RoleVoter</literal> will vote to deny access. If no |                     <literal>RoleVoter</literal> will vote to deny access. If no | ||||||
|             <literal>ConfigAttribute</literal> begins with <literal>ROLE_</literal>, the voter will |                     <literal>ConfigAttribute</literal> begins with <literal>ROLE_</literal>, the | ||||||
|           abstain.</para> |                     voter will abstain.</para> | ||||||
|             </section> |             </section> | ||||||
|             <section xml:id="authz-authenticated-voter"> |             <section xml:id="authz-authenticated-voter"> | ||||||
|                 <title><classname>AuthenticatedVoter</classname></title> |                 <title><classname>AuthenticatedVoter</classname></title> | ||||||
|                 <para> Another voter which we've implicitly seen is the |                 <para> Another voter which we've implicitly seen is the | ||||||
|             <classname>AuthenticatedVoter</classname>, which can be used to differentiate between |                     <classname>AuthenticatedVoter</classname>, which can be used to differentiate | ||||||
|           anonymous, fully-authenticated and remember-me authenticated users. Many sites allow |                     between anonymous, fully-authenticated and remember-me authenticated users. Many | ||||||
|           certain limited access under remember-me authentication, but require a user to confirm |                     sites allow certain limited access under remember-me authentication, but require | ||||||
|           their identity by logging in for full access.</para> |                     a user to confirm their identity by logging in for full access.</para> | ||||||
|         <para>When we've used the attribute <literal>IS_AUTHENTICATED_ANONYMOUSLY</literal> to grant |                 <para>When we've used the attribute <literal>IS_AUTHENTICATED_ANONYMOUSLY</literal> | ||||||
|           anonymous access, this attribute was being processed by the |                     to grant anonymous access, this attribute was being processed by the | ||||||
|             <classname>AuthenticatedVoter</classname>. See the Javadoc for this class for more |                     <classname>AuthenticatedVoter</classname>. See the Javadoc for this class for | ||||||
|           information. </para> |                     more information. </para> | ||||||
|             </section> |             </section> | ||||||
|             <section> |             <section> | ||||||
|                 <title>Custom Voters</title> |                 <title>Custom Voters</title> | ||||||
|                 <para>It is also possible to implement a custom |                 <para>It is also possible to implement a custom | ||||||
|             <interfacename>AccessDecisionVoter</interfacename>. Several examples are provided in |                     <interfacename>AccessDecisionVoter</interfacename>. Several examples are | ||||||
|           Spring Security unit tests, including <literal>ContactSecurityVoter</literal> and |                     provided in Spring Security unit tests, including | ||||||
|             <literal>DenyVoter</literal>. The <literal>ContactSecurityVoter</literal> abstains from |                     <literal>ContactSecurityVoter</literal> and <literal>DenyVoter</literal>. The | ||||||
|           voting decisions where a <literal>CONTACT_OWNED_BY_CURRENT_USER</literal> |                     <literal>ContactSecurityVoter</literal> abstains from voting decisions where a | ||||||
|  |                     <literal>CONTACT_OWNED_BY_CURRENT_USER</literal> | ||||||
|                     <literal>ConfigAttribute</literal> is not found. If voting, it queries the |                     <literal>ConfigAttribute</literal> is not found. If voting, it queries the | ||||||
|                     <classname>MethodInvocation</classname> to extract the owner of the |                     <classname>MethodInvocation</classname> to extract the owner of the | ||||||
|             <literal>Contact</literal> object that is subject of the method call. It votes to grant |                     <literal>Contact</literal> object that is subject of the method call. It votes | ||||||
|           access if the <literal>Contact</literal> owner matches the principal presented in the |                     to grant access if the <literal>Contact</literal> owner matches the principal | ||||||
|             <interfacename>Authentication</interfacename> object. It could have just as easily |                     presented in the <interfacename>Authentication</interfacename> object. It could | ||||||
|           compared the <literal>Contact</literal> owner with some |                     have just as easily compared the <literal>Contact</literal> owner with some | ||||||
|                     <interfacename>GrantedAuthority</interfacename> the |                     <interfacename>GrantedAuthority</interfacename> the | ||||||
|             <interfacename>Authentication</interfacename> object presented. All of this is achieved |                     <interfacename>Authentication</interfacename> object presented. All of this is | ||||||
|           with relatively few lines of code and demonstrates the flexibility of the authorization |                     achieved with relatively few lines of code and demonstrates the flexibility of | ||||||
|           model.</para> |                     the authorization model.</para> | ||||||
|             </section> |             </section> | ||||||
|         </section> |         </section> | ||||||
|     </section> |     </section> | ||||||
|  | @ -188,43 +199,46 @@ boolean supports(Class clazz); | ||||||
|             <title>After Invocation Handling</title> |             <title>After Invocation Handling</title> | ||||||
|         </info> |         </info> | ||||||
|         <para>Whilst the <interfacename>AccessDecisionManager</interfacename> is called by the |         <para>Whilst the <interfacename>AccessDecisionManager</interfacename> is called by the | ||||||
|         <classname>AbstractSecurityInterceptor</classname> before proceeding with the secure object |             <classname>AbstractSecurityInterceptor</classname> before proceeding with the secure | ||||||
|       invocation, some applications need a way of modifying the object actually returned by the |             object invocation, some applications need a way of modifying the object actually | ||||||
|       secure object invocation. Whilst you could easily implement your own AOP concern to achieve |             returned by the secure object invocation. Whilst you could easily implement your own AOP | ||||||
|       this, Spring Security provides a convenient hook that has several concrete implementations |             concern to achieve this, Spring Security provides a convenient hook that has several | ||||||
|       that integrate with its ACL capabilities.</para> |             concrete implementations that integrate with its ACL capabilities.</para> | ||||||
|         <para><xref linkend="authz-after-invocation"/> illustrates Spring Security's |         <para><xref linkend="authz-after-invocation"/> illustrates Spring Security's | ||||||
|             <literal>AfterInvocationManager</literal> and its concrete implementations. <figure |             <literal>AfterInvocationManager</literal> and its concrete implementations. <figure | ||||||
|             xml:id="authz-after-invocation"> |             xml:id="authz-after-invocation"> | ||||||
|             <title>After Invocation Implementation</title> |             <title>After Invocation Implementation</title> | ||||||
|             <mediaobject> |             <mediaobject> | ||||||
|                 <imageobject> |                 <imageobject> | ||||||
|             <imagedata align="center" fileref="images/after-invocation.png" format="PNG" scale="75"/> |                     <imagedata align="center" fileref="images/after-invocation.png" format="PNG" | ||||||
|  |                         scale="75"/> | ||||||
|                 </imageobject> |                 </imageobject> | ||||||
|             </mediaobject> |             </mediaobject> | ||||||
|             </figure></para> |             </figure></para> | ||||||
|     <para>Like many other parts of Spring Security, <literal>AfterInvocationManager</literal> has a |         <para>Like many other parts of Spring Security, <literal>AfterInvocationManager</literal> | ||||||
|       single concrete implementation, <literal>AfterInvocationProviderManager</literal>, which polls |             has a single concrete implementation, <literal>AfterInvocationProviderManager</literal>, | ||||||
|       a list of <literal>AfterInvocationProvider</literal>s. Each |             which polls a list of <literal>AfterInvocationProvider</literal>s. Each | ||||||
|         <literal>AfterInvocationProvider</literal> is allowed to modify the return object or throw |             <literal>AfterInvocationProvider</literal> is allowed to modify the return object or | ||||||
|       an <literal>AccessDeniedException</literal>. Indeed multiple providers can modify the object, |             throw an <literal>AccessDeniedException</literal>. Indeed multiple providers can modify | ||||||
|       as the result of the previous provider is passed to the next in the list.</para> |             the object, as the result of the previous provider is passed to the next in the | ||||||
|     <para>Please be aware that if you're using <literal>AfterInvocationManager</literal>, you will |             list.</para> | ||||||
|       still need configuration attributes that allow the |         <para>Please be aware that if you're using <literal>AfterInvocationManager</literal>, you | ||||||
|  |             will still need configuration attributes that allow the | ||||||
|             <classname>MethodSecurityInterceptor</classname>'s |             <classname>MethodSecurityInterceptor</classname>'s | ||||||
|         <interfacename>AccessDecisionManager</interfacename> to allow an operation. If you're using |             <interfacename>AccessDecisionManager</interfacename> to allow an operation. If you're | ||||||
|       the typical Spring Security included <interfacename>AccessDecisionManager</interfacename> |             using the typical Spring Security included | ||||||
|       implementations, having no configuration attributes defined for a particular secure method |             <interfacename>AccessDecisionManager</interfacename> implementations, having no | ||||||
|       invocation will cause each <interfacename>AccessDecisionVoter</interfacename> to abstain from |             configuration attributes defined for a particular secure method invocation will cause | ||||||
|       voting. In turn, if the <interfacename>AccessDecisionManager</interfacename> property |             each <interfacename>AccessDecisionVoter</interfacename> to abstain from voting. In turn, | ||||||
|  |             if the <interfacename>AccessDecisionManager</interfacename> property | ||||||
|             "<literal>allowIfAllAbstainDecisions</literal>" is <literal>false</literal>, an |             "<literal>allowIfAllAbstainDecisions</literal>" is <literal>false</literal>, an | ||||||
|         <literal>AccessDeniedException</literal> will be thrown. You may avoid this potential issue |             <literal>AccessDeniedException</literal> will be thrown. You may avoid this potential | ||||||
|       by either (i) setting "<literal>allowIfAllAbstainDecisions</literal>" to |             issue by either (i) setting "<literal>allowIfAllAbstainDecisions</literal>" to | ||||||
|         <literal>true</literal> (although this is generally not recommended) or (ii) simply ensure |             <literal>true</literal> (although this is generally not recommended) or (ii) simply | ||||||
|       that there is at least one configuration attribute that an |             ensure that there is at least one configuration attribute that an | ||||||
|             <interfacename>AccessDecisionVoter</interfacename> will vote to grant access for. This |             <interfacename>AccessDecisionVoter</interfacename> will vote to grant access for. This | ||||||
|       latter (recommended) approach is usually achieved through a <literal>ROLE_USER</literal> or |             latter (recommended) approach is usually achieved through a <literal>ROLE_USER</literal> | ||||||
|         <literal>ROLE_AUTHENTICATED</literal> configuration attribute.</para> |             or <literal>ROLE_AUTHENTICATED</literal> configuration attribute.</para> | ||||||
|         <!-- TODO: Move to ACL section and add reference here --> |         <!-- TODO: Move to ACL section and add reference here --> | ||||||
|         <!-- |         <!-- | ||||||
|     <section xml:id="after-invocation-acl-aware"> |     <section xml:id="after-invocation-acl-aware"> | ||||||
|  |  | ||||||
|  | @ -27,11 +27,10 @@ | ||||||
|                 <title>Configuration</title> |                 <title>Configuration</title> | ||||||
|             </info> |             </info> | ||||||
|             <para>To implement HTTP Basic Authentication, you need to add a |             <para>To implement HTTP Basic Authentication, you need to add a | ||||||
|                     <literal>BasicAuthenticationFilter</literal> to your filter chain. The |                 <literal>BasicAuthenticationFilter</literal> to your filter chain. The application | ||||||
|                 application context should contain <literal>BasicAuthenticationFilter</literal> and |                 context should contain <literal>BasicAuthenticationFilter</literal> and its required | ||||||
|                 its required collaborator:</para> |                 collaborator:</para> | ||||||
|             <para> |             <para> <programlisting language="xml"><![CDATA[ | ||||||
|                 <programlisting language="xml"><![CDATA[ |  | ||||||
| <bean id="basicAuthenticationFilter" | <bean id="basicAuthenticationFilter" | ||||||
|   class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter"> |   class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter"> | ||||||
|   <property name="authenticationManager" ref="authenticationManager"/> |   <property name="authenticationManager" ref="authenticationManager"/> | ||||||
|  | @ -42,14 +41,13 @@ | ||||||
|   class="org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint"> |   class="org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint"> | ||||||
|   <property name="realmName" value="Name Of Your Realm"/> |   <property name="realmName" value="Name Of Your Realm"/> | ||||||
| </bean>]]> | </bean>]]> | ||||||
|                 </programlisting> |                 </programlisting> </para> | ||||||
|             </para> |  | ||||||
|             <para>The configured <interfacename>AuthenticationManager</interfacename> processes each |             <para>The configured <interfacename>AuthenticationManager</interfacename> processes each | ||||||
|                 authentication request. If authentication fails, the configured |                 authentication request. If authentication fails, the configured | ||||||
|                     <interfacename>AuthenticationEntryPoint</interfacename> will be used to retry |                 <interfacename>AuthenticationEntryPoint</interfacename> will be used to retry the | ||||||
|                 the authentication process. Usually you will use the filter in combination with a |                 authentication process. Usually you will use the filter in combination with a | ||||||
|                     <literal>BasicAuthenticationEntryPoint</literal>, which returns a 401 response |                 <literal>BasicAuthenticationEntryPoint</literal>, which returns a 401 response with | ||||||
|                 with a suitable header to retry HTTP Basic authentication. If authentication is |                 a suitable header to retry HTTP Basic authentication. If authentication is | ||||||
|                 successful, the resulting <interfacename>Authentication</interfacename> object will |                 successful, the resulting <interfacename>Authentication</interfacename> object will | ||||||
|                 be placed into the <classname>SecurityContextHolder</classname> as usual.</para> |                 be placed into the <classname>SecurityContextHolder</classname> as usual.</para> | ||||||
|             <para>If the authentication event was successful, or authentication was not attempted |             <para>If the authentication event was successful, or authentication was not attempted | ||||||
|  | @ -86,8 +84,7 @@ | ||||||
| 
 | 
 | ||||||
|   expirationTime:   The date and time when the nonce expires, expressed in milliseconds |   expirationTime:   The date and time when the nonce expires, expressed in milliseconds | ||||||
|   key:              A private key to prevent modification of the nonce token |   key:              A private key to prevent modification of the nonce token | ||||||
|             </programlisting> |             </programlisting> </para> | ||||||
|         </para> |  | ||||||
|         <para>The <classname>DigestAuthenticatonEntryPoint</classname> has a property specifying the |         <para>The <classname>DigestAuthenticatonEntryPoint</classname> has a property specifying the | ||||||
|             <literal>key</literal> used for generating the nonce tokens, along with a |             <literal>key</literal> used for generating the nonce tokens, along with a | ||||||
|             <literal>nonceValiditySeconds</literal> property for determining the expiration time |             <literal>nonceValiditySeconds</literal> property for determining the expiration time | ||||||
|  | @ -99,9 +96,9 @@ | ||||||
|             if they disagree on an included value (eg password). In Spring Security implementation, |             if they disagree on an included value (eg password). In Spring Security implementation, | ||||||
|             if the server-generated nonce has merely expired (but the digest was otherwise valid), |             if the server-generated nonce has merely expired (but the digest was otherwise valid), | ||||||
|             the <classname>DigestAuthenticationEntryPoint</classname> will send a |             the <classname>DigestAuthenticationEntryPoint</classname> will send a | ||||||
|                 <literal>"stale=true"</literal> header. This tells the user agent there is no need |             <literal>"stale=true"</literal> header. This tells the user agent there is no need to | ||||||
|             to disturb the user (as the password and username etc is correct), but simply to try |             disturb the user (as the password and username etc is correct), but simply to try again | ||||||
|             again using a new nonce.</para> |             using a new nonce.</para> | ||||||
|         <para>An appropriate value for <classname>DigestAuthenticationEntryPoint</classname>'s |         <para>An appropriate value for <classname>DigestAuthenticationEntryPoint</classname>'s | ||||||
|             <literal>nonceValiditySeconds</literal> parameter will depend on your application. |             <literal>nonceValiditySeconds</literal> parameter will depend on your application. | ||||||
|             Extremely secure applications should note that an intercepted authentication header can |             Extremely secure applications should note that an intercepted authentication header can | ||||||
|  | @ -120,12 +117,10 @@ | ||||||
|             <title>Configuration</title> |             <title>Configuration</title> | ||||||
|             <para>Now that we've reviewed the theory, let's see how to use it. To implement HTTP |             <para>Now that we've reviewed the theory, let's see how to use it. To implement HTTP | ||||||
|                 Digest Authentication, it is necessary to define |                 Digest Authentication, it is necessary to define | ||||||
|                     <literal>DigestAuthenticationFilter</literal> in the filter chain. The |                 <literal>DigestAuthenticationFilter</literal> in the filter chain. The application | ||||||
|                 application context will need to define the |                 context will need to define the <literal>DigestAuthenticationFilter</literal> and | ||||||
|                     <literal>DigestAuthenticationFilter</literal> and its required |                 its required collaborators:</para> | ||||||
|                 collaborators:</para> |             <para> <programlisting><![CDATA[ | ||||||
|             <para> |  | ||||||
|                 <programlisting><![CDATA[ |  | ||||||
| <bean id="digestFilter" class= | <bean id="digestFilter" class= | ||||||
|     "org.springframework.security.web.authentication.www.DigestAuthenticationFilter"> |     "org.springframework.security.web.authentication.www.DigestAuthenticationFilter"> | ||||||
|   <property name="userDetailsService" ref="jdbcDaoImpl"/> |   <property name="userDetailsService" ref="jdbcDaoImpl"/> | ||||||
|  | @ -139,11 +134,10 @@ | ||||||
|   <property name="key" value="acegi"/> |   <property name="key" value="acegi"/> | ||||||
|   <property name="nonceValiditySeconds" value="10"/> |   <property name="nonceValiditySeconds" value="10"/> | ||||||
| </bean>]]> | </bean>]]> | ||||||
|                 </programlisting> |                 </programlisting> </para> | ||||||
|             </para> |  | ||||||
|             <para>The configured <interfacename>UserDetailsService</interfacename> is needed because |             <para>The configured <interfacename>UserDetailsService</interfacename> is needed because | ||||||
|                     <literal>DigestAuthenticationFilter</literal> must have direct access to the |                 <literal>DigestAuthenticationFilter</literal> must have direct access to the clear | ||||||
|                 clear text password of a user. Digest Authentication will NOT work if you are using |                 text password of a user. Digest Authentication will NOT work if you are using | ||||||
|                 encoded passwords in your DAO. The DAO collaborator, along with the |                 encoded passwords in your DAO. The DAO collaborator, along with the | ||||||
|                 <literal>UserCache</literal>, are typically shared directly with a |                 <literal>UserCache</literal>, are typically shared directly with a | ||||||
|                 <classname>DaoAuthenticationProvider</classname>. The |                 <classname>DaoAuthenticationProvider</classname>. The | ||||||
|  |  | ||||||
|  | @ -4,11 +4,11 @@ | ||||||
|     <section xml:id="cas-overview"> |     <section xml:id="cas-overview"> | ||||||
|         <title>Overview</title> |         <title>Overview</title> | ||||||
|         <para>JA-SIG produces an enterprise-wide single sign on system known as CAS. Unlike other |         <para>JA-SIG produces an enterprise-wide single sign on system known as CAS. Unlike other | ||||||
|       initiatives, JA-SIG's Central Authentication Service is open source, widely used, simple to |             initiatives, JA-SIG's Central Authentication Service is open source, widely used, simple | ||||||
|       understand, platform independent, and supports proxy capabilities. Spring Security fully |             to understand, platform independent, and supports proxy capabilities. Spring Security | ||||||
|       supports CAS, and provides an easy migration path from single-application deployments of |             fully supports CAS, and provides an easy migration path from single-application | ||||||
|       Spring Security through to multiple-application deployments secured by an enterprise-wide CAS |             deployments of Spring Security through to multiple-application deployments secured by an | ||||||
|       server.</para> |             enterprise-wide CAS server.</para> | ||||||
|         <para>You can learn more about CAS at <literal>http://www.ja-sig.org/cas</literal>. You will |         <para>You can learn more about CAS at <literal>http://www.ja-sig.org/cas</literal>. You will | ||||||
|             also need to visit this site to download the CAS Server files.</para> |             also need to visit this site to download the CAS Server files.</para> | ||||||
|     </section> |     </section> | ||||||
|  | @ -16,28 +16,30 @@ | ||||||
|         <info> |         <info> | ||||||
|             <title>How CAS Works</title> |             <title>How CAS Works</title> | ||||||
|         </info> |         </info> | ||||||
|     <para>Whilst the CAS web site contains documents that detail the architecture of CAS, we present |         <para>Whilst the CAS web site contains documents that detail the architecture of CAS, we | ||||||
|       the general overview again here within the context of Spring Security. Spring Security 3.0 |             present the general overview again here within the context of Spring Security. Spring | ||||||
|       supports CAS 3. At the time of writing, the CAS server was at version 3.3.</para> |             Security 3.0 supports CAS 3. At the time of writing, the CAS server was at version | ||||||
|     <para>Somewhere in your enterprise you will need to setup a CAS server. The CAS server is simply |             3.3.</para> | ||||||
|       a standard WAR file, so there isn't anything difficult about setting up your server. Inside |         <para>Somewhere in your enterprise you will need to setup a CAS server. The CAS server is | ||||||
|       the WAR file you will customise the login and other single sign on pages displayed to |             simply a standard WAR file, so there isn't anything difficult about setting up your | ||||||
|       users.</para> |             server. Inside the WAR file you will customise the login and other single sign on pages | ||||||
|  |             displayed to users.</para> | ||||||
|         <para>When deploying a CAS 3.3 server, you will also need to specify an |         <para>When deploying a CAS 3.3 server, you will also need to specify an | ||||||
|             <literal>AuthenticationHandler</literal> in the |             <literal>AuthenticationHandler</literal> in the | ||||||
|             <filename>deployerConfigContext.xml</filename> included with CAS. The |             <filename>deployerConfigContext.xml</filename> included with CAS. The | ||||||
|         <literal>AuthenticationHandler</literal> has a simple method that returns a boolean as to |             <literal>AuthenticationHandler</literal> has a simple method that returns a boolean as | ||||||
|       whether a given set of Credentials is valid. Your <literal>AuthenticationHandler</literal> |             to whether a given set of Credentials is valid. Your | ||||||
|       implementation will need to link into some type of backend authentication repository, such as |             <literal>AuthenticationHandler</literal> implementation will need to link into some type | ||||||
|       an LDAP server or database. CAS itself includes numerous |             of backend authentication repository, such as an LDAP server or database. CAS itself | ||||||
|         <literal>AuthenticationHandler</literal>s out of the box to assist with this. When you |             includes numerous <literal>AuthenticationHandler</literal>s out of the box to assist | ||||||
|       download and deploy the server war file, it is set up to successfully authenticate users who |             with this. When you download and deploy the server war file, it is set up to | ||||||
|       enter a password matching their username, which is useful for testing.</para> |             successfully authenticate users who enter a password matching their username, which is | ||||||
|  |             useful for testing.</para> | ||||||
|         <para>Apart from the CAS server itself, the other key players are of course the secure web |         <para>Apart from the CAS server itself, the other key players are of course the secure web | ||||||
|             applications deployed throughout your enterprise. These web applications are known as |             applications deployed throughout your enterprise. These web applications are known as | ||||||
|       "services". There are two types of services: standard services and proxy services. A proxy |             "services". There are two types of services: standard services and proxy services. A | ||||||
|       service is able to request resources from other services on behalf of the user. This will be |             proxy service is able to request resources from other services on behalf of the user. | ||||||
|       explained more fully later.</para> |             This will be explained more fully later.</para> | ||||||
|         <!-- |         <!-- | ||||||
|   <section xml:id="cas-sequence"> |   <section xml:id="cas-sequence"> | ||||||
|     <title>Spring Security and CAS Interaction Sequence</title> |     <title>Spring Security and CAS Interaction Sequence</title> | ||||||
|  | @ -249,30 +251,28 @@ | ||||||
|             <title>Configuration of CAS Client</title> |             <title>Configuration of CAS Client</title> | ||||||
|         </info> |         </info> | ||||||
|         <para>The web application side of CAS is made easy due to Spring Security. It is assumed you |         <para>The web application side of CAS is made easy due to Spring Security. It is assumed you | ||||||
|       already know the basics of using Spring Security, so these are not covered again below. We'll |             already know the basics of using Spring Security, so these are not covered again below. | ||||||
|       assume a namespace based configuration is being used and add in the CAS beans as required. </para> |             We'll assume a namespace based configuration is being used and add in the CAS beans as | ||||||
|     <para>You will need to add a <classname>ServiceProperties</classname> bean to your application |             required. </para> | ||||||
|       context. This represents your CAS service:</para> |         <para>You will need to add a <classname>ServiceProperties</classname> bean to your | ||||||
|     <para> |             application context. This represents your CAS service:</para> | ||||||
|       <programlisting><![CDATA[ |         <para> <programlisting><![CDATA[ | ||||||
|   <bean id="serviceProperties" |   <bean id="serviceProperties" | ||||||
|         class="org.springframework.security.cas.ServiceProperties"> |         class="org.springframework.security.cas.ServiceProperties"> | ||||||
|     <property name="service" |     <property name="service" | ||||||
|         value="https://localhost:8443/cas-sample/j_spring_cas_security_check"/> |         value="https://localhost:8443/cas-sample/j_spring_cas_security_check"/> | ||||||
|     <property name="sendRenew" value="false"/> |     <property name="sendRenew" value="false"/> | ||||||
|   </bean>]]> |   </bean>]]> | ||||||
|     </programlisting> |     </programlisting> </para> | ||||||
|     </para> |  | ||||||
|         <para>The <literal>service</literal> must equal a URL that will be monitored by the |         <para>The <literal>service</literal> must equal a URL that will be monitored by the | ||||||
|             <literal>CasAuthenticationFilter</literal>. The <literal>sendRenew</literal> defaults to |             <literal>CasAuthenticationFilter</literal>. The <literal>sendRenew</literal> defaults to | ||||||
|       false, but should be set to true if your application is particularly sensitive. What this |             false, but should be set to true if your application is particularly sensitive. What | ||||||
|       parameter does is tell the CAS login service that a single sign on login is unacceptable. |             this parameter does is tell the CAS login service that a single sign on login is | ||||||
|       Instead, the user will need to re-enter their username and password in order to gain access to |             unacceptable. Instead, the user will need to re-enter their username and password in | ||||||
|       the service.</para> |             order to gain access to the service.</para> | ||||||
|         <para>The following beans should be configured to commence the CAS authentication process |         <para>The following beans should be configured to commence the CAS authentication process | ||||||
|             (assuming you're using a namespace configuration):</para> |             (assuming you're using a namespace configuration):</para> | ||||||
|     <para> |         <para> <programlisting><![CDATA[ | ||||||
|       <programlisting><![CDATA[ |  | ||||||
| <security:http entry-point-ref="casEntryPoint"> | <security:http entry-point-ref="casEntryPoint"> | ||||||
|    ... |    ... | ||||||
|    <custom-filter position="FORM_LOGIN_FILTER" ref="myFilter" /> |    <custom-filter position="FORM_LOGIN_FILTER" ref="myFilter" /> | ||||||
|  | @ -289,21 +289,22 @@ | ||||||
|   <property name="serviceProperties" ref="serviceProperties"/> |   <property name="serviceProperties" ref="serviceProperties"/> | ||||||
| </bean> | </bean> | ||||||
| ]]> | ]]> | ||||||
|     </programlisting> |     </programlisting> </para> | ||||||
|     </para> |  | ||||||
|         <para> The <classname>CasAuthenticationEntryPoint</classname> should be selected to drive |         <para> The <classname>CasAuthenticationEntryPoint</classname> should be selected to drive | ||||||
|             authentication using <link xlink:href="ns-entry-point-ref" |             authentication using <link xlink:href="ns-entry-point-ref" | ||||||
|             ><literal>entry-point-ref</literal></link>. </para> |             ><literal>entry-point-ref</literal></link>. </para> | ||||||
|         <para>The <classname>CasAuthenticationFilter</classname> has very similar properties to the |         <para>The <classname>CasAuthenticationFilter</classname> has very similar properties to the | ||||||
|         <classname>UsernamePasswordAuthenticationFilter</classname> (used for form-based logins). |             <classname>UsernamePasswordAuthenticationFilter</classname> (used for form-based | ||||||
|     </para> |             logins). </para> | ||||||
|     <para>For CAS to operate, the <classname>ExceptionTranslationFilter</classname> must have its |         <para>For CAS to operate, the <classname>ExceptionTranslationFilter</classname> must have | ||||||
|         <literal>authenticationEntryPoint</literal> property set to the |             its <literal>authenticationEntryPoint</literal> property set to the | ||||||
|             <classname>CasAuthenticationEntryPoint</classname> bean.</para> |             <classname>CasAuthenticationEntryPoint</classname> bean.</para> | ||||||
|         <para>The <classname>CasAuthenticationEntryPoint</classname> must refer to the |         <para>The <classname>CasAuthenticationEntryPoint</classname> must refer to the | ||||||
|         <classname>ServiceProperties</classname> bean (discussed above), which provides the URL to the |             <classname>ServiceProperties</classname> bean (discussed above), which provides the URL | ||||||
|       enterprise's CAS login server. This is where the user's browser will be redirected.</para> |             to the enterprise's CAS login server. This is where the user's browser will be | ||||||
|     <para>Next you need to add a <literal>CasAuthenticationProvider</literal> and its collaborators: <programlisting><![CDATA[ |             redirected.</para> | ||||||
|  |         <para>Next you need to add a <literal>CasAuthenticationProvider</literal> and its | ||||||
|  |             collaborators: <programlisting><![CDATA[ | ||||||
|   <security:authentication-manager alias="authenticationManager"> |   <security:authentication-manager alias="authenticationManager"> | ||||||
|     <security:authentication-provider ref="casAuthenticationProvider" /> |     <security:authentication-provider ref="casAuthenticationProvider" /> | ||||||
|   </security:authentication-manager> |   </security:authentication-manager> | ||||||
|  | @ -327,7 +328,8 @@ | ||||||
|       </programlisting> The |       </programlisting> The | ||||||
|             <classname>CasAuthenticationProvider</classname> uses a |             <classname>CasAuthenticationProvider</classname> uses a | ||||||
|             <interfacename>UserDetailsService</interfacename> instance to load the authorities for a |             <interfacename>UserDetailsService</interfacename> instance to load the authorities for a | ||||||
|       user, once they have been authentiated by CAS. We've shown a simple in-memory setup here. </para> |             user, once they have been authentiated by CAS. We've shown a simple in-memory setup | ||||||
|  |             here. </para> | ||||||
|         <para>The beans are all reasonable self-explanatory if you refer back to the "How CAS Works" |         <para>The beans are all reasonable self-explanatory if you refer back to the "How CAS Works" | ||||||
|             section.</para> |             section.</para> | ||||||
|     </section> |     </section> | ||||||
|  |  | ||||||
|  | @ -23,19 +23,18 @@ | ||||||
|             to HTTPS pages.</para> |             to HTTPS pages.</para> | ||||||
|         <para>If session hijacking is considered too significant a risk for your particular |         <para>If session hijacking is considered too significant a risk for your particular | ||||||
|             application, the only option is to use HTTPS for every request. This means the |             application, the only option is to use HTTPS for every request. This means the | ||||||
|                 <literal>jsessionid</literal> is never sent across an insecure channel. You will |             <literal>jsessionid</literal> is never sent across an insecure channel. You will need to | ||||||
|             need to ensure your <literal>web.xml</literal>-defined |             ensure your <literal>web.xml</literal>-defined <literal><welcome-file></literal> | ||||||
|                 <literal><welcome-file></literal> points to an HTTPS location, and the |             points to an HTTPS location, and the application never directs the user to an HTTP | ||||||
|             application never directs the user to an HTTP location. Spring Security provides a |             location. Spring Security provides a solution to assist with the latter.</para> | ||||||
|             solution to assist with the latter.</para> |  | ||||||
|     </section> |     </section> | ||||||
|     <section xml:id="channel-security-config"> |     <section xml:id="channel-security-config"> | ||||||
|         <info> |         <info> | ||||||
|             <title>Configuration</title> |             <title>Configuration</title> | ||||||
|         </info> |         </info> | ||||||
|         <para>Channel security is supported by the <link xlink:href="#ns-requires-channel">security |         <para>Channel security is supported by the <link xlink:href="#ns-requires-channel">security | ||||||
|                 namespace</link> by means of the <literal>requires-channel</literal> attribute on |             namespace</link> by means of the <literal>requires-channel</literal> attribute on the | ||||||
|             the <literal><intercept-url></literal> element and this is the simplest (and |             <literal><intercept-url></literal> element and this is the simplest (and | ||||||
|             recommended approach).</para> |             recommended approach).</para> | ||||||
|         <para>To configure channel security explicitly, you would define the following the filter in |         <para>To configure channel security explicitly, you would define the following the filter in | ||||||
|             your application context: <programlisting><![CDATA[ |             your application context: <programlisting><![CDATA[ | ||||||
|  | @ -75,13 +74,13 @@ | ||||||
|         <para>The <literal>ChannelProcessingFilter</literal> operates by filtering all web requests |         <para>The <literal>ChannelProcessingFilter</literal> operates by filtering all web requests | ||||||
|             and determining the configuration attributes that apply. It then delegates to the |             and determining the configuration attributes that apply. It then delegates to the | ||||||
|             <literal>ChannelDecisionManager</literal>. The default implementation, |             <literal>ChannelDecisionManager</literal>. The default implementation, | ||||||
|                 <literal>ChannelDecisionManagerImpl</literal>, should suffice in most cases. It |             <literal>ChannelDecisionManagerImpl</literal>, should suffice in most cases. It simply | ||||||
|             simply delegates to the list of configured <literal>ChannelProcessor</literal> |             delegates to the list of configured <literal>ChannelProcessor</literal> instances. The | ||||||
|             instances. The attribute <literal>ANY_CHANNEL</literal> can be used to override this |             attribute <literal>ANY_CHANNEL</literal> can be used to override this behaviour and skip | ||||||
|             behaviour and skip a particular URL. Otherwise, a <literal>ChannelProcessor</literal> |             a particular URL. Otherwise, a <literal>ChannelProcessor</literal> will review the | ||||||
|             will review the request, and if it is unhappy with the request (e.g. if it was received |             request, and if it is unhappy with the request (e.g. if it was received across the | ||||||
|             across the incorrect transport protocol), it will perform a redirect, throw an exception |             incorrect transport protocol), it will perform a redirect, throw an exception or take | ||||||
|             or take whatever other action is appropriate.</para> |             whatever other action is appropriate.</para> | ||||||
|         <para>Included with Spring Security are two concrete <literal>ChannelProcessor</literal> |         <para>Included with Spring Security are two concrete <literal>ChannelProcessor</literal> | ||||||
|             implementations: <literal>SecureChannelProcessor</literal> ensures requests with a |             implementations: <literal>SecureChannelProcessor</literal> ensures requests with a | ||||||
|             configuration attribute of <literal>REQUIRES_SECURE_CHANNEL</literal> are received over |             configuration attribute of <literal>REQUIRES_SECURE_CHANNEL</literal> are received over | ||||||
|  | @ -93,21 +92,20 @@ | ||||||
|             simply redirect the request to HTTP and HTTPS as appropriate. Appropriate defaults are |             simply redirect the request to HTTP and HTTPS as appropriate. Appropriate defaults are | ||||||
|             assigned to the <literal>ChannelProcessor</literal> implementations for the |             assigned to the <literal>ChannelProcessor</literal> implementations for the | ||||||
|             configuration attribute keywords they respond to and the |             configuration attribute keywords they respond to and the | ||||||
|                 <interfacename>ChannelEntryPoint</interfacename> they delegate to, although you have |             <interfacename>ChannelEntryPoint</interfacename> they delegate to, although you have the | ||||||
|             the ability to override these using the application context.</para> |             ability to override these using the application context.</para> | ||||||
|         <para>Note that the redirections are absolute (eg |         <para>Note that the redirections are absolute (eg | ||||||
|             <literal>http://www.company.com:8080/app/page</literal>), not relative (eg |             <literal>http://www.company.com:8080/app/page</literal>), not relative (eg | ||||||
|                 <literal>/app/page</literal>). During testing it was discovered that Internet |             <literal>/app/page</literal>). During testing it was discovered that Internet Explorer 6 | ||||||
|             Explorer 6 Service Pack 1 has a bug whereby it does not respond correctly to a |             Service Pack 1 has a bug whereby it does not respond correctly to a redirection | ||||||
|             redirection instruction which also changes the port to use. Accordingly, absolute URLs |             instruction which also changes the port to use. Accordingly, absolute URLs are used in | ||||||
|             are used in conjunction with bug detection logic in the |             conjunction with bug detection logic in the <classname>PortResolverImpl</classname> that | ||||||
|                 <classname>PortResolverImpl</classname> that is wired up by default to many Spring |             is wired up by default to many Spring Security beans. Please refer to the JavaDocs for | ||||||
|             Security beans. Please refer to the JavaDocs for <classname>PortResolverImpl</classname> |             <classname>PortResolverImpl</classname> for further details.</para> | ||||||
|             for further details.</para> |  | ||||||
|         <para>You should note that using a secure channel is recommended if usernames and passwords |         <para>You should note that using a secure channel is recommended if usernames and passwords | ||||||
|             are to be kept secure during the login process. If you do decide to use |             are to be kept secure during the login process. If you do decide to use | ||||||
|                 <classname>ChannelProcessingFilter</classname> with form-based login, please ensure |             <classname>ChannelProcessingFilter</classname> with form-based login, please ensure that | ||||||
|             that your login page is set to <literal>REQUIRES_SECURE_CHANNEL</literal>, and that the |             your login page is set to <literal>REQUIRES_SECURE_CHANNEL</literal>, and that the | ||||||
|             <literal>LoginUrlAuthenticationEntryPoint.forceHttps</literal> property is |             <literal>LoginUrlAuthenticationEntryPoint.forceHttps</literal> property is | ||||||
|             <literal>true</literal>.</para> |             <literal>true</literal>.</para> | ||||||
|     </section> |     </section> | ||||||
|  | @ -118,13 +116,13 @@ | ||||||
|         <para>Once configured, using the channel security filter is very easy. Simply request pages |         <para>Once configured, using the channel security filter is very easy. Simply request pages | ||||||
|             without regard to the protocol (ie HTTP or HTTPS) or port (eg 80, 8080, 443, 8443 etc). |             without regard to the protocol (ie HTTP or HTTPS) or port (eg 80, 8080, 443, 8443 etc). | ||||||
|             Obviously you'll still need a way of making the initial request (probably via the |             Obviously you'll still need a way of making the initial request (probably via the | ||||||
|                 <literal>web.xml</literal> |             <literal>web.xml</literal> <literal><welcome-file></literal> or a well-known home | ||||||
|             <literal><welcome-file></literal> or a well-known home page URL), but once this is |             page URL), but once this is done the filter will perform redirects as defined by your | ||||||
|             done the filter will perform redirects as defined by your application context.</para> |             application context.</para> | ||||||
|         <para>You can also add your own <literal>ChannelProcessor</literal> implementations to the |         <para>You can also add your own <literal>ChannelProcessor</literal> implementations to the | ||||||
|             <literal>ChannelDecisionManagerImpl</literal>. For example, you might set a |             <literal>ChannelDecisionManagerImpl</literal>. For example, you might set a | ||||||
|                 <literal>HttpSession</literal> attribute when a human user is detected via a "enter |             <literal>HttpSession</literal> attribute when a human user is detected via a "enter the | ||||||
|             the contents of this graphic" procedure. Your <literal>ChannelProcessor</literal> would |             contents of this graphic" procedure. Your <literal>ChannelProcessor</literal> would | ||||||
|             respond to say <literal>REQUIRES_HUMAN_USER</literal> configuration attributes and |             respond to say <literal>REQUIRES_HUMAN_USER</literal> configuration attributes and | ||||||
|             redirect to an appropriate entry point to start the human user validation process if the |             redirect to an appropriate entry point to start the human user validation process if the | ||||||
|             <literal>HttpSession</literal> attribute is not currently set.</para> |             <literal>HttpSession</literal> attribute is not currently set.</para> | ||||||
|  | @ -133,8 +131,8 @@ | ||||||
|             designed to handle unauthenticated requests, whilst the latter is designed to handle |             designed to handle unauthenticated requests, whilst the latter is designed to handle | ||||||
|             authenticated requests. The latter therefore has access to the granted authorities of |             authenticated requests. The latter therefore has access to the granted authorities of | ||||||
|             the authenticated principal. In addition, problems detected by a |             the authenticated principal. In addition, problems detected by a | ||||||
|                 <literal>ChannelProcessor</literal> will generally cause an HTTP/HTTPS redirection |             <literal>ChannelProcessor</literal> will generally cause an HTTP/HTTPS redirection so | ||||||
|             so its requirements can be met, whilst problems detected by an |             its requirements can be met, whilst problems detected by an | ||||||
|             <interfacename>AccessDecisionVoter</interfacename> will ultimately result in an |             <interfacename>AccessDecisionVoter</interfacename> will ultimately result in an | ||||||
|             <literal>AccessDeniedException</literal> (depending on the governing |             <literal>AccessDeniedException</literal> (depending on the governing | ||||||
|             <interfacename>AccessDecisionManager</interfacename>).</para> |             <interfacename>AccessDecisionManager</interfacename>).</para> | ||||||
|  |  | ||||||
|  | @ -42,7 +42,7 @@ | ||||||
|         </info> |         </info> | ||||||
|         <para>Questions and comments on Spring Security are welcome. You can use the Spring |         <para>Questions and comments on Spring Security are welcome. You can use the Spring | ||||||
|             Community Forum web site at <uri xlink:href="http://forum.springsource.org" |             Community Forum web site at <uri xlink:href="http://forum.springsource.org" | ||||||
|                 >http://forum.springsource.org</uri> to discuss Spring Security with other users of |             >http://forum.springsource.org</uri> to discuss Spring Security with other users of the | ||||||
|             the framework. Remember to use JIRA for bug reports, as explained above.</para> |             framework. Remember to use JIRA for bug reports, as explained above.</para> | ||||||
|     </section> |     </section> | ||||||
| </chapter> | </chapter> | ||||||
|  |  | ||||||
|  | @ -10,11 +10,11 @@ | ||||||
|         <para>We've already seen <classname>FilterSecurityInterceptor</classname> briefly when |         <para>We've already seen <classname>FilterSecurityInterceptor</classname> briefly when | ||||||
|             discussing <link xlink:href="#tech-intro-access-control">access-control in |             discussing <link xlink:href="#tech-intro-access-control">access-control in | ||||||
|             general</link>, and we've already used it with the namespace where the |             general</link>, and we've already used it with the namespace where the | ||||||
|                 <literal><intercept-url></literal> elements are combined to configure it |             <literal><intercept-url></literal> elements are combined to configure it internally. | ||||||
|             internally. Now we'll see how to explicitly configure it for use with a |             Now we'll see how to explicitly configure it for use with a | ||||||
|             <classname>FilterChainProxy</classname>, along with its companion filter |             <classname>FilterChainProxy</classname>, along with its companion filter | ||||||
|                 <classname>ExceptionTranslationFilter</classname>. A typical configuration example |             <classname>ExceptionTranslationFilter</classname>. A typical configuration example is | ||||||
|             is shown below: <programlisting language="xml"><![CDATA[ |             shown below: <programlisting language="xml"><![CDATA[ | ||||||
| <bean id="filterSecurityInterceptor" | <bean id="filterSecurityInterceptor" | ||||||
|       class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor"> |       class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor"> | ||||||
|   <property name="authenticationManager" ref="authenticationManager"/> |   <property name="authenticationManager" ref="authenticationManager"/> | ||||||
|  | @ -31,33 +31,31 @@ | ||||||
|             <interfacename>AuthenticationManager</interfacename> and an |             <interfacename>AuthenticationManager</interfacename> and an | ||||||
|             <interfacename>AccessDecisionManager</interfacename>. It is also supplied with |             <interfacename>AccessDecisionManager</interfacename>. It is also supplied with | ||||||
|             configuration attributes that apply to different HTTP URL requests. Refer back to <link |             configuration attributes that apply to different HTTP URL requests. Refer back to <link | ||||||
|                 xlink:href="#tech-intro-config-attributes">the original discussion on these</link> |             xlink:href="#tech-intro-config-attributes">the original discussion on these</link> in | ||||||
|             in the technical introduction.</para> |             the technical introduction.</para> | ||||||
|         <para>The <classname>FilterSecurityInterceptor</classname> can be configured with |         <para>The <classname>FilterSecurityInterceptor</classname> can be configured with | ||||||
|             configuration attributes in two ways. The first, which is shown above, is using the |             configuration attributes in two ways. The first, which is shown above, is using the | ||||||
|                 <literal><filter-security-metadata-source></literal> namespace element. This |             <literal><filter-security-metadata-source></literal> namespace element. This is | ||||||
|             is similar to the <literal><filter-chain-map></literal> used to configure a |             similar to the <literal><filter-chain-map></literal> used to configure a | ||||||
|                 <classname>FilterChainProxy</classname> but the |             <classname>FilterChainProxy</classname> but the <literal><intercept-url></literal> | ||||||
|                 <literal><intercept-url></literal> child elements only use the |             child elements only use the <literal>pattern</literal> and <literal>access</literal> | ||||||
|                 <literal>pattern</literal> and <literal>access</literal> attributes. Commas are used |             attributes. Commas are used to delimit the different configuration attributes that apply | ||||||
|             to delimit the different configuration attributes that apply to each HTTP URL. The |             to each HTTP URL. The second option is to write your own | ||||||
|             second option is to write your own |  | ||||||
|             <interfacename>SecurityMetadataSource</interfacename>, but this is beyond the scope of |             <interfacename>SecurityMetadataSource</interfacename>, but this is beyond the scope of | ||||||
|             this document. Irrespective of the approach used, the |             this document. Irrespective of the approach used, the | ||||||
|             <interfacename>SecurityMetadataSource</interfacename> is responsible for returning a |             <interfacename>SecurityMetadataSource</interfacename> is responsible for returning a | ||||||
|             <literal>List<ConfigAttribute></literal> containing all of the configuration |             <literal>List<ConfigAttribute></literal> containing all of the configuration | ||||||
|             attributes associated with a single secure HTTP URL.</para> |             attributes associated with a single secure HTTP URL.</para> | ||||||
|         <para>It should be noted that the |         <para>It should be noted that the | ||||||
|                 <literal>FilterSecurityInterceptor.setSecurityMetadataSource()</literal> method |             <literal>FilterSecurityInterceptor.setSecurityMetadataSource()</literal> method actually | ||||||
|             actually expects an instance of |             expects an instance of <interfacename>FilterSecurityMetadataSource</interfacename>. This | ||||||
|                 <interfacename>FilterSecurityMetadataSource</interfacename>. This is a marker |             is a marker interface which subclasses | ||||||
|             interface which subclasses <interfacename>SecurityMetadataSource</interfacename>. It |             <interfacename>SecurityMetadataSource</interfacename>. It simply denotes the | ||||||
|             simply denotes the <interfacename>SecurityMetadataSource</interfacename> understands |             <interfacename>SecurityMetadataSource</interfacename> understands | ||||||
|                 <classname>FilterInvocation</classname>s. In the interests of simplicity we'll |             <classname>FilterInvocation</classname>s. In the interests of simplicity we'll continue | ||||||
|             continue to refer to the |             to refer to the <interfacename>FilterInvocationSecurityMetadataSource</interfacename> as | ||||||
|                 <interfacename>FilterInvocationSecurityMetadataSource</interfacename> as a |             a <interfacename>SecurityMetadataSource</interfacename>, as the distinction is of little | ||||||
|                 <interfacename>SecurityMetadataSource</interfacename>, as the distinction is of |             relevance to most users.</para> | ||||||
|             little relevance to most users.</para> |  | ||||||
|         <para>The <interfacename>SecurityMetadataSource</interfacename> created by the namespace |         <para>The <interfacename>SecurityMetadataSource</interfacename> created by the namespace | ||||||
|             syntax obtains the configuration attributes for a particular |             syntax obtains the configuration attributes for a particular | ||||||
|             <classname>FilterInvocation</classname> by matching the request URL against the |             <classname>FilterInvocation</classname> by matching the request URL against the | ||||||
|  | @ -101,8 +99,7 @@ | ||||||
| --> | --> | ||||||
|     </section> |     </section> | ||||||
|     <section xml:id="exception-translation-filter"> |     <section xml:id="exception-translation-filter"> | ||||||
|         <title> |         <title> <classname>ExceptionTranslationFilter</classname></title> | ||||||
|             <classname>ExceptionTranslationFilter</classname></title> |  | ||||||
|         <para>The <classname>ExceptionTranslationFilter</classname> sits above the |         <para>The <classname>ExceptionTranslationFilter</classname> sits above the | ||||||
|             <classname>FilterSecurityInterceptor</classname> in the security filter stack. It |             <classname>FilterSecurityInterceptor</classname> in the security filter stack. It | ||||||
|             doesn't do any actual security enforcement itself, but handles exceptions thrown by the |             doesn't do any actual security enforcement itself, but handles exceptions thrown by the | ||||||
|  | @ -128,10 +125,10 @@ | ||||||
|             <para> The <interfacename>AuthenticationEntryPoint</interfacename> will be called if the |             <para> The <interfacename>AuthenticationEntryPoint</interfacename> will be called if the | ||||||
|                 user requests a secure HTTP resource but they are not authenticated. An appropriate |                 user requests a secure HTTP resource but they are not authenticated. An appropriate | ||||||
|                 <exceptionname>AuthenticationException</exceptionname> or |                 <exceptionname>AuthenticationException</exceptionname> or | ||||||
|                     <exceptionname>AccessDeniedException</exceptionname> will be thrown by a |                 <exceptionname>AccessDeniedException</exceptionname> will be thrown by a security | ||||||
|                 security interceptor further down the call stack, triggering the |                 interceptor further down the call stack, triggering the | ||||||
|                     <methodname>commence</methodname> method on the entry point. This does the job |                 <methodname>commence</methodname> method on the entry point. This does the job of | ||||||
|                 of presenting the appropriate response to the user so that authentication can begin. |                 presenting the appropriate response to the user so that authentication can begin. | ||||||
|                 The one we've used here is <classname>LoginUrlAuthenticationEntryPoint</classname>, |                 The one we've used here is <classname>LoginUrlAuthenticationEntryPoint</classname>, | ||||||
|                 which redirects the request to a different URL (typically a login page). The actual |                 which redirects the request to a different URL (typically a login page). The actual | ||||||
|                 implementation used will depend on the authentication mechanism you want to be used |                 implementation used will depend on the authentication mechanism you want to be used | ||||||
|  | @ -153,32 +150,31 @@ | ||||||
|             <para>If an <exceptionname>AccessDeniedException</exceptionname> is thrown and a user |             <para>If an <exceptionname>AccessDeniedException</exceptionname> is thrown and a user | ||||||
|                 has already been authenticated, then this means that an operation has been attempted |                 has already been authenticated, then this means that an operation has been attempted | ||||||
|                 for which they don't have enough permissions. In this case, |                 for which they don't have enough permissions. In this case, | ||||||
|                     <classname>ExceptionTranslationFilter</classname> will invoke a second strategy, |                 <classname>ExceptionTranslationFilter</classname> will invoke a second strategy, the | ||||||
|                 the <interfacename>AccessDeniedHandler</interfacename>. By default, an |                 <interfacename>AccessDeniedHandler</interfacename>. By default, an | ||||||
|                 <classname>AccessDeniedHandlerImpl</classname> is used, which just sends a 403 |                 <classname>AccessDeniedHandlerImpl</classname> is used, which just sends a 403 | ||||||
|                 (Forbidden) response to the client. Alternatively you can configure an instance |                 (Forbidden) response to the client. Alternatively you can configure an instance | ||||||
|                 explicitly (as in the above example) and set an error page URL which it will |                 explicitly (as in the above example) and set an error page URL which it will | ||||||
|                 forwards the request to <footnote> |                 forwards the request to <footnote> | ||||||
|                     <para>We use a forward so that the SecurityContextHolder still contains details |                 <para>We use a forward so that the SecurityContextHolder still contains details of | ||||||
|                         of the principal, which may be useful for displaying to the user. In old |                     the principal, which may be useful for displaying to the user. In old releases | ||||||
|                         releases of Spring Security we relied upon the servlet container to handle a |                     of Spring Security we relied upon the servlet container to handle a 403 error | ||||||
|                         403 error message, which lacked this useful contextual information.</para> |                     message, which lacked this useful contextual information.</para> | ||||||
|                 </footnote>. This can be a simple <quote>access denied</quote> page, such as a JSP, |                 </footnote>. This can be a simple <quote>access denied</quote> page, such as a JSP, | ||||||
|                 or it could be a more complex handler such as an MVC controller. And of course, you |                 or it could be a more complex handler such as an MVC controller. And of course, you | ||||||
|                 can implement the interface yourself and use your own implementation. </para> |                 can implement the interface yourself and use your own implementation. </para> | ||||||
|             <para>It's also possible to supply a custom |             <para>It's also possible to supply a custom | ||||||
|                     <interfacename>AccessDeniedHandler</interfacename> when you're using the |                 <interfacename>AccessDeniedHandler</interfacename> when you're using the namespace | ||||||
|                 namespace to configure your application. See <link |                 to configure your application. See <link xlink:href="#nsa-access-denied-handler">the | ||||||
|                     xlink:href="#nsa-access-denied-handler">the namespace appendix</link> for more |                 namespace appendix</link> for more details.</para> | ||||||
|                 details.</para> |  | ||||||
|         </section> |         </section> | ||||||
|     </section> |     </section> | ||||||
|     <section xml:id="security-context-persistence-filter"> |     <section xml:id="security-context-persistence-filter"> | ||||||
|         <title><classname>SecurityContextPersistenceFilter</classname></title> |         <title><classname>SecurityContextPersistenceFilter</classname></title> | ||||||
|         <para> We covered the purpose of this all-important filter in the <link |         <para> We covered the purpose of this all-important filter in the <link | ||||||
|                 xlink:href="#tech-intro-sec-context-persistence">Technical Overview</link> chapter |             xlink:href="#tech-intro-sec-context-persistence">Technical Overview</link> chapter so | ||||||
|             so you might want to re-read that section at this point. Let's first take a look at how |             you might want to re-read that section at this point. Let's first take a look at how you | ||||||
|             you would configure it for use with a <classname>FilterChainProxy</classname>. A basic |             would configure it for use with a <classname>FilterChainProxy</classname>. A basic | ||||||
|             configuration only requires the bean itself <programlisting><![CDATA[ |             configuration only requires the bean itself <programlisting><![CDATA[ | ||||||
| <bean id="securityContextPersistenceFilter" | <bean id="securityContextPersistenceFilter" | ||||||
|   class="org.springframework.security.web.context.SecurityContextPersistenceFilter"/> |   class="org.springframework.security.web.context.SecurityContextPersistenceFilter"/> | ||||||
|  | @ -208,16 +204,16 @@ public interface SecurityContextRepository { | ||||||
|                 <classname>HttpSessionSecurityContextRepository</classname>, which stores the |                 <classname>HttpSessionSecurityContextRepository</classname>, which stores the | ||||||
|                 security context as an <interfacename>HttpSession</interfacename> attribute <footnote> |                 security context as an <interfacename>HttpSession</interfacename> attribute <footnote> | ||||||
|                 <para>In Spring Security 2.0 and earlier, this filter was called |                 <para>In Spring Security 2.0 and earlier, this filter was called | ||||||
|                             <classname>HttpSessionContextIntegrationFilter</classname> and performed |                     <classname>HttpSessionContextIntegrationFilter</classname> and performed all the | ||||||
|                         all the work of storing the context was performed by the filter itself. If |                     work of storing the context was performed by the filter itself. If you were | ||||||
|                         you were familiar with this class, then most of the configuration options |                     familiar with this class, then most of the configuration options which were | ||||||
|                         which were available can now be found on |                     available can now be found on | ||||||
|                     <classname>HttpSessionSecurityContextRepository</classname>. </para> |                     <classname>HttpSessionSecurityContextRepository</classname>. </para> | ||||||
|                 </footnote>. The most important configuration parameter for this implementation is |                 </footnote>. The most important configuration parameter for this implementation is | ||||||
|                 the <literal>allowSessionCreation</literal> property, which defaults to |                 the <literal>allowSessionCreation</literal> property, which defaults to | ||||||
|                     <literal>true</literal>, thus allowing the class to create a session if it needs |                 <literal>true</literal>, thus allowing the class to create a session if it needs one | ||||||
|                 one to store the security context for an authenticated user (it won't create one |                 to store the security context for an authenticated user (it won't create one unless | ||||||
|                 unless authentication has taken place and the contents of the security context have |                 authentication has taken place and the contents of the security context have | ||||||
|                 changed). If you don't want a session to be created, then you can set this property |                 changed). If you don't want a session to be created, then you can set this property | ||||||
|                 to <literal>false</literal>: <programlisting language="xml"><![CDATA[ |                 to <literal>false</literal>: <programlisting language="xml"><![CDATA[ | ||||||
| <bean id="securityContextPersistenceFilter" | <bean id="securityContextPersistenceFilter" | ||||||
|  | @ -243,16 +239,16 @@ class="org.springframework.security.web.context.SecurityContextPersistenceFilter | ||||||
|             something that will allow a user to authenticate. This filter is the most commonly used |             something that will allow a user to authenticate. This filter is the most commonly used | ||||||
|             authentication filter and the one that is most often customized <footnote> |             authentication filter and the one that is most often customized <footnote> | ||||||
|             <para>For historical reasons, prior to Spring Security 3.0, this filter was called |             <para>For historical reasons, prior to Spring Security 3.0, this filter was called | ||||||
|                         <classname>AuthenticationProcessingFilter</classname> and the entry point |                 <classname>AuthenticationProcessingFilter</classname> and the entry point was called | ||||||
|                     was called <classname>AuthenticationProcessingFilterEntryPoint</classname>. |                 <classname>AuthenticationProcessingFilterEntryPoint</classname>. Since the framework | ||||||
|                     Since the framework now supports many different forms of authentication, they |                 now supports many different forms of authentication, they have both been given more | ||||||
|                     have both been given more specific names in 3.0.</para> |                 specific names in 3.0.</para> | ||||||
|             </footnote>. It also provides the implementation used by the |             </footnote>. It also provides the implementation used by the | ||||||
|                 <literal><form-login></literal> element from the namespace. There are three |             <literal><form-login></literal> element from the namespace. There are three stages | ||||||
|             stages required to configure it. <orderedlist> |             required to configure it. <orderedlist> | ||||||
|             <listitem> |             <listitem> | ||||||
|                     <para>Configure a <classname>LoginUrlAuthenticationEntryPoint</classname> with |                 <para>Configure a <classname>LoginUrlAuthenticationEntryPoint</classname> with the | ||||||
|                         the URL of the login page, just as we did above, and set it on the |                     URL of the login page, just as we did above, and set it on the | ||||||
|                     <classname>ExceptionTranslationFilter</classname>. </para> |                     <classname>ExceptionTranslationFilter</classname>. </para> | ||||||
|             </listitem> |             </listitem> | ||||||
|             <listitem> |             <listitem> | ||||||
|  | @ -260,17 +256,17 @@ class="org.springframework.security.web.context.SecurityContextPersistenceFilter | ||||||
|             </listitem> |             </listitem> | ||||||
|             <listitem> |             <listitem> | ||||||
|                 <para>Configure an instance of |                 <para>Configure an instance of | ||||||
|                             <classname>UsernamePasswordAuthenticationFilter</classname> in the |                     <classname>UsernamePasswordAuthenticationFilter</classname> in the application | ||||||
|                         application context</para> |                     context</para> | ||||||
|             </listitem> |             </listitem> | ||||||
|             <listitem> |             <listitem> | ||||||
|                     <para>Add the filter bean to your filter chain proxy (making sure you pay |                 <para>Add the filter bean to your filter chain proxy (making sure you pay attention | ||||||
|                         attention to the order). <!-- TODO: link --></para> |                     to the order). <!-- TODO: link --></para> | ||||||
|             </listitem> |             </listitem> | ||||||
|             </orderedlist> The login form simply contains <literal>j_username</literal> and |             </orderedlist> The login form simply contains <literal>j_username</literal> and | ||||||
|                 <literal>j_password</literal> input fields, and posts to the URL that is monitored |             <literal>j_password</literal> input fields, and posts to the URL that is monitored by | ||||||
|             by the filter (by default this is <literal>/j_spring_security_check</literal>). The |             the filter (by default this is <literal>/j_spring_security_check</literal>). The basic | ||||||
|             basic filter configuration looks something like this: <programlisting><![CDATA[ |             filter configuration looks something like this: <programlisting><![CDATA[ | ||||||
| <bean id="authenticationFilter" class= | <bean id="authenticationFilter" class= | ||||||
| "org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"> | "org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"> | ||||||
|   <property name="authenticationManager" ref="authenticationManager"/> |   <property name="authenticationManager" ref="authenticationManager"/> | ||||||
|  | @ -280,38 +276,37 @@ class="org.springframework.security.web.context.SecurityContextPersistenceFilter | ||||||
|         <section xml:id="form-login-flow-handling"> |         <section xml:id="form-login-flow-handling"> | ||||||
|             <title>Application Flow on Authentication Success and Failure</title> |             <title>Application Flow on Authentication Success and Failure</title> | ||||||
|             <para> The filter calls the configured |             <para> The filter calls the configured | ||||||
|                     <interfacename>AuthenticationManager</interfacename> to process each |                 <interfacename>AuthenticationManager</interfacename> to process each authentication | ||||||
|                 authentication request. The destination following a successful authentication or an |                 request. The destination following a successful authentication or an authentication | ||||||
|                 authentication failure is controlled by the |                 failure is controlled by the | ||||||
|                 <interfacename>AuthenticationSuccessHandler</interfacename> and |                 <interfacename>AuthenticationSuccessHandler</interfacename> and | ||||||
|                 <interfacename>AuthenticationFailureHandler</interfacename> strategy interfaces, |                 <interfacename>AuthenticationFailureHandler</interfacename> strategy interfaces, | ||||||
|                 respectively. The filter has properties which allow you to set these so you can |                 respectively. The filter has properties which allow you to set these so you can | ||||||
|                 customize the behaviour completely <footnote> |                 customize the behaviour completely <footnote> | ||||||
|                     <para>In versions prior to 3.0, the application flow at this point had evolved |                 <para>In versions prior to 3.0, the application flow at this point had evolved to a | ||||||
|                         to a stage was controlled by a mix of properties on this class and strategy |                     stage was controlled by a mix of properties on this class and strategy plugins. | ||||||
|                         plugins. The decision was made for 3.0 to refactor the code to make these |                     The decision was made for 3.0 to refactor the code to make these two strategies | ||||||
|                         two strategies entirely responsible. </para> |                     entirely responsible. </para> | ||||||
|                 </footnote>. Some standard implementations are supplied such as |                 </footnote>. Some standard implementations are supplied such as | ||||||
|                 <classname>SimpleUrlAuthenticationSuccessHandler</classname>, |                 <classname>SimpleUrlAuthenticationSuccessHandler</classname>, | ||||||
|                 <classname>SavedRequestAwareAuthenticationSuccessHandler</classname>, |                 <classname>SavedRequestAwareAuthenticationSuccessHandler</classname>, | ||||||
|                 <classname>SimpleUrlAuthenticationFailureHandler</classname> and |                 <classname>SimpleUrlAuthenticationFailureHandler</classname> and | ||||||
|                     <classname>ExceptionMappingAuthenticationFailureHandler</classname>. Have a look |                 <classname>ExceptionMappingAuthenticationFailureHandler</classname>. Have a look at | ||||||
|                 at the Javadoc for these classes to see how they work. </para> |                 the Javadoc for these classes to see how they work. </para> | ||||||
|             <para>If authentication is successful, the resulting |             <para>If authentication is successful, the resulting | ||||||
|                 <interfacename>Authentication</interfacename> object will be placed into the |                 <interfacename>Authentication</interfacename> object will be placed into the | ||||||
|                 <classname>SecurityContextHolder</classname>. The configured |                 <classname>SecurityContextHolder</classname>. The configured | ||||||
|                     <interfacename>AuthenticationSuccessHandler</interfacename> will then be called |                 <interfacename>AuthenticationSuccessHandler</interfacename> will then be called to | ||||||
|                 to either redirect or forward the user to the appropriate destination. By default a |                 either redirect or forward the user to the appropriate destination. By default a | ||||||
|                     <classname>SavedRequestAwareAuthenticationSuccessHandler</classname> is used, |                 <classname>SavedRequestAwareAuthenticationSuccessHandler</classname> is used, which | ||||||
|                 which means that the user will be redirected to the original destination they |                 means that the user will be redirected to the original destination they requested | ||||||
|                 requested before they were asked to login. <note> |                 before they were asked to login. <note> | ||||||
|                 <para> The <classname>ExceptionTranslationFilter</classname> caches the original |                 <para> The <classname>ExceptionTranslationFilter</classname> caches the original | ||||||
|                         request a user makes. When the user authenticates, the request handler makes |                     request a user makes. When the user authenticates, the request handler makes use | ||||||
|                         use of this cached request to obtain the original URL and redirect to it. |                     of this cached request to obtain the original URL and redirect to it. The | ||||||
|                         The original request is then rebuilt and used as an alternative. </para> |                     original request is then rebuilt and used as an alternative. </para> | ||||||
|                 </note> If authentication fails, the configured |                 </note> If authentication fails, the configured | ||||||
|                     <interfacename>AuthenticationFailureHandler</interfacename> will be invoked. |                 <interfacename>AuthenticationFailureHandler</interfacename> will be invoked. </para> | ||||||
|             </para> |  | ||||||
|         </section> |         </section> | ||||||
|     </section> |     </section> | ||||||
| </chapter> | </chapter> | ||||||
|  |  | ||||||
|  | @ -5,9 +5,9 @@ | ||||||
|         classes, let's take a closer look at one or two of the core interfaces and their |         classes, let's take a closer look at one or two of the core interfaces and their | ||||||
|         implementations, in particular the <interfacename>AuthenticationManager</interfacename>, |         implementations, in particular the <interfacename>AuthenticationManager</interfacename>, | ||||||
|         <interfacename>UserDetailsService</interfacename> and the |         <interfacename>UserDetailsService</interfacename> and the | ||||||
|             <interfacename>AccessDecisionManager</interfacename>. These crop up regularly throughout |         <interfacename>AccessDecisionManager</interfacename>. These crop up regularly throughout the | ||||||
|         the remainder of this document so it's important you know how they are configured and how |         remainder of this document so it's important you know how they are configured and how they | ||||||
|         they operate. </para> |         operate. </para> | ||||||
|     <section xml:id="core-services-authentication-manager"> |     <section xml:id="core-services-authentication-manager"> | ||||||
|         <title>The <interfacename>AuthenticationManager</interfacename>, |         <title>The <interfacename>AuthenticationManager</interfacename>, | ||||||
|             <classname>ProviderManager</classname> and |             <classname>ProviderManager</classname> and | ||||||
|  | @ -19,27 +19,25 @@ | ||||||
|         <para>The default implementation in Spring Security is called |         <para>The default implementation in Spring Security is called | ||||||
|             <classname>ProviderManager</classname> and rather than handling the authentication |             <classname>ProviderManager</classname> and rather than handling the authentication | ||||||
|             request itself, it delegates to a list of configured |             request itself, it delegates to a list of configured | ||||||
|                 <classname>AuthenticationProvider</classname>s, each of which is queried in turn to |             <classname>AuthenticationProvider</classname>s, each of which is queried in turn to see | ||||||
|             see if it can perform the authentication. Each provider will either throw an exception |             if it can perform the authentication. Each provider will either throw an exception or | ||||||
|             or return a fully populated <interfacename>Authentication</interfacename> object. |             return a fully populated <interfacename>Authentication</interfacename> object. Remember | ||||||
|             Remember our good friends, <interfacename>UserDetails</interfacename> and |             our good friends, <interfacename>UserDetails</interfacename> and | ||||||
|             <interfacename>UserDetailsService</interfacename>? If not, head back to the previous |             <interfacename>UserDetailsService</interfacename>? If not, head back to the previous | ||||||
|             chapter and refresh your memory. The most common approach to verifying an authentication |             chapter and refresh your memory. The most common approach to verifying an authentication | ||||||
|             request is to load the corresponding <interfacename>UserDetails</interfacename> and |             request is to load the corresponding <interfacename>UserDetails</interfacename> and | ||||||
|             check the loaded password against the one that has been entered by the user. This is the |             check the loaded password against the one that has been entered by the user. This is the | ||||||
|             approach used by the <classname>DaoAuthenticationProvider</classname> (see below). The |             approach used by the <classname>DaoAuthenticationProvider</classname> (see below). The | ||||||
|             loaded <interfacename>UserDetails</interfacename> object - and particularly the |             loaded <interfacename>UserDetails</interfacename> object - and particularly the | ||||||
|                 <literal>GrantedAuthority</literal>s it contains - will be used when building the |             <literal>GrantedAuthority</literal>s it contains - will be used when building the fully | ||||||
|             fully populated <interfacename>Authentication</interfacename> object which is returned |             populated <interfacename>Authentication</interfacename> object which is returned from a | ||||||
|             from a successful authentication and stored in the |             successful authentication and stored in the <classname>SecurityContext</classname>. </para> | ||||||
|                 <classname>SecurityContext</classname>. </para> |         <para> If you are using the namespace, an instance of <classname>ProviderManager</classname> | ||||||
|         <para> If you are using the namespace, an instance of |             is created and maintained internally, and you add providers to it by using the namespace | ||||||
|                 <classname>ProviderManager</classname> is created and maintained internally, and |             authentication provider elements (see <link xlink:href="#ns-auth-manager">the namespace | ||||||
|             you add providers to it by using the namespace authentication provider elements |             chapter</link>). In this case, you should not declare a | ||||||
|             (see <link xlink:href="#ns-auth-manager">the namespace chapter</link>). In this |             <classname>ProviderManager</classname> bean in your application context. However, if you | ||||||
|             case, you should not declare a <classname>ProviderManager</classname> bean in your |             are not using the namespace then you would declare it like so: <programlisting language="xml"><![CDATA[ | ||||||
|             application context. However, if you are not using the namespace then you would declare |  | ||||||
|             it like so: <programlisting language="xml"><![CDATA[ |  | ||||||
| <bean id="authenticationManager" | <bean id="authenticationManager" | ||||||
|      class="org.springframework.security.authentication.ProviderManager"> |      class="org.springframework.security.authentication.ProviderManager"> | ||||||
|   <property name="providers"> |   <property name="providers"> | ||||||
|  | @ -78,12 +76,12 @@ | ||||||
|             <para>The simplest <interfacename>AuthenticationProvider</interfacename> implemented by |             <para>The simplest <interfacename>AuthenticationProvider</interfacename> implemented by | ||||||
|                 Spring Security is <literal>DaoAuthenticationProvider</literal>, which is also one |                 Spring Security is <literal>DaoAuthenticationProvider</literal>, which is also one | ||||||
|                 of the earliest supported by the framework. It leverages a |                 of the earliest supported by the framework. It leverages a | ||||||
|                     <interfacename>UserDetailsService</interfacename> (as a DAO) in order to lookup |                 <interfacename>UserDetailsService</interfacename> (as a DAO) in order to lookup the | ||||||
|                 the username, password and <interfacename>GrantedAuthority</interfacename>s. It |                 username, password and <interfacename>GrantedAuthority</interfacename>s. It | ||||||
|                 authenticates the user simply by comparing the password submitted in a |                 authenticates the user simply by comparing the password submitted in a | ||||||
|                     <classname>UsernamePasswordAuthenticationToken</classname> against the one |                 <classname>UsernamePasswordAuthenticationToken</classname> against the one loaded by | ||||||
|                 loaded by the <interfacename>UserDetailsService</interfacename>. Configuring the |                 the <interfacename>UserDetailsService</interfacename>. Configuring the provider is | ||||||
|                 provider is quite simple: <programlisting language="xml"><![CDATA[ |                 quite simple: <programlisting language="xml"><![CDATA[ | ||||||
| <bean id="daoAuthenticationProvider" | <bean id="daoAuthenticationProvider" | ||||||
|     class="org.springframework.security.authentication.dao.DaoAuthenticationProvider"> |     class="org.springframework.security.authentication.dao.DaoAuthenticationProvider"> | ||||||
|   <property name="userDetailsService" ref="inMemoryDaoImpl"/> |   <property name="userDetailsService" ref="inMemoryDaoImpl"/> | ||||||
|  | @ -94,8 +92,8 @@ | ||||||
|                 <interfacename>PasswordEncoder</interfacename> provides encoding and decoding of |                 <interfacename>PasswordEncoder</interfacename> provides encoding and decoding of | ||||||
|                 passwords presented in the <interfacename>UserDetails</interfacename> object that is |                 passwords presented in the <interfacename>UserDetails</interfacename> object that is | ||||||
|                 returned from the configured <interfacename>UserDetailsService</interfacename>. A |                 returned from the configured <interfacename>UserDetailsService</interfacename>. A | ||||||
|                     <interfacename>SaltSource</interfacename> enables the passwords to be populated |                 <interfacename>SaltSource</interfacename> enables the passwords to be populated with | ||||||
|                 with a "salt", which enhances the security of the passwords in the authentication |                 a "salt", which enhances the security of the passwords in the authentication | ||||||
|                 repository. These will be discussed in more detail <link |                 repository. These will be discussed in more detail <link | ||||||
|                 xlink:href="core-services-password-encodin">below</link>. </para> |                 xlink:href="core-services-password-encodin">below</link>. </para> | ||||||
|         </section> |         </section> | ||||||
|  | @ -104,23 +102,21 @@ | ||||||
|         <title><interfacename>UserDetailsService</interfacename> Implementations</title> |         <title><interfacename>UserDetailsService</interfacename> Implementations</title> | ||||||
|         <para>As mentioned in the earlier in this reference guide, most authentication providers |         <para>As mentioned in the earlier in this reference guide, most authentication providers | ||||||
|             take advantage of the <interfacename>UserDetails</interfacename> and |             take advantage of the <interfacename>UserDetails</interfacename> and | ||||||
|                 <interfacename>UserDetailsService</interfacename> interfaces. Recall that the |             <interfacename>UserDetailsService</interfacename> interfaces. Recall that the contract | ||||||
|             contract for <interfacename>UserDetailsService</interfacename> is a single |             for <interfacename>UserDetailsService</interfacename> is a single method:</para> | ||||||
|             method:</para> |  | ||||||
|         <para> |         <para> | ||||||
|             <programlisting> |             <programlisting> | ||||||
|   UserDetails loadUserByUsername(String username) throws UsernameNotFoundException; |   UserDetails loadUserByUsername(String username) throws UsernameNotFoundException; | ||||||
|             </programlisting> |             </programlisting> </para> | ||||||
|         </para> |  | ||||||
|         <para>The returned <interfacename>UserDetails</interfacename> is an interface that provides |         <para>The returned <interfacename>UserDetails</interfacename> is an interface that provides | ||||||
|             getters that guarantee non-null provision of authentication information such as the |             getters that guarantee non-null provision of authentication information such as the | ||||||
|             username, password, granted authorities and whether the user account is enabled or |             username, password, granted authorities and whether the user account is enabled or | ||||||
|             disabled. Most authentication providers will use a |             disabled. Most authentication providers will use a | ||||||
|                 <interfacename>UserDetailsService</interfacename>, even if the username and password |             <interfacename>UserDetailsService</interfacename>, even if the username and password are | ||||||
|             are not actually used as part of the authentication decision. They may use the returned |             not actually used as part of the authentication decision. They may use the returned | ||||||
|             <interfacename>UserDetails</interfacename> object just for its |             <interfacename>UserDetails</interfacename> object just for its | ||||||
|                 <literal>GrantedAuthority</literal> information, because some other system (like |             <literal>GrantedAuthority</literal> information, because some other system (like LDAP or | ||||||
|             LDAP or X.509 or CAS etc) has undertaken the responsibility of actually validating the |             X.509 or CAS etc) has undertaken the responsibility of actually validating the | ||||||
|             credentials.</para> |             credentials.</para> | ||||||
|         <para>Given <interfacename>UserDetailsService</interfacename> is so simple to implement, it |         <para>Given <interfacename>UserDetailsService</interfacename> is so simple to implement, it | ||||||
|             should be easy for users to retrieve authentication information using a persistence |             should be easy for users to retrieve authentication information using a persistence | ||||||
|  | @ -133,8 +129,8 @@ | ||||||
|                 many applications do not require such complexity. This is particularly true if |                 many applications do not require such complexity. This is particularly true if | ||||||
|                 you're building a prototype application or just starting integrating Spring |                 you're building a prototype application or just starting integrating Spring | ||||||
|                 Security, when you don't really want to spend time configuring databases or writing |                 Security, when you don't really want to spend time configuring databases or writing | ||||||
|                     <interfacename>UserDetailsService</interfacename> implementations. For this sort |                 <interfacename>UserDetailsService</interfacename> implementations. For this sort of | ||||||
|                 of situation, a simple option is to use the <literal>user-service</literal> element |                 situation, a simple option is to use the <literal>user-service</literal> element | ||||||
|                 from the security <link xlink:href="#ns-minimal">namespace</link>: <programlisting><![CDATA[ |                 from the security <link xlink:href="#ns-minimal">namespace</link>: <programlisting><![CDATA[ | ||||||
|   <user-service id="userDetailsService"> |   <user-service id="userDetailsService"> | ||||||
|     <user name="jimi" password="jimispassword" authorities="ROLE_USER, ROLE_ADMIN" /> |     <user name="jimi" password="jimispassword" authorities="ROLE_USER, ROLE_ADMIN" /> | ||||||
|  | @ -158,11 +154,10 @@ | ||||||
|                 Spring JDBC is used, so it avoids the complexity of a fully-featured object |                 Spring JDBC is used, so it avoids the complexity of a fully-featured object | ||||||
|                 relational mapper (ORM) just to store user details. If your application does use an |                 relational mapper (ORM) just to store user details. If your application does use an | ||||||
|                 ORM tool, you might prefer to write a custom |                 ORM tool, you might prefer to write a custom | ||||||
|                     <interfacename>UserDetailsService</interfacename> to reuse the mapping files |                 <interfacename>UserDetailsService</interfacename> to reuse the mapping files you've | ||||||
|                 you've probably already created. Returning to <literal>JdbcDaoImpl</literal>, an |                 probably already created. Returning to <literal>JdbcDaoImpl</literal>, an example | ||||||
|                 example configuration is shown below:</para> |                 configuration is shown below:</para> | ||||||
|             <para> |             <para> <programlisting language="xml"><![CDATA[ | ||||||
|                 <programlisting language="xml"><![CDATA[ |  | ||||||
| <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> | <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> | ||||||
|   <property name="driverClassName" value="org.hsqldb.jdbcDriver"/> |   <property name="driverClassName" value="org.hsqldb.jdbcDriver"/> | ||||||
|   <property name="url" value="jdbc:hsqldb:hsql://localhost:9001"/> |   <property name="url" value="jdbc:hsqldb:hsql://localhost:9001"/> | ||||||
|  | @ -173,19 +168,17 @@ | ||||||
| <bean id="userDetailsService" | <bean id="userDetailsService" | ||||||
|       class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl"> |       class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl"> | ||||||
|   <property name="dataSource" ref="dataSource"/> |   <property name="dataSource" ref="dataSource"/> | ||||||
| </bean> ]]>       </programlisting> | </bean> ]]>       </programlisting> </para> | ||||||
|             </para> |  | ||||||
|             <para>You can use different relational database management systems by modifying the |             <para>You can use different relational database management systems by modifying the | ||||||
|                     <literal>DriverManagerDataSource</literal> shown above. You can also use a |                 <literal>DriverManagerDataSource</literal> shown above. You can also use a global | ||||||
|                 global data source obtained from JNDI, as with any other Spring |                 data source obtained from JNDI, as with any other Spring configuration.</para> | ||||||
|                 configuration.</para> |  | ||||||
|             <section> |             <section> | ||||||
|                 <title>Authority Groups</title> |                 <title>Authority Groups</title> | ||||||
|                 <para>By default, <classname>JdbcDaoImpl</classname> loads the authorities for a |                 <para>By default, <classname>JdbcDaoImpl</classname> loads the authorities for a | ||||||
|                     single user with the assumption that the authorities are mapped directly to |                     single user with the assumption that the authorities are mapped directly to | ||||||
|                     users (see the <link xlink:href="#appendix-schema">database schema |                     users (see the <link xlink:href="#appendix-schema">database schema | ||||||
|                         appendix</link>). An alternative approach is to partition the authorities |                     appendix</link>). An alternative approach is to partition the authorities into | ||||||
|                     into groups and assign groups to the user. Some people prefer this approach as a |                     groups and assign groups to the user. Some people prefer this approach as a | ||||||
|                     means of administering user rights. See the <classname>JdbcDaoImpl</classname> |                     means of administering user rights. See the <classname>JdbcDaoImpl</classname> | ||||||
|                     Javadoc for more information on how to enable the use of group authorities. The |                     Javadoc for more information on how to enable the use of group authorities. The | ||||||
|                     group schema is also included in the appendix.</para> |                     group schema is also included in the appendix.</para> | ||||||
|  | @ -231,14 +224,14 @@ | ||||||
|             <para> One potential problem with the use of password hashes that it is relatively easy |             <para> One potential problem with the use of password hashes that it is relatively easy | ||||||
|                 to get round the one-way property of the hash if a common word is used for the |                 to get round the one-way property of the hash if a common word is used for the | ||||||
|                 input. For example, if you search for the hash value |                 input. For example, if you search for the hash value | ||||||
|                     <literal>5f4dcc3b5aa765d61d8327deb882cf99</literal> using google, you will |                 <literal>5f4dcc3b5aa765d61d8327deb882cf99</literal> using google, you will quickly | ||||||
|                 quickly find the original word <quote>password</quote>. In a similar way, an |                 find the original word <quote>password</quote>. In a similar way, an attacker can | ||||||
|                 attacker can build a dictionary of hashes from a standard word list and use this to |                 build a dictionary of hashes from a standard word list and use this to lookup the | ||||||
|                 lookup the original password. One way to help prevent this is to have a suitably |                 original password. One way to help prevent this is to have a suitably strong | ||||||
|                 strong password policy to try to prevent common words from being used. Another is to |                 password policy to try to prevent common words from being used. Another is to use a | ||||||
|                 use a <quote>salt</quote> when calculating the hashes. This is an additional string |                 <quote>salt</quote> when calculating the hashes. This is an additional string of | ||||||
|                 of known data for each user which is combined with the password before calculating |                 known data for each user which is combined with the password before calculating the | ||||||
|                 the hash. Ideally the data should be as random as possible, but in practice any salt |                 hash. Ideally the data should be as random as possible, but in practice any salt | ||||||
|                 value is usually preferable to none. Spring Security has a |                 value is usually preferable to none. Spring Security has a | ||||||
|                 <interfacename>SaltSource</interfacename> interface which can be used by an |                 <interfacename>SaltSource</interfacename> interface which can be used by an | ||||||
|                 authentication provider to generate a salt value for a particular user. Using a salt |                 authentication provider to generate a salt value for a particular user. Using a salt | ||||||
|  | @ -248,31 +241,31 @@ | ||||||
|         <section> |         <section> | ||||||
|             <title> Hashing and Authentication</title> |             <title> Hashing and Authentication</title> | ||||||
|             <para>When an authentication provider (such as Spring Security's |             <para>When an authentication provider (such as Spring Security's | ||||||
|                     <classname>DaoAuthenticationProvider</classname> needs to check the password in |                 <classname>DaoAuthenticationProvider</classname> needs to check the password in a | ||||||
|                 a submitted authentication request against the known value for a user, and the |                 submitted authentication request against the known value for a user, and the stored | ||||||
|                 stored password is encoded in some way, then the submitted value must be encoded |                 password is encoded in some way, then the submitted value must be encoded using | ||||||
|                 using exactly the same algorithm. It's up to you to check that these are compatible |                 exactly the same algorithm. It's up to you to check that these are compatible as | ||||||
|                 as Spring Security has no control over the persistent values. If you add password |                 Spring Security has no control over the persistent values. If you add password | ||||||
|                 hashing to your authentication configuration in Spring Security, and your database |                 hashing to your authentication configuration in Spring Security, and your database | ||||||
|                 contains plaintext passwords, then there is no way authentication can succeed. Even |                 contains plaintext passwords, then there is no way authentication can succeed. Even | ||||||
|                 if you are aware that your database is using MD5 to encode the passwords, for |                 if you are aware that your database is using MD5 to encode the passwords, for | ||||||
|                 example, and your application is configured to use Spring Security's |                 example, and your application is configured to use Spring Security's | ||||||
|                     <classname>Md5PasswordEncoder</classname>, there are still things that can go |                 <classname>Md5PasswordEncoder</classname>, there are still things that can go wrong. | ||||||
|                 wrong. The database may have the passwords encoded in Base 64, for example while the |                 The database may have the passwords encoded in Base 64, for example while the | ||||||
|                 enocoder is using hexadecimal strings (the default)<footnote><para>You can configure |                 enocoder is using hexadecimal strings (the default)<footnote> | ||||||
|                         the encoder to use Base 64 instead of hex by setting the |                 <para>You can configure the encoder to use Base 64 instead of hex by setting the | ||||||
|                             <literal>encodeHashAsBase64</literal> property to |                     <literal>encodeHashAsBase64</literal> property to <literal>true</literal>. Check | ||||||
|                             <literal>true</literal>. Check the Javadoc for |                     the Javadoc for <classname>MessageDigestPasswordEncoder</classname> and its | ||||||
|                             <classname>MessageDigestPasswordEncoder</classname> and its parent |                     parent classes for more information.</para> | ||||||
|                         classes for more information.</para></footnote>. Alternatively your database |                 </footnote>. Alternatively your database may be using upper-case while the output | ||||||
|                 may be using upper-case while the output from the encoder is lower-case. Make sure |                 from the encoder is lower-case. Make sure you write a test to check the output from | ||||||
|                 you write a test to check the output from your configured password encoder with a |                 your configured password encoder with a known password and salt combination and | ||||||
|                 known password and salt combination and check that it matches the database value |                 check that it matches the database value before going further and attempting to | ||||||
|                 before going further and attempting to authenticate through your application. For |                 authenticate through your application. For more information on the default method | ||||||
|                 more information on the default method for merging salt and password, see the |                 for merging salt and password, see the Javadoc for | ||||||
|                 Javadoc for <classname>BasePasswordEncoder</classname>. If you want to generate |                 <classname>BasePasswordEncoder</classname>. If you want to generate encoded | ||||||
|                 encoded passwords directly in Java for storage in your user database, then you can |                 passwords directly in Java for storage in your user database, then you can use the | ||||||
|                 use the <methodname>encodePassword</methodname> method on the |                 <methodname>encodePassword</methodname> method on the | ||||||
|                 <interfacename>PasswordEncoder</interfacename>.</para> |                 <interfacename>PasswordEncoder</interfacename>.</para> | ||||||
|         </section> |         </section> | ||||||
|     </section> |     </section> | ||||||
|  |  | ||||||
|  | @ -8,8 +8,8 @@ | ||||||
|         </info> |         </info> | ||||||
|         <para>Spring Security includes a production-quality |         <para>Spring Security includes a production-quality | ||||||
|             <classname>AuthenticationProvider</classname> implementation called |             <classname>AuthenticationProvider</classname> implementation called | ||||||
|                 <literal>DaoAuthenticationProvider</literal>. This authentication provider is |             <literal>DaoAuthenticationProvider</literal>. This authentication provider is compatible | ||||||
|             compatible with all of the authentication mechanisms that generate a |             with all of the authentication mechanisms that generate a | ||||||
|             <literal>UsernamePasswordAuthenticationToken</literal>, and is probably the most |             <literal>UsernamePasswordAuthenticationToken</literal>, and is probably the most | ||||||
|             commonly used provider in the framework. Like most of the other authentication |             commonly used provider in the framework. Like most of the other authentication | ||||||
|             providers, the DaoAuthenticationProvider leverages a UserDetailsService in order to |             providers, the DaoAuthenticationProvider leverages a UserDetailsService in order to | ||||||
|  | @ -27,8 +27,7 @@ | ||||||
|             at the start of this part of the reference guide), and ensuring a suitable |             at the start of this part of the reference guide), and ensuring a suitable | ||||||
|             authentication mechanism is configured to present a UsernamePasswordAuthenticationToken, |             authentication mechanism is configured to present a UsernamePasswordAuthenticationToken, | ||||||
|             the configuration of the provider itself is rather simple:</para> |             the configuration of the provider itself is rather simple:</para> | ||||||
|         <para> |         <para> <programlisting> | ||||||
|             <programlisting> |  | ||||||
|         <![CDATA[ |         <![CDATA[ | ||||||
| <bean id="daoAuthenticationProvider" | <bean id="daoAuthenticationProvider" | ||||||
|     class="org.springframework.security.authentication.dao.DaoAuthenticationProvider"> |     class="org.springframework.security.authentication.dao.DaoAuthenticationProvider"> | ||||||
|  | @ -36,14 +35,13 @@ | ||||||
|   <property name="saltSource" ref bean="saltSource"/> |   <property name="saltSource" ref bean="saltSource"/> | ||||||
|   <property name="passwordEncoder" ref="passwordEncoder"/> |   <property name="passwordEncoder" ref="passwordEncoder"/> | ||||||
| </bean>  ]]> | </bean>  ]]> | ||||||
|     </programlisting> |     </programlisting> </para> | ||||||
|         </para> |  | ||||||
|         <para>The <literal>PasswordEncoder</literal> and <literal>SaltSource</literal> are optional. |         <para>The <literal>PasswordEncoder</literal> and <literal>SaltSource</literal> are optional. | ||||||
|             A <literal>PasswordEncoder</literal> provides encoding and decoding of passwords |             A <literal>PasswordEncoder</literal> provides encoding and decoding of passwords | ||||||
|             presented in the <interfacename>UserDetails</interfacename> object that is returned from |             presented in the <interfacename>UserDetails</interfacename> object that is returned from | ||||||
|             the configured <interfacename>UserDetailsService</interfacename>. A |             the configured <interfacename>UserDetailsService</interfacename>. A | ||||||
|                 <literal>SaltSource</literal> enables the passwords to be populated with a "salt", |             <literal>SaltSource</literal> enables the passwords to be populated with a "salt", which | ||||||
|             which enhances the security of the passwords in the authentication repository. |             enhances the security of the passwords in the authentication repository. | ||||||
|             <literal>PasswordEncoder</literal> implementations are provided with Spring Security |             <literal>PasswordEncoder</literal> implementations are provided with Spring Security | ||||||
|             covering MD5, SHA and cleartext encodings. Two <literal>SaltSource</literal> |             covering MD5, SHA and cleartext encodings. Two <literal>SaltSource</literal> | ||||||
|             implementations are also provided: <literal>SystemWideSaltSource</literal> which encodes |             implementations are also provided: <literal>SystemWideSaltSource</literal> which encodes | ||||||
|  | @ -55,14 +53,12 @@ | ||||||
|             supports optional caching of <interfacename>UserDetails</interfacename> objects. The |             supports optional caching of <interfacename>UserDetails</interfacename> objects. The | ||||||
|             <literal>UserCache</literal> interface enables the |             <literal>UserCache</literal> interface enables the | ||||||
|             <literal>DaoAuthenticationProvider</literal> to place a |             <literal>DaoAuthenticationProvider</literal> to place a | ||||||
|                 <interfacename>UserDetails</interfacename> object into the cache, and retrieve it |             <interfacename>UserDetails</interfacename> object into the cache, and retrieve it from | ||||||
|             from the cache upon subsequent authentication attempts for the same username. By default |             the cache upon subsequent authentication attempts for the same username. By default the | ||||||
|             the <literal>DaoAuthenticationProvider</literal> uses the |             <literal>DaoAuthenticationProvider</literal> uses the <literal>NullUserCache</literal>, | ||||||
|                 <literal>NullUserCache</literal>, which performs no caching. A usable caching |             which performs no caching. A usable caching implementation is also provided, | ||||||
|             implementation is also provided, <literal>EhCacheBasedUserCache</literal>, which is |             <literal>EhCacheBasedUserCache</literal>, which is configured as follows:</para> | ||||||
|             configured as follows:</para> |         <para> <programlisting><![CDATA[ | ||||||
|         <para> |  | ||||||
|             <programlisting><![CDATA[ |  | ||||||
| <bean id="daoAuthenticationProvider" | <bean id="daoAuthenticationProvider" | ||||||
|     class="org.springframework.security.authentication.dao.DaoAuthenticationProvider"> |     class="org.springframework.security.authentication.dao.DaoAuthenticationProvider"> | ||||||
|   <property name="userDetailsService" ref="userDetailsService"/> |   <property name="userDetailsService" ref="userDetailsService"/> | ||||||
|  | @ -82,15 +78,14 @@ | ||||||
|     class="org.springframework.security.core.userdetails.cache.EhCacheBasedUserCache"> |     class="org.springframework.security.core.userdetails.cache.EhCacheBasedUserCache"> | ||||||
|   <property name="cache" ref="userCacheBackend"/> |   <property name="cache" ref="userCacheBackend"/> | ||||||
| </bean>]]> | </bean>]]> | ||||||
|     </programlisting> |     </programlisting> </para> | ||||||
|         </para> |  | ||||||
|         <para>All Spring Security EH-CACHE implementations (including |         <para>All Spring Security EH-CACHE implementations (including | ||||||
|                 <literal>EhCacheBasedUserCache</literal>) require an EH-CACHE |             <literal>EhCacheBasedUserCache</literal>) require an EH-CACHE <literal>Cache</literal> | ||||||
|                 <literal>Cache</literal> object. The <literal>Cache</literal> object can be obtained |             object. The <literal>Cache</literal> object can be obtained from wherever you like, | ||||||
|             from wherever you like, although we recommend you use Spring's factory classes as shown |             although we recommend you use Spring's factory classes as shown in the above | ||||||
|             in the above configuration. If using Spring's factory classes, please refer to the |             configuration. If using Spring's factory classes, please refer to the Spring | ||||||
|             Spring documentation for further details on how to optimise the cache storage location, |             documentation for further details on how to optimise the cache storage location, memory | ||||||
|             memory usage, eviction policies, timeouts etc.</para> |             usage, eviction policies, timeouts etc.</para> | ||||||
|         <note> |         <note> | ||||||
|             <para>In the majority of cases, where your application is a stateful web application, |             <para>In the majority of cases, where your application is a stateful web application, | ||||||
|                 you don't need to use a cache as the user's authentication information will be |                 you don't need to use a cache as the user's authentication information will be | ||||||
|  |  | ||||||
|  | @ -9,9 +9,9 @@ | ||||||
|         <para>Complex applications often will find the need to define access permissions not simply |         <para>Complex applications often will find the need to define access permissions not simply | ||||||
|             at a web request or method invocation level. Instead, security decisions need to |             at a web request or method invocation level. Instead, security decisions need to | ||||||
|             comprise both who (<interfacename>Authentication</interfacename>), where |             comprise both who (<interfacename>Authentication</interfacename>), where | ||||||
|             (<classname>MethodInvocation</classname>) and what (<literal>SomeDomainObject</literal>). In |             (<classname>MethodInvocation</classname>) and what | ||||||
|             other words, authorization decisions also need to consider the actual domain object |             (<literal>SomeDomainObject</literal>). In other words, authorization decisions also need | ||||||
|             instance subject of a method invocation.</para> |             to consider the actual domain object instance subject of a method invocation.</para> | ||||||
|         <para>Imagine you're designing an application for a pet clinic. There will be two main |         <para>Imagine you're designing an application for a pet clinic. There will be two main | ||||||
|             groups of users of your Spring-based application: staff of the pet clinic, as well as |             groups of users of your Spring-based application: staff of the pet clinic, as well as | ||||||
|             the pet clinic's customers. The staff will have access to all of the data, whilst your |             the pet clinic's customers. The staff will have access to all of the data, whilst your | ||||||
|  | @ -29,42 +29,42 @@ | ||||||
|                     object.</para> |                     object.</para> | ||||||
|             </listitem> |             </listitem> | ||||||
|             <listitem> |             <listitem> | ||||||
|                     <para>Write an <interfacename>AccessDecisionVoter</interfacename> to enforce the security |                 <para>Write an <interfacename>AccessDecisionVoter</interfacename> to enforce the | ||||||
|                         from the <literal>GrantedAuthority[]</literal>s stored in the |                     security from the <literal>GrantedAuthority[]</literal>s stored in the | ||||||
|                     <interfacename>Authentication</interfacename> object. This would mean your |                     <interfacename>Authentication</interfacename> object. This would mean your | ||||||
|                     <interfacename>AuthenticationManager</interfacename> would need to populate the |                     <interfacename>AuthenticationManager</interfacename> would need to populate the | ||||||
|                     <interfacename>Authentication</interfacename> with custom |                     <interfacename>Authentication</interfacename> with custom | ||||||
|                     <interfacename>GrantedAuthority</interfacename>[]s representing each of the |                     <interfacename>GrantedAuthority</interfacename>[]s representing each of the | ||||||
|                             <literal>Customer</literal> domain object instances the principal has |                     <literal>Customer</literal> domain object instances the principal has access | ||||||
|                         access to.</para> |                     to.</para> | ||||||
|             </listitem> |             </listitem> | ||||||
|             <listitem> |             <listitem> | ||||||
|                     <para>Write an <interfacename>AccessDecisionVoter</interfacename> to enforce the security |                 <para>Write an <interfacename>AccessDecisionVoter</interfacename> to enforce the | ||||||
|                         and open the target <literal>Customer</literal> domain object directly. This |                     security and open the target <literal>Customer</literal> domain object directly. | ||||||
|                         would mean your voter needs access to a DAO that allows it to retrieve the |                     This would mean your voter needs access to a DAO that allows it to retrieve the | ||||||
|                     <literal>Customer</literal> object. It would then access the |                     <literal>Customer</literal> object. It would then access the | ||||||
|                             <literal>Customer</literal> object's collection of approved users and |                     <literal>Customer</literal> object's collection of approved users and make the | ||||||
|                         make the appropriate decision.</para> |                     appropriate decision.</para> | ||||||
|             </listitem> |             </listitem> | ||||||
|             </orderedlist></para> |             </orderedlist></para> | ||||||
|         <para>Each one of these approaches is perfectly legitimate. However, the first couples your |         <para>Each one of these approaches is perfectly legitimate. However, the first couples your | ||||||
|             authorization checking to your business code. The main problems with this include the |             authorization checking to your business code. The main problems with this include the | ||||||
|             enhanced difficulty of unit testing and the fact it would be more difficult to reuse the |             enhanced difficulty of unit testing and the fact it would be more difficult to reuse the | ||||||
|             <literal>Customer</literal> authorization logic elsewhere. Obtaining the |             <literal>Customer</literal> authorization logic elsewhere. Obtaining the | ||||||
|                 <literal>GrantedAuthority[]</literal>s from the <interfacename>Authentication</interfacename> |             <literal>GrantedAuthority[]</literal>s from the | ||||||
|             object is also fine, but will not scale to large numbers of |             <interfacename>Authentication</interfacename> object is also fine, but will not scale to | ||||||
|             <literal>Customer</literal>s. If a user might be able to access 5,000 |             large numbers of <literal>Customer</literal>s. If a user might be able to access 5,000 | ||||||
|             <literal>Customer</literal>s (unlikely in this case, but imagine if it were a popular |             <literal>Customer</literal>s (unlikely in this case, but imagine if it were a popular | ||||||
|             vet for a large Pony Club!) the amount of memory consumed and time required to construct |             vet for a large Pony Club!) the amount of memory consumed and time required to construct | ||||||
|             the <interfacename>Authentication</interfacename> object would be undesirable. The final method, |             the <interfacename>Authentication</interfacename> object would be undesirable. The final | ||||||
|             opening the <literal>Customer</literal> directly from external code, is probably the |             method, opening the <literal>Customer</literal> directly from external code, is probably | ||||||
|             best of the three. It achieves separation of concerns, and doesn't misuse memory or CPU |             the best of the three. It achieves separation of concerns, and doesn't misuse memory or | ||||||
|             cycles, but it is still inefficient in that both the |             CPU cycles, but it is still inefficient in that both the | ||||||
|             <interfacename>AccessDecisionVoter</interfacename> and the eventual business method itself will |             <interfacename>AccessDecisionVoter</interfacename> and the eventual business method | ||||||
|             perform a call to the DAO responsible for retrieving the <literal>Customer</literal> |             itself will perform a call to the DAO responsible for retrieving the | ||||||
|             object. Two accesses per method invocation is clearly undesirable. In addition, with |             <literal>Customer</literal> object. Two accesses per method invocation is clearly | ||||||
|             every approach listed you'll need to write your own access control list (ACL) |             undesirable. In addition, with every approach listed you'll need to write your own | ||||||
|             persistence and business logic from scratch.</para> |             access control list (ACL) persistence and business logic from scratch.</para> | ||||||
|         <para>Fortunately, there is another alternative, which we'll talk about below.</para> |         <para>Fortunately, there is another alternative, which we'll talk about below.</para> | ||||||
|     </section> |     </section> | ||||||
|     <section xml:id="domain-acls-key-concepts"> |     <section xml:id="domain-acls-key-concepts"> | ||||||
|  | @ -83,12 +83,12 @@ | ||||||
|                     (and modifying those ACLs)</para> |                     (and modifying those ACLs)</para> | ||||||
|             </listitem> |             </listitem> | ||||||
|             <listitem> |             <listitem> | ||||||
|                     <para>A way of ensuring a given principal is permitted to work with your |                 <para>A way of ensuring a given principal is permitted to work with your objects, | ||||||
|                         objects, before methods are called</para> |                     before methods are called</para> | ||||||
|             </listitem> |             </listitem> | ||||||
|             <listitem> |             <listitem> | ||||||
|                     <para>A way of ensuring a given principal is permitted to work with your objects |                 <para>A way of ensuring a given principal is permitted to work with your objects (or | ||||||
|                         (or something they return), after methods are called</para> |                     something they return), after methods are called</para> | ||||||
|             </listitem> |             </listitem> | ||||||
|             </itemizedlist></para> |             </itemizedlist></para> | ||||||
|         <para>As indicated by the first bullet point, one of the main capabilities of the Spring |         <para>As indicated by the first bullet point, one of the main capabilities of the Spring | ||||||
|  | @ -105,43 +105,40 @@ | ||||||
|             main tables used by default in the implementation. The tables are presented below in |             main tables used by default in the implementation. The tables are presented below in | ||||||
|             order of size in a typical Spring Security ACL deployment, with the table with the most |             order of size in a typical Spring Security ACL deployment, with the table with the most | ||||||
|             rows listed last:</para> |             rows listed last:</para> | ||||||
|         <para> |         <para> <itemizedlist> | ||||||
|             <itemizedlist> |  | ||||||
|             <listitem> |             <listitem> | ||||||
|                 <para>ACL_SID allows us to uniquely identify any principal or authority in the |                 <para>ACL_SID allows us to uniquely identify any principal or authority in the | ||||||
|                         system ("SID" stands for "security identity"). The only columns are the ID, |                     system ("SID" stands for "security identity"). The only columns are the ID, a | ||||||
|                         a textual representation of the SID, and a flag to indicate whether the |                     textual representation of the SID, and a flag to indicate whether the textual | ||||||
|                         textual representation refers to a principal name or a |                     representation refers to a principal name or a | ||||||
|                     <interfacename>GrantedAuthority</interfacename>. Thus, there is a single row for |                     <interfacename>GrantedAuthority</interfacename>. Thus, there is a single row for | ||||||
|                         each unique principal or <interfacename>GrantedAuthority</interfacename>. When used in |                     each unique principal or <interfacename>GrantedAuthority</interfacename>. When | ||||||
|                         the context of receiving a permission, a SID is generally called a |                     used in the context of receiving a permission, a SID is generally called a | ||||||
|                     "recipient".</para> |                     "recipient".</para> | ||||||
|             </listitem> |             </listitem> | ||||||
|             <listitem> |             <listitem> | ||||||
|                 <para>ACL_CLASS allows us to uniquely identify any domain object class in the |                 <para>ACL_CLASS allows us to uniquely identify any domain object class in the | ||||||
|                         system. The only columns are the ID and the Java class name. Thus, there is |                     system. The only columns are the ID and the Java class name. Thus, there is a | ||||||
|                         a single row for each unique Class we wish to store ACL permissions |                     single row for each unique Class we wish to store ACL permissions for.</para> | ||||||
|                     for.</para> |  | ||||||
|             </listitem> |             </listitem> | ||||||
|             <listitem> |             <listitem> | ||||||
|                     <para>ACL_OBJECT_IDENTITY stores information for each unique domain object |                 <para>ACL_OBJECT_IDENTITY stores information for each unique domain object instance | ||||||
|                         instance in the system. Columns include the ID, a foreign key to the |                     in the system. Columns include the ID, a foreign key to the ACL_CLASS table, a | ||||||
|                         ACL_CLASS table, a unique identifier so we know which ACL_CLASS instance |                     unique identifier so we know which ACL_CLASS instance we're providing | ||||||
|                         we're providing information for, the parent, a foreign key to the ACL_SID |                     information for, the parent, a foreign key to the ACL_SID table to represent the | ||||||
|                         table to represent the owner of the domain object instance, and whether we |                     owner of the domain object instance, and whether we allow ACL entries to inherit | ||||||
|                         allow ACL entries to inherit from any parent ACL. We have a single row for |                     from any parent ACL. We have a single row for every domain object instance we're | ||||||
|                         every domain object instance we're storing ACL permissions for.</para> |                     storing ACL permissions for.</para> | ||||||
|             </listitem> |             </listitem> | ||||||
|             <listitem> |             <listitem> | ||||||
|                 <para>Finally, ACL_ENTRY stores the individual permissions assigned to each |                 <para>Finally, ACL_ENTRY stores the individual permissions assigned to each | ||||||
|                     recipient. Columns include a foreign key to the ACL_OBJECT_IDENTITY, the |                     recipient. Columns include a foreign key to the ACL_OBJECT_IDENTITY, the | ||||||
|                         recipient (ie a foreign key to ACL_SID), whether we'll be auditing or not, |                     recipient (ie a foreign key to ACL_SID), whether we'll be auditing or not, and | ||||||
|                         and the integer bit mask that represents the actual permission being granted |                     the integer bit mask that represents the actual permission being granted or | ||||||
|                         or denied. We have a single row for every recipient that receives a |                     denied. We have a single row for every recipient that receives a permission to | ||||||
|                         permission to work with a domain object.</para> |                     work with a domain object.</para> | ||||||
|             </listitem> |             </listitem> | ||||||
|             </itemizedlist> |             </itemizedlist> </para> | ||||||
|         </para> |  | ||||||
|         <para>As mentioned in the last paragraph, the ACL system uses integer bit masking. Don't |         <para>As mentioned in the last paragraph, the ACL system uses integer bit masking. Don't | ||||||
|             worry, you need not be aware of the finer points of bit shifting to use the ACL system, |             worry, you need not be aware of the finer points of bit shifting to use the ACL system, | ||||||
|             but suffice to say that we have 32 bits we can switch on or off. Each of these bits |             but suffice to say that we have 32 bits we can switch on or off. Each of these bits | ||||||
|  | @ -163,9 +160,9 @@ | ||||||
|                 <para><literal>Acl</literal>: Every domain object has one and only one |                 <para><literal>Acl</literal>: Every domain object has one and only one | ||||||
|                     <literal>Acl</literal> object, which internally holds the |                     <literal>Acl</literal> object, which internally holds the | ||||||
|                     <literal>AccessControlEntry</literal>s as well as knows the owner of the |                     <literal>AccessControlEntry</literal>s as well as knows the owner of the | ||||||
|                         <literal>Acl</literal>. An Acl does not refer directly to the domain object, |                     <literal>Acl</literal>. An Acl does not refer directly to the domain object, but | ||||||
|                     but instead to an <literal>ObjectIdentity</literal>. The <literal>Acl</literal> |                     instead to an <literal>ObjectIdentity</literal>. The <literal>Acl</literal> is | ||||||
|                     is stored in the ACL_OBJECT_IDENTITY table.</para> |                     stored in the ACL_OBJECT_IDENTITY table.</para> | ||||||
|             </listitem> |             </listitem> | ||||||
|             <listitem> |             <listitem> | ||||||
|                 <para><literal>AccessControlEntry</literal>: An <literal>Acl</literal> holds |                 <para><literal>AccessControlEntry</literal>: An <literal>Acl</literal> holds | ||||||
|  | @ -183,11 +180,11 @@ | ||||||
|             </listitem> |             </listitem> | ||||||
|             <listitem> |             <listitem> | ||||||
|                 <para><literal>Sid</literal>: The ACL module needs to refer to principals and |                 <para><literal>Sid</literal>: The ACL module needs to refer to principals and | ||||||
|                         <literal>GrantedAuthority[]</literal>s. A level of indirection is provided |                     <literal>GrantedAuthority[]</literal>s. A level of indirection is provided by | ||||||
|                     by the <literal>Sid</literal> interface, which is an abbreviation of "security |                     the <literal>Sid</literal> interface, which is an abbreviation of "security | ||||||
|                     identity". Common classes include <literal>PrincipalSid</literal> (to represent |                     identity". Common classes include <literal>PrincipalSid</literal> (to represent | ||||||
|                     the principal inside an <interfacename>Authentication</interfacename> object) and |                     the principal inside an <interfacename>Authentication</interfacename> object) | ||||||
|                         <literal>GrantedAuthoritySid</literal>. The security identity information is |                     and <literal>GrantedAuthoritySid</literal>. The security identity information is | ||||||
|                     stored in the ACL_SID table.</para> |                     stored in the ACL_SID table.</para> | ||||||
|             </listitem> |             </listitem> | ||||||
|             <listitem> |             <listitem> | ||||||
|  | @ -227,15 +224,14 @@ | ||||||
|             ACL information somewhere. This necessitates the instantiation of a |             ACL information somewhere. This necessitates the instantiation of a | ||||||
|             <literal>DataSource</literal> using Spring. The <literal>DataSource</literal> is then |             <literal>DataSource</literal> using Spring. The <literal>DataSource</literal> is then | ||||||
|             injected into a <literal>JdbcMutableAclService</literal> and |             injected into a <literal>JdbcMutableAclService</literal> and | ||||||
|                 <literal>BasicLookupStrategy</literal> instance. The latter provides |             <literal>BasicLookupStrategy</literal> instance. The latter provides high-performance | ||||||
|             high-performance ACL retrieval capabilities, and the former provides mutator |             ACL retrieval capabilities, and the former provides mutator capabilities. Refer to one | ||||||
|             capabilities. Refer to one of the samples that ship with Spring Security for an example |             of the samples that ship with Spring Security for an example configuration. You'll also | ||||||
|             configuration. You'll also need to populate the database with the four ACL-specific |             need to populate the database with the four ACL-specific tables listed in the last | ||||||
|             tables listed in the last section (refer to the ACL samples for the appropriate SQL |             section (refer to the ACL samples for the appropriate SQL statements).</para> | ||||||
|             statements).</para> |  | ||||||
|         <para>Once you've created the required schema and instantiated |         <para>Once you've created the required schema and instantiated | ||||||
|                 <literal>JdbcMutableAclService</literal>, you'll next need to ensure your domain |             <literal>JdbcMutableAclService</literal>, you'll next need to ensure your domain model | ||||||
|             model supports interoperability with the Spring Security ACL package. Hopefully |             supports interoperability with the Spring Security ACL package. Hopefully | ||||||
|             <literal>ObjectIdentityImpl</literal> will prove sufficient, as it provides a large |             <literal>ObjectIdentityImpl</literal> will prove sufficient, as it provides a large | ||||||
|             number of ways in which it can be used. Most people will have domain objects that |             number of ways in which it can be used. Most people will have domain objects that | ||||||
|             contain a <literal>public Serializable getId()</literal> method. If the return type is |             contain a <literal>public Serializable getId()</literal> method. If the return type is | ||||||
|  | @ -272,7 +268,8 @@ aclService.updateAcl(acl); | ||||||
|             position in the Acl the new entry will be inserted. In the example above, we're just |             position in the Acl the new entry will be inserted. In the example above, we're just | ||||||
|             putting the new ACE at the end of the existing ACEs. The final argument is a boolean |             putting the new ACE at the end of the existing ACEs. The final argument is a boolean | ||||||
|             indicating whether the ACE is granting or denying. Most of the time it will be granting |             indicating whether the ACE is granting or denying. Most of the time it will be granting | ||||||
|             (true), but if it is denying (false), the permissions are effectively being blocked.</para> |             (true), but if it is denying (false), the permissions are effectively being | ||||||
|  |             blocked.</para> | ||||||
|         <para>Spring Security does not provide any special integration to automatically create, |         <para>Spring Security does not provide any special integration to automatically create, | ||||||
|             update or delete ACLs as part of your DAO or repository operations. Instead, you will |             update or delete ACLs as part of your DAO or repository operations. Instead, you will | ||||||
|             need to write code like shown above for your individual domain objects. It's worth |             need to write code like shown above for your individual domain objects. It's worth | ||||||
|  | @ -282,15 +279,15 @@ aclService.updateAcl(acl); | ||||||
|         <para>Once you've used the above techniques to store some ACL information in the database, |         <para>Once you've used the above techniques to store some ACL information in the database, | ||||||
|             the next step is to actually use the ACL information as part of authorization decision |             the next step is to actually use the ACL information as part of authorization decision | ||||||
|             logic. You have a number of choices here. You could write your own |             logic. You have a number of choices here. You could write your own | ||||||
|                 <interfacename>AccessDecisionVoter</interfacename> or <literal>AfterInvocationProvider</literal> |             <interfacename>AccessDecisionVoter</interfacename> or | ||||||
|             that respectively fires before or after a method invocation. Such classes would use |             <literal>AfterInvocationProvider</literal> that respectively fires before or after a | ||||||
|                 <literal>AclService</literal> to retrieve the relevant ACL and then call |             method invocation. Such classes would use <literal>AclService</literal> to retrieve the | ||||||
|                 <literal>Acl.isGranted(Permission[] permission, Sid[] sids, boolean |             relevant ACL and then call <literal>Acl.isGranted(Permission[] permission, Sid[] sids, | ||||||
|                 administrativeMode)</literal> to decide whether permission is granted or denied. |             boolean administrativeMode)</literal> to decide whether permission is granted or denied. | ||||||
|             Alternately, you could use our <literal>AclEntryVoter</literal>, |             Alternately, you could use our <literal>AclEntryVoter</literal>, | ||||||
|             <literal>AclEntryAfterInvocationProvider</literal> or |             <literal>AclEntryAfterInvocationProvider</literal> or | ||||||
|                 <literal>AclEntryAfterInvocationCollectionFilteringProvider</literal> classes. All |             <literal>AclEntryAfterInvocationCollectionFilteringProvider</literal> classes. All of | ||||||
|             of these classes provide a declarative-based approach to evaluating ACL information at |             these classes provide a declarative-based approach to evaluating ACL information at | ||||||
|             runtime, freeing you from needing to write any code. Please refer to the sample |             runtime, freeing you from needing to write any code. Please refer to the sample | ||||||
|             applications to learn how to use these classes.</para> |             applications to learn how to use these classes.</para> | ||||||
|     </section> |     </section> | ||||||
|  |  | ||||||
|  | @ -18,8 +18,8 @@ | ||||||
|         <section xml:id="el-common-built-in"> |         <section xml:id="el-common-built-in"> | ||||||
|             <title>Common Built-In Expressions</title> |             <title>Common Built-In Expressions</title> | ||||||
|             <para>The base class for expression root objects is |             <para>The base class for expression root objects is | ||||||
|                     <classname>SecurityExpressionRoot</classname>. This provides some common |                 <classname>SecurityExpressionRoot</classname>. This provides some common expressions | ||||||
|                 expressions which are available in both web and method security.</para> |                 which are available in both web and method security.</para> | ||||||
|             <table frame="none"> |             <table frame="none"> | ||||||
|                 <title>Common built-in expressions</title> |                 <title>Common built-in expressions</title> | ||||||
|                 <tgroup cols="2"> |                 <tgroup cols="2"> | ||||||
|  | @ -51,8 +51,8 @@ | ||||||
|                         <row> |                         <row> | ||||||
|                             <entry><literal>authentication</literal></entry> |                             <entry><literal>authentication</literal></entry> | ||||||
|                             <entry>Allows direct access to the current |                             <entry>Allows direct access to the current | ||||||
|                                     <interfacename>Authentication</interfacename> object obtained |                                 <interfacename>Authentication</interfacename> object obtained from | ||||||
|                                 from the <interfacename>SecurityContext</interfacename></entry> |                                 the <interfacename>SecurityContext</interfacename></entry> | ||||||
|                         </row> |                         </row> | ||||||
|                         <row> |                         <row> | ||||||
|                             <entry><literal>permitAll</literal></entry> |                             <entry><literal>permitAll</literal></entry> | ||||||
|  | @ -90,8 +90,8 @@ | ||||||
|     <section xml:id="el-access-web"> |     <section xml:id="el-access-web"> | ||||||
|         <title>Web Security Expressions</title> |         <title>Web Security Expressions</title> | ||||||
|         <para> To use expressions to secure individual URLs, you would first need to set the |         <para> To use expressions to secure individual URLs, you would first need to set the | ||||||
|                 <literal>use-expressions</literal> attribute in the <literal><http></literal> |             <literal>use-expressions</literal> attribute in the <literal><http></literal> element | ||||||
|             element to <literal>true</literal>. Spring Security will then expect the |             to <literal>true</literal>. Spring Security will then expect the | ||||||
|             <literal>access</literal> attributes of the <literal><intercept-url></literal> |             <literal>access</literal> attributes of the <literal><intercept-url></literal> | ||||||
|             elements to contain Spring EL expressions. The expressions should evaluate to a boolean, |             elements to contain Spring EL expressions. The expressions should evaluate to a boolean, | ||||||
|             defining whether access should be allowed or not. For example:<programlisting><![CDATA[ |             defining whether access should be allowed or not. For example:<programlisting><![CDATA[ | ||||||
|  | @ -106,8 +106,8 @@ | ||||||
|             already seen the built-in <literal>hasRole</literal> expression in the previous section. |             already seen the built-in <literal>hasRole</literal> expression in the previous section. | ||||||
|             The expression <literal>hasIpAddress</literal> is an additional built-in expression |             The expression <literal>hasIpAddress</literal> is an additional built-in expression | ||||||
|             which is specific to web security. It is defined by the |             which is specific to web security. It is defined by the | ||||||
|                 <classname>WebSecurityExpressionRoot</classname> class, an instance of which is used |             <classname>WebSecurityExpressionRoot</classname> class, an instance of which is used as | ||||||
|             as the expression root object when evaluation web-access expressions. This object also |             the expression root object when evaluation web-access expressions. This object also | ||||||
|             directly exposed the <interfacename>HttpServletRequest</interfacename> object under the |             directly exposed the <interfacename>HttpServletRequest</interfacename> object under the | ||||||
|             name <literal>request</literal> so you can invoke the request directly in an |             name <literal>request</literal> so you can invoke the request directly in an | ||||||
|             expression.</para> |             expression.</para> | ||||||
|  | @ -150,25 +150,25 @@ | ||||||
|                     whether the current user has the <quote>admin</quote>permission for the given |                     whether the current user has the <quote>admin</quote>permission for the given | ||||||
|                     contact. The built-in <literal>hasPermission()</literal> expression is linked |                     contact. The built-in <literal>hasPermission()</literal> expression is linked | ||||||
|                     into the Spring Security ACL module through the application context, as we'll |                     into the Spring Security ACL module through the application context, as we'll | ||||||
|                         <link xlink:href="#el-permission-evaluator">see below</link>. You can access |                     <link xlink:href="#el-permission-evaluator">see below</link>. You can access any | ||||||
|                     any of the method arguments by name as expression variables, provided your code |                     of the method arguments by name as expression variables, provided your code has | ||||||
|                     has debug information compiled in. Any Spring-EL functionality is available |                     debug information compiled in. Any Spring-EL functionality is available within | ||||||
|                     within the expression, so you can also access properties on the arguments. For |                     the expression, so you can also access properties on the arguments. For example, | ||||||
|                     example, if you wanted a particular method to only allow access to a user whose |                     if you wanted a particular method to only allow access to a user whose username | ||||||
|                     username matched that of the contact, you could write</para> |                     matched that of the contact, you could write</para> | ||||||
|                 <programlisting> |                 <programlisting> | ||||||
|  @PreAuthorize("#contact.name == principal.name)") |  @PreAuthorize("#contact.name == principal.name)") | ||||||
|  public void doSomething(Contact contact);</programlisting> |  public void doSomething(Contact contact);</programlisting> | ||||||
|                 <para>Here we are accessing another built–in expression, which is the |                 <para>Here we are accessing another built–in expression, which is the | ||||||
|                     <literal>principal</literal> of the current Spring Security |                     <literal>principal</literal> of the current Spring Security | ||||||
|                         <interfacename>Authentication</interfacename> object obtained from the |                     <interfacename>Authentication</interfacename> object obtained from the security | ||||||
|                     security context. You can also access the |                     context. You can also access the <interfacename>Authentication</interfacename> | ||||||
|                         <interfacename>Authentication</interfacename> object itself directly using |                     object itself directly using the expression name | ||||||
|                     the expression name <literal>authentication</literal>.</para> |                     <literal>authentication</literal>.</para> | ||||||
|                 <para>Less commonly, you may wish to perform an access-control check after the |                 <para>Less commonly, you may wish to perform an access-control check after the | ||||||
|                     method has been invoked. This can be achieved using the |                     method has been invoked. This can be achieved using the | ||||||
|                         <literal>@PostAuthorize</literal> annotation. To access the return value |                     <literal>@PostAuthorize</literal> annotation. To access the return value from a | ||||||
|                     from a method, use the built–in name <literal>returnObject</literal> in the |                     method, use the built–in name <literal>returnObject</literal> in the | ||||||
|                     expression.</para> |                     expression.</para> | ||||||
|             </section> |             </section> | ||||||
|             <section> |             <section> | ||||||
|  | @ -227,8 +227,7 @@ | ||||||
|                     long as it is consistent with how the permissions are loaded.</para> |                     long as it is consistent with how the permissions are loaded.</para> | ||||||
|                 <para>To use <literal>hasPermission()</literal> expressions, you have to explicitly |                 <para>To use <literal>hasPermission()</literal> expressions, you have to explicitly | ||||||
|                     configure a <interfacename>PermissionEvaluator</interfacename> in your |                     configure a <interfacename>PermissionEvaluator</interfacename> in your | ||||||
|                     application context. This would look something like this: |                     application context. This would look something like this: <programlisting language="xml"> <![CDATA[ | ||||||
| <programlisting language="xml"> <![CDATA[ |  | ||||||
| <security:global-method-security pre-post-annotations="enabled"> | <security:global-method-security pre-post-annotations="enabled"> | ||||||
|   <security:expression-handler ref="expressionHandler"/> |   <security:expression-handler ref="expressionHandler"/> | ||||||
| </security:global-method-security> | </security:global-method-security> | ||||||
|  | @ -239,9 +238,8 @@ | ||||||
| </bean>]]></programlisting>Where <literal>myPermissionEvaluator</literal> is the bean which | </bean>]]></programlisting>Where <literal>myPermissionEvaluator</literal> is the bean which | ||||||
|                     implements <interfacename>PermissionEvaluator</interfacename>. Usually this will |                     implements <interfacename>PermissionEvaluator</interfacename>. Usually this will | ||||||
|                     be the implementation from the ACL module which is called |                     be the implementation from the ACL module which is called | ||||||
|                         <classname>AclPermissionEvaluator</classname>. See the |                     <classname>AclPermissionEvaluator</classname>. See the <quote>Contacts</quote> | ||||||
|                         <quote>Contacts</quote> sample application configuration for more |                     sample application configuration for more details.</para> | ||||||
|                     details.</para> |  | ||||||
|             </section> |             </section> | ||||||
|         </section> |         </section> | ||||||
|     </section> |     </section> | ||||||
|  |  | ||||||
|  | @ -1,67 +1,68 @@ | ||||||
| <chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="form"> | <chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="form"> | ||||||
|     <info><title>Form Authentication Mechanism</title></info> |     <info> | ||||||
|  |         <title>Form Authentication Mechanism</title> | ||||||
|  |     </info> | ||||||
| 
 | 
 | ||||||
|     <section xml:id="form-overview"> |     <section xml:id="form-overview"> | ||||||
|         <info><title>Overview</title></info> |         <info> | ||||||
|  |             <title>Overview</title> | ||||||
|  |         </info> | ||||||
| 
 | 
 | ||||||
|         <para>HTTP Form Authentication involves using the |         <para>HTTP Form Authentication involves using the | ||||||
|             <literal>UsernamePasswordAuthenticationFilter</literal> to process a login |             <literal>UsernamePasswordAuthenticationFilter</literal> to process a login form. This is | ||||||
|             form. This is the most common way for an application to authenticate end |             the most common way for an application to authenticate end users. Form-based | ||||||
|             users. Form-based authentication is entirely compatible with the DAO, LDAP |             authentication is entirely compatible with the DAO, LDAP and JAAS authentication | ||||||
|             and JAAS authentication providers.</para> |             providers.</para> | ||||||
|         <para>This is also the mechanism used by the <form-login> element from the namespace |         <para>This is also the mechanism used by the <form-login> element from the namespace | ||||||
|             and it's recommended that you use that unless you have specific customization requirements. |             and it's recommended that you use that unless you have specific customization | ||||||
|         </para> |             requirements. </para> | ||||||
|     </section> |     </section> | ||||||
| 
 | 
 | ||||||
|     <section xml:id="form-config"> |     <section xml:id="form-config"> | ||||||
|         <info><title>Configuration</title></info> |         <info> | ||||||
|  |             <title>Configuration</title> | ||||||
|  |         </info> | ||||||
| 
 | 
 | ||||||
|         <para>The login form simply contains <literal>j_username</literal> and |         <para>The login form simply contains <literal>j_username</literal> and | ||||||
|             <literal>j_password</literal> input fields, and posts to a URL that is |             <literal>j_password</literal> input fields, and posts to a URL that is monitored by the | ||||||
|             monitored by the filter (by default |             filter (by default <literal>/j_spring_security_check</literal>). You should add an | ||||||
|             <literal>/j_spring_security_check</literal>). You should add an |             <literal>UsernamePasswordAuthenticationFilter</literal> to your application context: <programlisting><![CDATA[ | ||||||
|             <literal>UsernamePasswordAuthenticationFilter</literal> to your application context: |  | ||||||
|             <programlisting><![CDATA[ |  | ||||||
| <bean id="authenticationProcessingFilter" class= | <bean id="authenticationProcessingFilter" class= | ||||||
| "org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"> | "org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"> | ||||||
|   <property name="authenticationManager" ref="authenticationManager"/> |   <property name="authenticationManager" ref="authenticationManager"/> | ||||||
|   <property name="filterProcessesUrl" value="/j_spring_security_check"/> |   <property name="filterProcessesUrl" value="/j_spring_security_check"/> | ||||||
| </bean> ]]> | </bean> ]]> | ||||||
|             </programlisting></para> |             </programlisting></para> | ||||||
|         <para> |         <para> The configured <interfacename>AuthenticationManager</interfacename> processes each | ||||||
|             The configured <interfacename>AuthenticationManager</interfacename> |             authentication request. The destination following a successful authentication or an | ||||||
|             processes each authentication request. The destination following a successful authentication |             authentication failure is controlled by the | ||||||
|             or an authentication failure is controlled by the <interfacename>AuthenticationSuccessHandler</interfacename> |             <interfacename>AuthenticationSuccessHandler</interfacename> and | ||||||
|             and <interfacename>AuthenticationFailureHandler</interfacename> interfaces, respectively. |             <interfacename>AuthenticationFailureHandler</interfacename> interfaces, respectively. | ||||||
|             The filter has properties which allow you to set these |             The filter has properties which allow you to set these <footnote> | ||||||
|             <footnote><para>In versions prior to 3.0, the application flow at this point had evolved to a stage |             <para>In versions prior to 3.0, the application flow at this point had evolved to a | ||||||
|                 was controlled by a mix of properties on this class and strategy plugins. The |                 stage was controlled by a mix of properties on this class and strategy plugins. The | ||||||
|             decision was made for 3.0 to refactor the code to make these two strategies entirely responsible. |                 decision was made for 3.0 to refactor the code to make these two strategies entirely | ||||||
|             </para></footnote>. |                 responsible. </para> | ||||||
|             Some standard implementations are supplied for these such as |             </footnote>. Some standard implementations are supplied for these such as | ||||||
|             <classname>SimpleUrlAuthenticationSuccessHandler</classname>, |             <classname>SimpleUrlAuthenticationSuccessHandler</classname>, | ||||||
|             <classname>SavedRequestAwareAuthenticationSuccessHandler</classname>, |             <classname>SavedRequestAwareAuthenticationSuccessHandler</classname>, | ||||||
|             <classname>SimpleUrlAuthenticationFailureHandler</classname> and |             <classname>SimpleUrlAuthenticationFailureHandler</classname> and | ||||||
|             <classname>ExceptionMappingAuthenticationFailureHandler</classname>. Have a look at the Javadoc |             <classname>ExceptionMappingAuthenticationFailureHandler</classname>. Have a look at the | ||||||
|             for these classes to see how they work. |             Javadoc for these classes to see how they work. </para> | ||||||
|             </para> |  | ||||||
| 
 | 
 | ||||||
|         <para>If authentication is successful, the resulting |         <para>If authentication is successful, the resulting | ||||||
|             <interfacename>Authentication</interfacename> object will be placed into the |             <interfacename>Authentication</interfacename> object will be placed into the | ||||||
|             <classname>SecurityContextHolder</classname>. |             <classname>SecurityContextHolder</classname>. The configured | ||||||
|             The configured AuthenticationSuccessHandler will then be called to either redirect or forward |             AuthenticationSuccessHandler will then be called to either redirect or forward the user | ||||||
|             the user to the appropriate destination. By default a <classname>SavedRequestAwareAuthenticationSuccessHandler</classname> |             to the appropriate destination. By default a | ||||||
|             is used, which means that the user will be redirected to the original destination they requested before they were asked to |             <classname>SavedRequestAwareAuthenticationSuccessHandler</classname> is used, which | ||||||
|             login. |             means that the user will be redirected to the original destination they requested before | ||||||
|             <note> |             they were asked to login. <note> | ||||||
|                 <para> |             <para> The <classname>ExceptionTranslationFilter</classname> caches the original request | ||||||
|                     The <classname>ExceptionTranslationFilter</classname> caches the original request a user makes. |                 a user makes. When the user authenticates, the request handler makes use of this | ||||||
|                     When the user authenticates, the request handler makes use of this cached request to obtain the original |                 cached request to obtain the original URL and redirect to it. The original request | ||||||
|                     URL and redirect to it. The original request is then rebuilt and used as an alternative. |                 is then rebuilt and used as an alternative. </para> | ||||||
|                 </para> |             </note> If authentication fails, the configured | ||||||
|             </note> |             <interfacename>AuthenticationFailureHandler</interfacename> will be invoked. </para> | ||||||
|             If authentication fails, the configured <interfacename>AuthenticationFailureHandler</interfacename> will be invoked. |  | ||||||
|         </para> |  | ||||||
|     </section> |     </section> | ||||||
| </chapter> | </chapter> | ||||||
|  | @ -25,8 +25,8 @@ | ||||||
|             targets. <quote>Authentication</quote> is the process of establishing a principal is who |             targets. <quote>Authentication</quote> is the process of establishing a principal is who | ||||||
|             they claim to be (a <quote>principal</quote> generally means a user, device or some |             they claim to be (a <quote>principal</quote> generally means a user, device or some | ||||||
|             other system which can perform an action in your application). |             other system which can perform an action in your application). | ||||||
|                 <quote>Authorization</quote> refers to the process of deciding whether a principal |             <quote>Authorization</quote> refers to the process of deciding whether a principal is | ||||||
|             is allowed to perform an action within your application. To arrive at the point where an |             allowed to perform an action within your application. To arrive at the point where an | ||||||
|             authorization decision is needed, the identity of the principal has already been |             authorization decision is needed, the identity of the principal has already been | ||||||
|             established by the authentication process. These concepts are common, and not at all |             established by the authentication process. These concepts are common, and not at all | ||||||
|             specific to Spring Security. </para> |             specific to Spring Security. </para> | ||||||
|  | @ -134,8 +134,8 @@ | ||||||
|             </listitem> |             </listitem> | ||||||
|         </itemizedlist> |         </itemizedlist> | ||||||
|         <para>(* Denotes provided by a third party; check our <link |         <para>(* Denotes provided by a third party; check our <link | ||||||
|                 xlink:href="http://acegisecurity.org/powering.html">integration page</link> for |             xlink:href="http://acegisecurity.org/powering.html">integration page</link> for links to | ||||||
|             links to the latest details)</para> |             the latest details)</para> | ||||||
|         <para>Many independent software vendors (ISVs) adopt Spring Security because of this |         <para>Many independent software vendors (ISVs) adopt Spring Security because of this | ||||||
|             significant choice of flexible authentication models. Doing so allows them to quickly |             significant choice of flexible authentication models. Doing so allows them to quickly | ||||||
|             integrate their solutions with whatever their end clients need, without undertaking a |             integrate their solutions with whatever their end clients need, without undertaking a | ||||||
|  | @ -205,9 +205,9 @@ | ||||||
|             <literal>http://apr.apache.org/versioning.html</literal>. We quote the introduction |             <literal>http://apr.apache.org/versioning.html</literal>. We quote the introduction | ||||||
|             contained on that page for your convenience:</para> |             contained on that page for your convenience:</para> | ||||||
|         <para><quote>Versions are denoted using a standard triplet of integers: MAJOR.MINOR.PATCH. |         <para><quote>Versions are denoted using a standard triplet of integers: MAJOR.MINOR.PATCH. | ||||||
|                 The basic intent is that MAJOR versions are incompatible, large-scale upgrades of |             The basic intent is that MAJOR versions are incompatible, large-scale upgrades of the | ||||||
|                 the API. MINOR versions retain source and binary compatibility with older minor |             API. MINOR versions retain source and binary compatibility with older minor versions, | ||||||
|                 versions, and changes in the PATCH level are perfectly compatible, forwards and |             and changes in the PATCH level are perfectly compatible, forwards and | ||||||
|             backwards.</quote></para> |             backwards.</quote></para> | ||||||
|     </section> |     </section> | ||||||
|     <section xml:id="get-spring-security"> |     <section xml:id="get-spring-security"> | ||||||
|  | @ -215,8 +215,8 @@ | ||||||
|         <para>You can get hold of Spring Security in several ways. You can download a packaged |         <para>You can get hold of Spring Security in several ways. You can download a packaged | ||||||
|             distribution from the main Spring <link |             distribution from the main Spring <link | ||||||
|             xlink:href="http://www.springsource.com/download/community?project=Spring%20Security" |             xlink:href="http://www.springsource.com/download/community?project=Spring%20Security" | ||||||
|                 >download page</link>, download individual jars (and sample WAR files) from the |             >download page</link>, download individual jars (and sample WAR files) from the Maven | ||||||
|             Maven Central repository (or a SpringSource Maven repository for snapshot and milestone |             Central repository (or a SpringSource Maven repository for snapshot and milestone | ||||||
|             releases) or, alternatively, you can build the project from source yourself. See the |             releases) or, alternatively, you can build the project from source yourself. See the | ||||||
|             project web site for more details. </para> |             project web site for more details. </para> | ||||||
|         <section xml:id="modules"> |         <section xml:id="modules"> | ||||||
|  | @ -233,8 +233,23 @@ | ||||||
|                 <para>Contains core authentication and access-contol classes and interfaces, |                 <para>Contains core authentication and access-contol classes and interfaces, | ||||||
|                     remoting support and basic provisioning APIs. Required by any application which |                     remoting support and basic provisioning APIs. Required by any application which | ||||||
|                     uses Spring Security. Supports standalone applications, remote clients, method |                     uses Spring Security. Supports standalone applications, remote clients, method | ||||||
|                     (service layer) security and JDBC user provisioning. Contains the top-level |                     (service layer) security and JDBC user provisioning. Contains the top-level packages:<itemizedlist> | ||||||
|                                     packages:<itemizedlist><listitem><para><literal>org.springframework.security.core</literal></para></listitem><listitem><para><literal>org.springframework.security.access</literal></para></listitem><listitem><para><literal>org.springframework.security.authentication</literal></para></listitem><listitem><para><literal>org.springframework.security.provisioning</literal></para></listitem><listitem><para><literal>org.springframework.security.remoting</literal></para></listitem></itemizedlist></para> |                     <listitem> | ||||||
|  |                         <para><literal>org.springframework.security.core</literal></para> | ||||||
|  |                     </listitem> | ||||||
|  |                     <listitem> | ||||||
|  |                         <para><literal>org.springframework.security.access</literal></para> | ||||||
|  |                     </listitem> | ||||||
|  |                     <listitem> | ||||||
|  |                         <para><literal>org.springframework.security.authentication</literal></para> | ||||||
|  |                     </listitem> | ||||||
|  |                     <listitem> | ||||||
|  |                         <para><literal>org.springframework.security.provisioning</literal></para> | ||||||
|  |                     </listitem> | ||||||
|  |                     <listitem> | ||||||
|  |                         <para><literal>org.springframework.security.remoting</literal></para> | ||||||
|  |                     </listitem> | ||||||
|  |                     </itemizedlist></para> | ||||||
|             </section> |             </section> | ||||||
|             <section xml:id="spring-security-web"> |             <section xml:id="spring-security-web"> | ||||||
|                 <title>Web - <literal>spring-security-web.jar</literal></title> |                 <title>Web - <literal>spring-security-web.jar</literal></title> | ||||||
|  |  | ||||||
|  | @ -1,36 +1,38 @@ | ||||||
| <chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="jaas"> | <chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="jaas"> | ||||||
|     <info><title>Java Authentication and Authorization Service (JAAS) Provider</title></info> |     <info> | ||||||
|  |         <title>Java Authentication and Authorization Service (JAAS) Provider</title> | ||||||
|  |     </info> | ||||||
| 
 | 
 | ||||||
|     <section xml:id="jaas-overview"> |     <section xml:id="jaas-overview"> | ||||||
|         <info><title>Overview</title></info> |         <info> | ||||||
|         <para>Spring Security provides a package able to delegate |             <title>Overview</title> | ||||||
|             authentication requests to the Java Authentication and Authorization |         </info> | ||||||
|             Service (JAAS). This package is discussed in detail below.</para> |         <para>Spring Security provides a package able to delegate authentication requests to the | ||||||
|  |             Java Authentication and Authorization Service (JAAS). This package is discussed in | ||||||
|  |             detail below.</para> | ||||||
| 
 | 
 | ||||||
|         <para>Central to JAAS operation are login configuration files. To |         <para>Central to JAAS operation are login configuration files. To learn more about JAAS | ||||||
|             learn more about JAAS login configuration files, consult the JAAS |             login configuration files, consult the JAAS reference documentation available from Sun | ||||||
|             reference documentation available from Sun Microsystems. We expect you |             Microsystems. We expect you to have a basic understanding of JAAS and its login | ||||||
|             to have a basic understanding of JAAS and its login configuration file |             configuration file syntax in order to understand this section.</para> | ||||||
|             syntax in order to understand this section.</para> |  | ||||||
|     </section> |     </section> | ||||||
| 
 | 
 | ||||||
|     <section xml:id="jaas-config"> |     <section xml:id="jaas-config"> | ||||||
|         <info><title>Configuration</title></info> |         <info> | ||||||
|         <para>The <literal>JaasAuthenticationProvider</literal> attempts to |             <title>Configuration</title> | ||||||
|             authenticate a user’s principal and credentials through JAAS.</para> |         </info> | ||||||
|  |         <para>The <literal>JaasAuthenticationProvider</literal> attempts to authenticate a user’s | ||||||
|  |             principal and credentials through JAAS.</para> | ||||||
| 
 | 
 | ||||||
|         <para>Let’s assume we have a JAAS login configuration file, |         <para>Let’s assume we have a JAAS login configuration file, | ||||||
|             <literal>/WEB-INF/login.conf</literal>, with the following |             <literal>/WEB-INF/login.conf</literal>, with the following contents: | ||||||
|             contents: |             <programlisting> | ||||||
| <programlisting> |  | ||||||
| JAASTest { | JAASTest { | ||||||
|     sample.SampleLoginModule required; |     sample.SampleLoginModule required; | ||||||
| };</programlisting></para> | };</programlisting></para> | ||||||
|         <para>Like all Spring Security beans, the |         <para>Like all Spring Security beans, the <classname>JaasAuthenticationProvider</classname> | ||||||
|             <classname>JaasAuthenticationProvider</classname> is configured via the |             is configured via the application context. The following definitions would correspond to | ||||||
|             application context. The following definitions would correspond to the |             the above JAAS login configuration file: <programlisting><![CDATA[ | ||||||
|             above JAAS login configuration file: |  | ||||||
| <programlisting><![CDATA[ |  | ||||||
| <bean id="jaasAuthenticationProvider" | <bean id="jaasAuthenticationProvider" | ||||||
|    class="org.springframework.security.authentication.jaas.JaasAuthenticationProvider"> |    class="org.springframework.security.authentication.jaas.JaasAuthenticationProvider"> | ||||||
|  <property name="loginConfig" value="/WEB-INF/login.conf"/> |  <property name="loginConfig" value="/WEB-INF/login.conf"/> | ||||||
|  | @ -55,82 +57,76 @@ JAASTest { | ||||||
|             <interfacename>AuthorityGranter</interfacename>s are discussed below.</para> |             <interfacename>AuthorityGranter</interfacename>s are discussed below.</para> | ||||||
| 
 | 
 | ||||||
|         <section xml:id="jaas-callbackhandler"> |         <section xml:id="jaas-callbackhandler"> | ||||||
|             <info><title xml:id="jaas-callback-handler">JAAS CallbackHandler</title></info> |             <info> | ||||||
|  |                 <title xml:id="jaas-callback-handler">JAAS CallbackHandler</title> | ||||||
|  |             </info> | ||||||
| 
 | 
 | ||||||
|             <para>Most JAAS <literal>LoginModule</literal>s require a callback |             <para>Most JAAS <literal>LoginModule</literal>s require a callback of some sort. These | ||||||
|                 of some sort. These callbacks are usually used to obtain the |                 callbacks are usually used to obtain the username and password from the user.</para> | ||||||
|                 username and password from the user.</para> |  | ||||||
| 
 | 
 | ||||||
|             <para>In a Spring Security deployment, Spring Security is |             <para>In a Spring Security deployment, Spring Security is responsible for this user | ||||||
|                 responsible for this user interaction (via the authentication |                 interaction (via the authentication mechanism). Thus, by the time the authentication | ||||||
|                 mechanism). Thus, by the time the authentication request is |                 request is delegated through to JAAS, Spring Security's authentication mechanism | ||||||
|                 delegated through to JAAS, Spring Security's authentication |                 will already have fully-populated an <interfacename>Authentication</interfacename> | ||||||
|                 mechanism will already have fully-populated an |                 object containing all the information required by the JAAS | ||||||
|                 <interfacename>Authentication</interfacename> object containing all the |  | ||||||
|                 information required by the JAAS |  | ||||||
|                 <literal>LoginModule</literal>.</para> |                 <literal>LoginModule</literal>.</para> | ||||||
| 
 | 
 | ||||||
|             <para>Therefore, the JAAS package for Spring Security provides two |             <para>Therefore, the JAAS package for Spring Security provides two default callback | ||||||
|                 default callback handlers, |                 handlers, <literal>JaasNameCallbackHandler</literal> and | ||||||
|                 <literal>JaasNameCallbackHandler</literal> and |                 <literal>JaasPasswordCallbackHandler</literal>. Each of these callback handlers | ||||||
|                 <literal>JaasPasswordCallbackHandler</literal>. Each of these |                 implement <literal>JaasAuthenticationCallbackHandler</literal>. In most cases these | ||||||
|                 callback handlers implement |                 callback handlers can simply be used without understanding the internal | ||||||
|                 <literal>JaasAuthenticationCallbackHandler</literal>. In most cases |                 mechanics.</para> | ||||||
|                 these callback handlers can simply be used without understanding the |  | ||||||
|                 internal mechanics.</para> |  | ||||||
| 
 | 
 | ||||||
|             <para>For those needing full control over the callback behavior, |             <para>For those needing full control over the callback behavior, internally | ||||||
|                 internally <literal>JaasAuthenticationProvider</literal> wraps these |                 <literal>JaasAuthenticationProvider</literal> wraps these | ||||||
|                 <literal>JaasAuthenticationCallbackHandler</literal>s with an |                 <literal>JaasAuthenticationCallbackHandler</literal>s with an | ||||||
|                 <literal>InternalCallbackHandler</literal>. The |                 <literal>InternalCallbackHandler</literal>. The | ||||||
|                 <literal>InternalCallbackHandler</literal> is the class that |                 <literal>InternalCallbackHandler</literal> is the class that actually implements | ||||||
|                 actually implements JAAS’ normal <literal>CallbackHandler</literal> |                 JAAS’ normal <literal>CallbackHandler</literal> interface. Any time that the JAAS | ||||||
|                 interface. Any time that the JAAS <literal>LoginModule</literal> is |                 <literal>LoginModule</literal> is used, it is passed a list of application context | ||||||
|                 used, it is passed a list of application context configured |                 configured <literal>InternalCallbackHandler</literal>s. If the | ||||||
|                 <literal>InternalCallbackHandler</literal>s. If the |  | ||||||
|                 <literal>LoginModule</literal> requests a callback against the |                 <literal>LoginModule</literal> requests a callback against the | ||||||
|                 <literal>InternalCallbackHandler</literal>s, the callback is in-turn |                 <literal>InternalCallbackHandler</literal>s, the callback is in-turn passed to the | ||||||
|                 passed to the <literal>JaasAuthenticationCallbackHandler</literal>s |                 <literal>JaasAuthenticationCallbackHandler</literal>s being wrapped.</para> | ||||||
|                 being wrapped.</para> |  | ||||||
|         </section> |         </section> | ||||||
| 
 | 
 | ||||||
|         <section xml:id="jaas-authoritygranter"> |         <section xml:id="jaas-authoritygranter"> | ||||||
|             <info><title xml:id="jaas-authority-granter">JAAS AuthorityGranter</title></info> |             <info> | ||||||
|  |                 <title xml:id="jaas-authority-granter">JAAS AuthorityGranter</title> | ||||||
|  |             </info> | ||||||
| 
 | 
 | ||||||
|             <para>JAAS works with principals. Even "roles" are represented as |             <para>JAAS works with principals. Even "roles" are represented as principals in JAAS. | ||||||
|                 principals in JAAS. Spring Security, on the other hand, works with |                 Spring Security, on the other hand, works with | ||||||
|                 <interfacename>Authentication</interfacename> objects. Each |                 <interfacename>Authentication</interfacename> objects. Each | ||||||
|                 <interfacename>Authentication</interfacename> object contains a single |                 <interfacename>Authentication</interfacename> object contains a single principal, | ||||||
|                 principal, and multiple <interfacename>GrantedAuthority</interfacename>[]s. To |                 and multiple <interfacename>GrantedAuthority</interfacename>[]s. To facilitate | ||||||
|                 facilitate mapping between these different concepts, Spring |                 mapping between these different concepts, Spring Security's JAAS package includes an | ||||||
|                 Security's JAAS package includes an |  | ||||||
|                 <literal>AuthorityGranter</literal> interface.</para> |                 <literal>AuthorityGranter</literal> interface.</para> | ||||||
| 
 | 
 | ||||||
|             <para>An <literal>AuthorityGranter</literal> is responsible for |             <para>An <literal>AuthorityGranter</literal> is responsible for inspecting a JAAS | ||||||
|                 inspecting a JAAS principal and returning a set of |                 principal and returning a set of <literal>String</literal>s, representing the | ||||||
|                 <literal>String</literal>s, representing the authorities assigned to the principal. |                 authorities assigned to the principal. For each returned authority string, the | ||||||
|                 For each returned authority string, the |  | ||||||
|                 <classname>JaasAuthenticationProvider</classname> creates a |                 <classname>JaasAuthenticationProvider</classname> creates a | ||||||
|                 <classname>JaasGrantedAuthority</classname> (which implements Spring |                 <classname>JaasGrantedAuthority</classname> (which implements Spring Security’s | ||||||
|                 Security’s <interfacename>GrantedAuthority</interfacename> interface) containing |                 <interfacename>GrantedAuthority</interfacename> interface) containing the authority | ||||||
|                 the authority string and the JAAS principal that the |                 string and the JAAS principal that the | ||||||
|                 <interfacename>AuthorityGranter</interfacename> was passed. The |                 <interfacename>AuthorityGranter</interfacename> was passed. The | ||||||
|                 <classname>JaasAuthenticationProvider</classname> obtains the JAAS |                 <classname>JaasAuthenticationProvider</classname> obtains the JAAS principals by | ||||||
|                 principals by firstly successfully authenticating the user’s |                 firstly successfully authenticating the user’s credentials using the JAAS | ||||||
|                 credentials using the JAAS <literal>LoginModule</literal>, and then |                 <literal>LoginModule</literal>, and then accessing the | ||||||
|                 accessing the <literal>LoginContext</literal> it returns. A call to |                 <literal>LoginContext</literal> it returns. A call to | ||||||
|                 <literal>LoginContext.getSubject().getPrincipals()</literal> is |                 <literal>LoginContext.getSubject().getPrincipals()</literal> is made, with each | ||||||
|                 made, with each resulting principal passed to each |                 resulting principal passed to each <interfacename>AuthorityGranter</interfacename> | ||||||
|                 <interfacename>AuthorityGranter</interfacename> defined against the |                 defined against the | ||||||
|                 <literal>JaasAuthenticationProvider.setAuthorityGranters(List)</literal> |                 <literal>JaasAuthenticationProvider.setAuthorityGranters(List)</literal> | ||||||
|                 property.</para> |                 property.</para> | ||||||
| 
 | 
 | ||||||
|             <para>Spring Security does not include any production |             <para>Spring Security does not include any production | ||||||
|                 <interfacename>AuthorityGranter</interfacename>s given that every JAAS principal |                 <interfacename>AuthorityGranter</interfacename>s given that every JAAS principal has | ||||||
|                 has an implementation-specific meaning. However, there is a |                 an implementation-specific meaning. However, there is a | ||||||
|                 <literal>TestAuthorityGranter</literal> in the unit tests that |                 <literal>TestAuthorityGranter</literal> in the unit tests that demonstrates a simple | ||||||
|                 demonstrates a simple <literal>AuthorityGranter</literal> |                 <literal>AuthorityGranter</literal> implementation.</para> | ||||||
|                 implementation.</para> |  | ||||||
|         </section> |         </section> | ||||||
|     </section> |     </section> | ||||||
| </chapter> | </chapter> | ||||||
|  | @ -17,12 +17,11 @@ | ||||||
|             following link provides a good introduction to the concepts involved and a guide to |             following link provides a good introduction to the concepts involved and a guide to | ||||||
|             setting up a directory using the free LDAP server OpenLDAP: <uri |             setting up a directory using the free LDAP server OpenLDAP: <uri | ||||||
|             xmlns:xlink="http://www.w3.org/1999/xlink" |             xmlns:xlink="http://www.w3.org/1999/xlink" | ||||||
|                 xlink:href="http://www.zytrax.com/books/ldap/" |             xlink:href="http://www.zytrax.com/books/ldap/">http://www.zytrax.com/books/ldap/</uri>. | ||||||
|                 >http://www.zytrax.com/books/ldap/</uri>. Some familiarity with the JNDI APIs used |             Some familiarity with the JNDI APIs used to access LDAP from Java may also be useful. We | ||||||
|             to access LDAP from Java may also be useful. We don't use any third-party LDAP libraries |             don't use any third-party LDAP libraries (Mozilla, JLDAP etc.) in the LDAP provider, but | ||||||
|             (Mozilla, JLDAP etc.) in the LDAP provider, but extensive use is made of Spring LDAP, so |             extensive use is made of Spring LDAP, so some familiarity with that project may be | ||||||
|             some familiarity with that project may be useful if you plan on adding your own |             useful if you plan on adding your own customizations.</para> | ||||||
|             customizations.</para> |  | ||||||
|     </section> |     </section> | ||||||
|     <section> |     <section> | ||||||
|         <info> |         <info> | ||||||
|  | @ -31,9 +30,9 @@ | ||||||
|         <para> LDAP authentication in Spring Security can be roughly divided into the following |         <para> LDAP authentication in Spring Security can be roughly divided into the following | ||||||
|             stages. <orderedlist inheritnum="ignore" continuation="restarts"> |             stages. <orderedlist inheritnum="ignore" continuation="restarts"> | ||||||
|             <listitem> |             <listitem> | ||||||
|                     <para>Obtaining the unique LDAP <quote>Distinguished Name</quote>, or DN, from |                 <para>Obtaining the unique LDAP <quote>Distinguished Name</quote>, or DN, from the | ||||||
|                         the login name. This will often mean performing a search in the directory, |                     login name. This will often mean performing a search in the directory, unless | ||||||
|                         unless the exact mapping of usernames to DNs is known in advance.</para> |                     the exact mapping of usernames to DNs is known in advance.</para> | ||||||
|             </listitem> |             </listitem> | ||||||
|             <listitem> |             <listitem> | ||||||
|                 <para>Authenticating the user, either by binding as that user or by performing a |                 <para>Authenticating the user, either by binding as that user or by performing a | ||||||
|  | @ -72,8 +71,8 @@ | ||||||
|   <ldap-server root="dc=springframework,dc=org"/> |   <ldap-server root="dc=springframework,dc=org"/> | ||||||
|  ]]> |  ]]> | ||||||
|     </programlisting> Here we've specified that the root DIT of the directory should be |     </programlisting> Here we've specified that the root DIT of the directory should be | ||||||
|                     <quote>dc=springframework,dc=org</quote>, which is the default. Used this way, |                 <quote>dc=springframework,dc=org</quote>, which is the default. Used this way, the | ||||||
|                 the namespace parser will create an embedded Apache Directory server and scan the |                 namespace parser will create an embedded Apache Directory server and scan the | ||||||
|                 classpath for any LDIF files, which it will attempt to load into the server. You can |                 classpath for any LDIF files, which it will attempt to load into the server. You can | ||||||
|                 customize this behaviour using the <literal>ldif</literal> attribute, which defines |                 customize this behaviour using the <literal>ldif</literal> attribute, which defines | ||||||
|                 an LDIF resource to be loaded: <programlisting><![CDATA[ |                 an LDIF resource to be loaded: <programlisting><![CDATA[ | ||||||
|  | @ -112,34 +111,30 @@ | ||||||
|             <para> How authorities are loaded from groups in the LDAP directory is controlled by the |             <para> How authorities are loaded from groups in the LDAP directory is controlled by the | ||||||
|                 following attributes. <itemizedlist> |                 following attributes. <itemizedlist> | ||||||
|                 <listitem> |                 <listitem> | ||||||
|                         <para> |                     <para> <literal>group-search-base</literal>. Defines the part of the directory | ||||||
|                             <literal>group-search-base</literal>. Defines the part of the directory |  | ||||||
|                         tree under which group searches should be performed.</para> |                         tree under which group searches should be performed.</para> | ||||||
|                 </listitem> |                 </listitem> | ||||||
|                 <listitem> |                 <listitem> | ||||||
|                         <para> |                     <para> <literal>group-role-attribute</literal>. The attribute which contains the | ||||||
|                             <literal>group-role-attribute</literal>. The attribute which contains |                         name of the authority defined by the group entry. Defaults to | ||||||
|                             the name of the authority defined by the group entry. Defaults to |                         <literal>cn</literal> </para> | ||||||
|                                 <literal>cn</literal> |  | ||||||
|                         </para> |  | ||||||
|                 </listitem> |                 </listitem> | ||||||
|                 <listitem> |                 <listitem> | ||||||
|                         <para> |                     <para> <literal>group-search-filter</literal>. The filter which is used to | ||||||
|                             <literal>group-search-filter</literal>. The filter which is used to |  | ||||||
|                         search for group membership. The default is |                         search for group membership. The default is | ||||||
|                         <literal>uniqueMember={0}</literal>, corresponding to the |                         <literal>uniqueMember={0}</literal>, corresponding to the | ||||||
|                                 <literal>groupOfUniqueMembers</literal> LDAP class. In this case, |                         <literal>groupOfUniqueMembers</literal> LDAP class. In this case, the | ||||||
|                             the substituted parameter is the full distinguished name of the user. |                         substituted parameter is the full distinguished name of the user. The | ||||||
|                             The parameter <literal>{1}</literal> can be used if you want to filter |                         parameter <literal>{1}</literal> can be used if you want to filter on the | ||||||
|                             on the login name.</para> |                         login name.</para> | ||||||
|                 </listitem> |                 </listitem> | ||||||
|                 </itemizedlist> So if we used the following configuration <programlisting><![CDATA[ |                 </itemizedlist> So if we used the following configuration <programlisting><![CDATA[ | ||||||
|   <ldap-authentication-provider user-dn-pattern="uid={0},ou=people" |   <ldap-authentication-provider user-dn-pattern="uid={0},ou=people" | ||||||
|           group-search-base="ou=groups" /> |           group-search-base="ou=groups" /> | ||||||
|     ]]></programlisting> and authenticated successfully as user <quote>ben</quote>, the subsequent |     ]]></programlisting> and authenticated successfully as user <quote>ben</quote>, the subsequent | ||||||
|                 loading of authorities would perform a search under the directory entry |                 loading of authorities would perform a search under the directory entry | ||||||
|                     <literal>ou=groups,dc=springframework,dc=org</literal>, looking for entries |                 <literal>ou=groups,dc=springframework,dc=org</literal>, looking for entries which | ||||||
|                 which contain the attribute <literal>uniqueMember</literal> with value |                 contain the attribute <literal>uniqueMember</literal> with value | ||||||
|                 <literal>uid=ben,ou=people,dc=springframework,dc=org</literal>. By default the |                 <literal>uid=ben,ou=people,dc=springframework,dc=org</literal>. By default the | ||||||
|                 authority names will have the prefix <literal>ROLE_</literal> prepended. You can |                 authority names will have the prefix <literal>ROLE_</literal> prepended. You can | ||||||
|                 change this using the <literal>role-prefix</literal> attribute. If you don't want |                 change this using the <literal>role-prefix</literal> attribute. If you don't want | ||||||
|  | @ -173,16 +168,14 @@ | ||||||
|                 to read them with the user's own permissions.</para> |                 to read them with the user's own permissions.</para> | ||||||
|             <para>There are currently two authentication strategies supplied with Spring Security: <itemizedlist> |             <para>There are currently two authentication strategies supplied with Spring Security: <itemizedlist> | ||||||
|                 <listitem> |                 <listitem> | ||||||
|                         <para>Authentication directly to the LDAP server ("bind" |                     <para>Authentication directly to the LDAP server ("bind" authentication).</para> | ||||||
|                             authentication).</para> |  | ||||||
|                 </listitem> |                 </listitem> | ||||||
|                 <listitem> |                 <listitem> | ||||||
|                         <para>Password comparison, where the password supplied by the user is |                     <para>Password comparison, where the password supplied by the user is compared | ||||||
|                             compared with the one stored in the repository. This can either be done |                         with the one stored in the repository. This can either be done by retrieving | ||||||
|                             by retrieving the value of the password attribute and checking it |                         the value of the password attribute and checking it locally or by performing | ||||||
|                             locally or by performing an LDAP "compare" operation, where the supplied |                         an LDAP "compare" operation, where the supplied password is passed to the | ||||||
|                             password is passed to the server for comparison and the real password |                         server for comparison and the real password value is never retrieved.</para> | ||||||
|                             value is never retrieved.</para> |  | ||||||
|                 </listitem> |                 </listitem> | ||||||
|                 </itemizedlist></para> |                 </itemizedlist></para> | ||||||
|             <section xml:id="ldap-ldap-authenticators-common"> |             <section xml:id="ldap-ldap-authenticators-common"> | ||||||
|  | @ -193,32 +186,31 @@ | ||||||
|                     distinguished name (DN) has to be obtained from the login name supplied to the |                     distinguished name (DN) has to be obtained from the login name supplied to the | ||||||
|                     application. This can be done either by simple pattern-matching (by setting the |                     application. This can be done either by simple pattern-matching (by setting the | ||||||
|                     <property>setUserDnPatterns</property> array property) or by setting the |                     <property>setUserDnPatterns</property> array property) or by setting the | ||||||
|                         <property>userSearch</property> property. For the DN pattern-matching |                     <property>userSearch</property> property. For the DN pattern-matching approach, | ||||||
|                     approach, a standard Java pattern format is used, and the login name will be |                     a standard Java pattern format is used, and the login name will be substituted | ||||||
|                     substituted for the parameter <parameter>{0}</parameter>. The pattern should be |                     for the parameter <parameter>{0}</parameter>. The pattern should be relative to | ||||||
|                     relative to the DN that the configured |                     the DN that the configured | ||||||
|                         <interfacename>SpringSecurityContextSource</interfacename> will bind to (see |                     <interfacename>SpringSecurityContextSource</interfacename> will bind to (see the | ||||||
|                     the section on <link linkend="ldap-context-source">connecting to the LDAP |                     section on <link linkend="ldap-context-source">connecting to the LDAP | ||||||
|                         server</link> for more information on this). For example, if you are using |                     server</link> for more information on this). For example, if you are using an | ||||||
|                     an LDAP server with the URL |                     LDAP server with the URL | ||||||
|                     <literal>ldap://monkeymachine.co.uk/dc=springframework,dc=org</literal>, and |                     <literal>ldap://monkeymachine.co.uk/dc=springframework,dc=org</literal>, and | ||||||
|                     have a pattern <literal>uid={0},ou=greatapes</literal>, then a login name of |                     have a pattern <literal>uid={0},ou=greatapes</literal>, then a login name of | ||||||
|                     "gorilla" will map to a DN |                     "gorilla" will map to a DN | ||||||
|                     <literal>uid=gorilla,ou=greatapes,dc=springframework,dc=org</literal>. Each |                     <literal>uid=gorilla,ou=greatapes,dc=springframework,dc=org</literal>. Each | ||||||
|                     configured DN pattern will be tried in turn until a match is found. For |                     configured DN pattern will be tried in turn until a match is found. For | ||||||
|                     information on using a search, see the section on <link |                     information on using a search, see the section on <link | ||||||
|                         linkend="ldap-searchobjects">search objects</link> below. A combination of |                     linkend="ldap-searchobjects">search objects</link> below. A combination of the | ||||||
|                     the two approaches can also be used - the patterns will be checked first and if |                     two approaches can also be used - the patterns will be checked first and if no | ||||||
|                     no matching DN is found, the search will be used.</para> |                     matching DN is found, the search will be used.</para> | ||||||
|             </section> |             </section> | ||||||
|             <section xml:id="ldap-ldap-authenticators-bind"> |             <section xml:id="ldap-ldap-authenticators-bind"> | ||||||
|                 <info> |                 <info> | ||||||
|                     <title>BindAuthenticator</title> |                     <title>BindAuthenticator</title> | ||||||
|                 </info> |                 </info> | ||||||
|                 <para>The class <classname>BindAuthenticator</classname> in the package |                 <para>The class <classname>BindAuthenticator</classname> in the package | ||||||
|                         <filename>org.springframework.security.ldap.authentication</filename> |                     <filename>org.springframework.security.ldap.authentication</filename> implements | ||||||
|                     implements the bind authentication strategy. It simply attempts to bind as the |                     the bind authentication strategy. It simply attempts to bind as the user.</para> | ||||||
|                     user.</para> |  | ||||||
|             </section> |             </section> | ||||||
|             <section xml:id="ldap-ldap-authenticators-password"> |             <section xml:id="ldap-ldap-authenticators-password"> | ||||||
|                 <info> |                 <info> | ||||||
|  | @ -254,16 +246,15 @@ | ||||||
|             <info> |             <info> | ||||||
|                 <title>LDAP Search Objects</title> |                 <title>LDAP Search Objects</title> | ||||||
|             </info> |             </info> | ||||||
|             <para>Often a more complicated strategy than simple DN-matching is required to |             <para>Often a more complicated strategy than simple DN-matching is required to locate a | ||||||
|                 locate a user entry in the directory. This can be encapsulated in an |                 user entry in the directory. This can be encapsulated in an | ||||||
|                     <interfacename>LdapUserSearch</interfacename> instance which can be supplied to |                 <interfacename>LdapUserSearch</interfacename> instance which can be supplied to the | ||||||
|                 the authenticator implementations, for example, to allow them to locate a user. The |                 authenticator implementations, for example, to allow them to locate a user. The | ||||||
|                 supplied implementation is <classname>FilterBasedLdapUserSearch</classname>.</para> |                 supplied implementation is <classname>FilterBasedLdapUserSearch</classname>.</para> | ||||||
|             <section xml:id="ldap-searchobjects-filter"> |             <section xml:id="ldap-searchobjects-filter"> | ||||||
|                 <info> |                 <info> | ||||||
|                     <title xml:id="ldap-searchobjects-filter-based"> |                     <title xml:id="ldap-searchobjects-filter-based"> | ||||||
|                         <classname>FilterBasedLdapUserSearch</classname> |                         <classname>FilterBasedLdapUserSearch</classname> </title> | ||||||
|                     </title> |  | ||||||
|                 </info> |                 </info> | ||||||
|                 <para>This bean uses an LDAP filter to match the user object in the directory. The |                 <para>This bean uses an LDAP filter to match the user object in the directory. The | ||||||
|                     process is explained in the Javadoc for the corresponding search method on the |                     process is explained in the Javadoc for the corresponding search method on the | ||||||
|  | @ -281,11 +272,11 @@ | ||||||
|                 <classname>LdapAuthenticationProvider</classname> will attempt to load a set of |                 <classname>LdapAuthenticationProvider</classname> will attempt to load a set of | ||||||
|                 authorities for the user by calling the configured |                 authorities for the user by calling the configured | ||||||
|                 <interfacename>LdapAuthoritiesPopulator</interfacename> bean. The |                 <interfacename>LdapAuthoritiesPopulator</interfacename> bean. The | ||||||
|                     <classname>DefaultLdapAuthoritiesPopulator</classname> is an implementation |                 <classname>DefaultLdapAuthoritiesPopulator</classname> is an implementation which | ||||||
|                 which will load the authorities by searching the directory for groups of which the |                 will load the authorities by searching the directory for groups of which the user is | ||||||
|                 user is a member (typically these will be <literal>groupOfNames</literal> or |                 a member (typically these will be <literal>groupOfNames</literal> or | ||||||
|                     <literal>groupOfUniqueNames</literal> entries in the directory). Consult the |                 <literal>groupOfUniqueNames</literal> entries in the directory). Consult the Javadoc | ||||||
|                 Javadoc for this class for more details on how it works. </para> |                 for this class for more details on how it works. </para> | ||||||
|             <para>If you want to use LDAP only for authentication, but load the authorities from a |             <para>If you want to use LDAP only for authentication, but load the authorities from a | ||||||
|                 difference source (such as a database) then you can provide your own implementation |                 difference source (such as a database) then you can provide your own implementation | ||||||
|                 of this interface and inject that instead.</para> |                 of this interface and inject that instead.</para> | ||||||
|  | @ -331,8 +322,8 @@ | ||||||
|                 filter <literal>(member=<user's-DN>)</literal>. The role name will be taken |                 filter <literal>(member=<user's-DN>)</literal>. The role name will be taken | ||||||
|                 from the <quote>ou</quote> attribute of each match.</para> |                 from the <quote>ou</quote> attribute of each match.</para> | ||||||
|             <para>To configure a user search object, which uses the filter |             <para>To configure a user search object, which uses the filter | ||||||
|                     <literal>(uid=<user-login-name>)</literal> for use instead of the |                 <literal>(uid=<user-login-name>)</literal> for use instead of the DN-pattern | ||||||
|                 DN-pattern (or in addition to it), you would configure the following bean <programlisting><![CDATA[ |                 (or in addition to it), you would configure the following bean <programlisting><![CDATA[ | ||||||
| <bean id="userSearch" | <bean id="userSearch" | ||||||
|     class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch"> |     class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch"> | ||||||
|   <constructor-arg index="0" value=""/> |   <constructor-arg index="0" value=""/> | ||||||
|  | @ -355,25 +346,25 @@ | ||||||
|                 <interfacename>UserDetailsService</interfacename>, a common requirement is to be |                 <interfacename>UserDetailsService</interfacename>, a common requirement is to be | ||||||
|                 able to customize this implementation and add extra properties. When using LDAP, |                 able to customize this implementation and add extra properties. When using LDAP, | ||||||
|                 these will normally be attributes from the user entry. The creation of the |                 these will normally be attributes from the user entry. The creation of the | ||||||
|                     <interfacename>UserDetails</interfacename> object is controlled by the |                 <interfacename>UserDetails</interfacename> object is controlled by the provider's | ||||||
|                 provider's <interfacename>UserDetailsContextMapper</interfacename> strategy, which |                 <interfacename>UserDetailsContextMapper</interfacename> strategy, which is | ||||||
|                 is responsible for mapping user objects to and from LDAP context data: <programlisting><![CDATA[ |                 responsible for mapping user objects to and from LDAP context data: <programlisting><![CDATA[ | ||||||
| public interface UserDetailsContextMapper { | public interface UserDetailsContextMapper { | ||||||
|   UserDetails mapUserFromContext(DirContextOperations ctx, String username, |   UserDetails mapUserFromContext(DirContextOperations ctx, String username, | ||||||
|           Collection<GrantedAuthority> authorities); |           Collection<GrantedAuthority> authorities); | ||||||
| 
 | 
 | ||||||
|   void mapUserToContext(UserDetails user, DirContextAdapter ctx); |   void mapUserToContext(UserDetails user, DirContextAdapter ctx); | ||||||
| }]]> | }]]> | ||||||
|                 </programlisting> Only the first method is relevant for |                 </programlisting> Only the first method is relevant for authentication. If you | ||||||
|                 authentication. If you provide an implementation of this interface, you can control |                 provide an implementation of this interface, you can control exactly how the | ||||||
|                 exactly how the UserDetails object is created. The first parameter is an instance of |                 UserDetails object is created. The first parameter is an instance of Spring LDAP's | ||||||
|                 Spring LDAP's <interfacename>DirContextOperations</interfacename> which gives you |                 <interfacename>DirContextOperations</interfacename> which gives you access to the | ||||||
|                 access to the LDAP attributes which were loaded. The <literal>username</literal> |                 LDAP attributes which were loaded. The <literal>username</literal> parameter is the | ||||||
|                 parameter is the name used to authenticate and the final parameter is the collection |                 name used to authenticate and the final parameter is the collection of authorities | ||||||
|                 of authorities loaded for the user. </para> |                 loaded for the user. </para> | ||||||
|             <para> The way the context data is loaded varies slightly depending on the type of |             <para> The way the context data is loaded varies slightly depending on the type of | ||||||
|                 authentication you are using. With the <classname>BindAuthenticator</classname>, |                 authentication you are using. With the <classname>BindAuthenticator</classname>, the | ||||||
|                 the context returned from the bind operation will be used to read the attributes, |                 context returned from the bind operation will be used to read the attributes, | ||||||
|                 otherwise the data will be read using the standard context obtained from the |                 otherwise the data will be read using the standard context obtained from the | ||||||
|                 configured <interfacename>ContextSource</interfacename> (when a search is configured |                 configured <interfacename>ContextSource</interfacename> (when a search is configured | ||||||
|                 to locate the user, this will be the data returned by the search object). </para> |                 to locate the user, this will be the data returned by the search object). </para> | ||||||
|  |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -4,135 +4,147 @@ | ||||||
|     <info> |     <info> | ||||||
|         <title>Pre-Authentication Scenarios</title> |         <title>Pre-Authentication Scenarios</title> | ||||||
|     </info> |     </info> | ||||||
|   <para> There are situations where you want to use Spring Security for authorization, but the user |     <para> There are situations where you want to use Spring Security for authorization, but the | ||||||
|     has already been reliably authenticated by some external system prior to accessing the |         user has already been reliably authenticated by some external system prior to accessing the | ||||||
|         application. We refer to these situations as <quote>pre-authenticated</quote> scenarios. |         application. We refer to these situations as <quote>pre-authenticated</quote> scenarios. | ||||||
|         Examples include X.509, Siteminder and authentication by the J2EE container in which the |         Examples include X.509, Siteminder and authentication by the J2EE container in which the | ||||||
|     application is running. When using pre-authentication, Spring Security has to |         application is running. When using pre-authentication, Spring Security has to <orderedlist> | ||||||
|           <orderedlist><listitem><para>Identify the user making the request. |         <listitem> | ||||||
|           </para></listitem><listitem><para>Obtain the authorities for the |             <para>Identify the user making the request. </para> | ||||||
|       user.</para></listitem></orderedlist>The details will depend on the external authentication |         </listitem> | ||||||
|     mechanism. A user might be identified by their certificate information in the case of X.509, or |         <listitem> | ||||||
|     by an HTTP request header in the case of Siteminder. If relying on container authentication, the |             <para>Obtain the authorities for the user.</para> | ||||||
|     user will be identified by calling the <methodname>getUserPrincipal()</methodname> method on the |         </listitem> | ||||||
|     incoming HTTP request. In some cases, the external mechanism may supply role/authority |         </orderedlist>The details will depend on the external authentication mechanism. A user might | ||||||
|     information for the user but in others the authorities must be obtained from a separate source, |         be identified by their certificate information in the case of X.509, or by an HTTP request | ||||||
|     such as a <interfacename>UserDetailsService</interfacename>. </para> |         header in the case of Siteminder. If relying on container authentication, the user will be | ||||||
|  |         identified by calling the <methodname>getUserPrincipal()</methodname> method on the incoming | ||||||
|  |         HTTP request. In some cases, the external mechanism may supply role/authority information | ||||||
|  |         for the user but in others the authorities must be obtained from a separate source, such as | ||||||
|  |         a <interfacename>UserDetailsService</interfacename>. </para> | ||||||
|     <section> |     <section> | ||||||
|         <title>Pre-Authentication Framework Classes</title> |         <title>Pre-Authentication Framework Classes</title> | ||||||
|     <para> Because most pre-authentication mechanisms follow the same pattern, Spring Security has a |         <para> Because most pre-authentication mechanisms follow the same pattern, Spring Security | ||||||
|       set of classes which provide an internal framework for implementing pre-authenticated |             has a set of classes which provide an internal framework for implementing | ||||||
|       authentication providers. This removes duplication and allows new implementations to be added |             pre-authenticated authentication providers. This removes duplication and allows new | ||||||
|       in a structured fashion, without having to write everything from scratch. You don't need to |             implementations to be added in a structured fashion, without having to write everything | ||||||
|       know about these classes if you want to use something like <link xlink:href="#x509">X.509 |             from scratch. You don't need to know about these classes if you want to use something | ||||||
|         authentication</link>, as it already has a namespace configuration option which is simpler |             like <link xlink:href="#x509">X.509 authentication</link>, as it already has a namespace | ||||||
|       to use and get started with. If you need to use explicit bean configuration or are planning on |             configuration option which is simpler to use and get started with. If you need to use | ||||||
|       writing your own implementation then an understanding of how the provided implementations work |             explicit bean configuration or are planning on writing your own implementation then an | ||||||
|       will be useful. You will find classes under the |             understanding of how the provided implementations work will be useful. You will find | ||||||
|         <package>org.springframework.security.web.authentication.preauth</package>. We just provide |             classes under the | ||||||
|       an outline here so you should consult the Javadoc and source where appropriate. </para> |             <package>org.springframework.security.web.authentication.preauth</package>. We just | ||||||
|  |             provide an outline here so you should consult the Javadoc and source where appropriate. </para> | ||||||
|         <section> |         <section> | ||||||
|             <title>AbstractPreAuthenticatedProcessingFilter</title> |             <title>AbstractPreAuthenticatedProcessingFilter</title> | ||||||
|       <para> This class will check the current contents of the security context and, if empty, it |             <para> This class will check the current contents of the security context and, if empty, | ||||||
|         will attempt to extract user information from the HTTP request and submit it to the |                 it will attempt to extract user information from the HTTP request and submit it to | ||||||
|           <interfacename>AuthenticationManager</interfacename>. Subclasses override the following |                 the <interfacename>AuthenticationManager</interfacename>. Subclasses override the | ||||||
|         methods to obtain this information: |                 following methods to obtain this information: | ||||||
|                 <programlisting language="java"> |                 <programlisting language="java"> | ||||||
|   protected abstract Object getPreAuthenticatedPrincipal(HttpServletRequest request); |   protected abstract Object getPreAuthenticatedPrincipal(HttpServletRequest request); | ||||||
| 
 | 
 | ||||||
|   protected abstract Object getPreAuthenticatedCredentials(HttpServletRequest request); |   protected abstract Object getPreAuthenticatedCredentials(HttpServletRequest request); | ||||||
| </programlisting> | </programlisting> | ||||||
|                 After calling these, the filter will create a |                 After calling these, the filter will create a | ||||||
|           <classname>PreAuthenticatedAuthenticationToken</classname> containing the returned data |                 <classname>PreAuthenticatedAuthenticationToken</classname> containing the returned | ||||||
|         and submit it for authentication. By <quote>authentication</quote> here, we really just mean |                 data and submit it for authentication. By <quote>authentication</quote> here, we | ||||||
|         further processing to perhaps load the user's authorities, but the standard Spring Security |                 really just mean further processing to perhaps load the user's authorities, but the | ||||||
|         authentication architecture is followed. </para> |                 standard Spring Security authentication architecture is followed. </para> | ||||||
|         </section> |         </section> | ||||||
|         <section> |         <section> | ||||||
|             <title>AbstractPreAuthenticatedAuthenticationDetailsSource</title> |             <title>AbstractPreAuthenticatedAuthenticationDetailsSource</title> | ||||||
|       <para> Like other Spring Security authentication filters, the pre-authentication filter has an |             <para> Like other Spring Security authentication filters, the pre-authentication filter | ||||||
|           <literal>authenticationDetailsSource</literal> property which by default will create a |                 has an <literal>authenticationDetailsSource</literal> property which by default will | ||||||
|           <classname>WebAuthenticationDetails</classname> object to store additional information |                 create a <classname>WebAuthenticationDetails</classname> object to store additional | ||||||
|         such as the session-identifier and originating IP address in the <literal>details</literal> |                 information such as the session-identifier and originating IP address in the | ||||||
|         property of the <interfacename>Authentication</interfacename> object. In cases where user |                 <literal>details</literal> property of the | ||||||
|         role information can be obtained from the pre-authentication mechanism, the data is also |                 <interfacename>Authentication</interfacename> object. In cases where user role | ||||||
|  |                 information can be obtained from the pre-authentication mechanism, the data is also | ||||||
|                 stored in this property. Subclasses of |                 stored in this property. Subclasses of | ||||||
|           <classname>AbstractPreAuthenticatedAuthenticationDetailsSource</classname> use an extended |                 <classname>AbstractPreAuthenticatedAuthenticationDetailsSource</classname> use an | ||||||
|         details object which implements the |                 extended details object which implements the | ||||||
|           <interfacename>GrantedAuthoritiesContainer</interfacename> interface, thus enabling the |                 <interfacename>GrantedAuthoritiesContainer</interfacename> interface, thus enabling | ||||||
|         authentication provider to read the authorities which were externally allocated to the user. |                 the authentication provider to read the authorities which were externally allocated | ||||||
|         We'll look at a concrete example next. </para> |                 to the user. We'll look at a concrete example next. </para> | ||||||
|             <section xml:id="j2ee-preauth-details"> |             <section xml:id="j2ee-preauth-details"> | ||||||
|                 <title>J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource</title> |                 <title>J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource</title> | ||||||
|         <para> If the filter is configured with an <literal>authenticationDetailsSource</literal> |                 <para> If the filter is configured with an | ||||||
|           which is an instance of this class, the authority information is obtained by calling the |                     <literal>authenticationDetailsSource</literal> which is an instance of this | ||||||
|             <methodname>isUserInRole(String role)</methodname> method for each of a pre-determined |                     class, the authority information is obtained by calling the | ||||||
|           set of <quote>mappable roles</quote>. The class gets these from a configured |                     <methodname>isUserInRole(String role)</methodname> method for each of a | ||||||
|             <interfacename>MappableAttributesRetriever</interfacename>. Possible implementations |                     pre-determined set of <quote>mappable roles</quote>. The class gets these from a | ||||||
|           include hard-coding a list in the application context and reading the role information |                     configured <interfacename>MappableAttributesRetriever</interfacename>. Possible | ||||||
|           from the <literal><security-role></literal> information in a |                     implementations include hard-coding a list in the application context and | ||||||
|             <filename>web.xml</filename> file. The pre-authentication sample application uses the |                     reading the role information from the <literal><security-role></literal> | ||||||
|           latter approach. </para> |                     information in a <filename>web.xml</filename> file. The pre-authentication | ||||||
|         <para>There is an additional stage where the roles (or attributes) are mapped to Spring |                     sample application uses the latter approach. </para> | ||||||
|           Security <interfacename>GrantedAuthority</interfacename> objects using a configured |                 <para>There is an additional stage where the roles (or attributes) are mapped to | ||||||
|             <interfacename>Attributes2GrantedAuthoritiesMapper</interfacename>. The default will |                     Spring Security <interfacename>GrantedAuthority</interfacename> objects using a | ||||||
|           just add the usual <literal>ROLE_</literal> prefix to the names, but it gives you full |                     configured <interfacename>Attributes2GrantedAuthoritiesMapper</interfacename>. | ||||||
|           control over the behaviour. </para> |                     The default will just add the usual <literal>ROLE_</literal> prefix to the | ||||||
|  |                     names, but it gives you full control over the behaviour. </para> | ||||||
|             </section> |             </section> | ||||||
|         </section> |         </section> | ||||||
|         <section> |         <section> | ||||||
|             <title>PreAuthenticatedAuthenticationProvider</title> |             <title>PreAuthenticatedAuthenticationProvider</title> | ||||||
|             <para> The pre-authenticated provider has little more to do than load the |             <para> The pre-authenticated provider has little more to do than load the | ||||||
|           <interfacename>UserDetails</interfacename> object for the user. It does this by delegating |                 <interfacename>UserDetails</interfacename> object for the user. It does this by | ||||||
|         to a <interfacename>AuthenticationUserDetailsService</interfacename>. The latter is similar |                 delegating to a <interfacename>AuthenticationUserDetailsService</interfacename>. The | ||||||
|         to the standard <interfacename>UserDetailsService</interfacename> but takes an |                 latter is similar to the standard <interfacename>UserDetailsService</interfacename> | ||||||
|           <interfacename>Authentication</interfacename> object rather than just user name: |                 but takes an <interfacename>Authentication</interfacename> object rather than just | ||||||
|  |                 user name: | ||||||
|                 <programlisting language="java"> |                 <programlisting language="java"> | ||||||
|   public interface AuthenticationUserDetailsService { |   public interface AuthenticationUserDetailsService { | ||||||
|     UserDetails loadUserDetails(Authentication token) throws UsernameNotFoundException; |     UserDetails loadUserDetails(Authentication token) throws UsernameNotFoundException; | ||||||
|   } |   } | ||||||
| </programlisting> | </programlisting> | ||||||
|         This interface may have also other uses but with pre-authentication it allows access to the |                 This interface may have also other uses but with pre-authentication it allows access | ||||||
|         authorities which were packaged in the <interfacename>Authentication</interfacename> object, |                 to the authorities which were packaged in the | ||||||
|         as we saw in the previous section. The |                 <interfacename>Authentication</interfacename> object, as we saw in the previous | ||||||
|           <classname>PreAuthenticatedGrantedAuthoritiesUserDetailsService</classname> class does |                 section. The | ||||||
|         this. Alternatively, it may delegate to a standard |                 <classname>PreAuthenticatedGrantedAuthoritiesUserDetailsService</classname> class | ||||||
|  |                 does this. Alternatively, it may delegate to a standard | ||||||
|                 <interfacename>UserDetailsService</interfacename> via the |                 <interfacename>UserDetailsService</interfacename> via the | ||||||
|                 <classname>UserDetailsByNameServiceWrapper</classname> implementation. </para> |                 <classname>UserDetailsByNameServiceWrapper</classname> implementation. </para> | ||||||
|         </section> |         </section> | ||||||
|         <section> |         <section> | ||||||
|             <title>Http403ForbiddenEntryPoint</title> |             <title>Http403ForbiddenEntryPoint</title> | ||||||
|       <para> The <interfacename>AuthenticationEntryPoint</interfacename> was discussed in the <link |             <para> The <interfacename>AuthenticationEntryPoint</interfacename> was discussed in the | ||||||
|           xlink:href="#tech-intro-auth-entry-point">technical overview</link> chapter. Normally it |                 <link xlink:href="#tech-intro-auth-entry-point">technical overview</link> chapter. | ||||||
|         is responsible for kick-starting the authentication process for an unauthenticated user |                 Normally it is responsible for kick-starting the authentication process for an | ||||||
|         (when they try to access a protected resource), but in the pre-authenticated case this |                 unauthenticated user (when they try to access a protected resource), but in the | ||||||
|         doesn't apply. You would only configure the |                 pre-authenticated case this doesn't apply. You would only configure the | ||||||
|           <classname>ExceptionTranslationFilter</classname> with an instance of this class if you |                 <classname>ExceptionTranslationFilter</classname> with an instance of this class if | ||||||
|         aren't using pre-authentication in combination with other authentication mechanisms. It will |                 you aren't using pre-authentication in combination with other authentication | ||||||
|         be called if the user is rejected by the |                 mechanisms. It will be called if the user is rejected by the | ||||||
|                 <classname>AbstractPreAuthenticatedProcessingFilter</classname> resulting in a null |                 <classname>AbstractPreAuthenticatedProcessingFilter</classname> resulting in a null | ||||||
|         authentication. It always returns a <literal>403</literal>-forbidden response code if |                 authentication. It always returns a <literal>403</literal>-forbidden response code | ||||||
|         called. </para> |                 if called. </para> | ||||||
|         </section> |         </section> | ||||||
|     </section> |     </section> | ||||||
|     <section> |     <section> | ||||||
|         <title>Concrete Implementations</title> |         <title>Concrete Implementations</title> | ||||||
|     <para> X.509 authentication is covered in its <link xlink:href="#x509">own chapter</link>. Here |         <para> X.509 authentication is covered in its <link xlink:href="#x509">own chapter</link>. | ||||||
|       we'll look at some classes which provide support for other pre-authenticated scenarios. </para> |             Here we'll look at some classes which provide support for other pre-authenticated | ||||||
|  |             scenarios. </para> | ||||||
|         <section> |         <section> | ||||||
|             <title>Request-Header Authentication (Siteminder)</title> |             <title>Request-Header Authentication (Siteminder)</title> | ||||||
|       <para> An external authentication system may supply information to the application by setting |             <para> An external authentication system may supply information to the application by | ||||||
|         specific headers on the HTTP request. A well known example of this is Siteminder, which |                 setting specific headers on the HTTP request. A well known example of this is | ||||||
|         passes the username in a header called <literal>SM_USER</literal>. This mechanism is |                 Siteminder, which passes the username in a header called <literal>SM_USER</literal>. | ||||||
|         supported by the class <classname>RequestHeaderAuthenticationFilter</classname> which simply |                 This mechanism is supported by the class | ||||||
|         extracts the username from the header. It defaults to using the name |                 <classname>RequestHeaderAuthenticationFilter</classname> which simply extracts the | ||||||
|           <literal>SM_USER</literal> as the header name. See the Javadoc for more details. </para> |                 username from the header. It defaults to using the name <literal>SM_USER</literal> | ||||||
|  |                 as the header name. See the Javadoc for more details. </para> | ||||||
|             <tip> |             <tip> | ||||||
|         <para>Note that when using a system like this, the framework performs no authentication |                 <para>Note that when using a system like this, the framework performs no | ||||||
|           checks at all and it is <emphasis>extremely</emphasis> important that the external system |                     authentication checks at all and it is <emphasis>extremely</emphasis> important | ||||||
|           is configured properly and protects all access to the application. If an attacker is able |                     that the external system is configured properly and protects all access to the | ||||||
|           to forge the headers in their original request without this being detected then they could |                     application. If an attacker is able to forge the headers in their original | ||||||
|           potentially choose any username they wished. </para> |                     request without this being detected then they could potentially choose any | ||||||
|  |                     username they wished. </para> | ||||||
|             </tip> |             </tip> | ||||||
|             <section> |             <section> | ||||||
|                 <title>Siteminder Example Configuration</title> |                 <title>Siteminder Example Configuration</title> | ||||||
|  | @ -162,27 +174,28 @@ class="org.springframework.security.web.authentication.preauth.PreAuthenticatedA | ||||||
|       <security:authentication-provider ref="preauthAuthProvider" /> |       <security:authentication-provider ref="preauthAuthProvider" /> | ||||||
|     </security-authentication-manager> |     </security-authentication-manager> | ||||||
| ]]> | ]]> | ||||||
| </programlisting> We've assumed here that the security namespace is being used for | </programlisting> We've assumed here that the security namespace is being used for configuration | ||||||
|           configuration (hence the user of the <literal>custom-filter</literal>, |                     (hence the user of the <literal>custom-filter</literal>, | ||||||
|                     <literal>authentication-manager</literal> and |                     <literal>authentication-manager</literal> and | ||||||
|             <literal>custom-authentication-provider</literal> elements (you can read more about them |                     <literal>custom-authentication-provider</literal> elements (you can read more | ||||||
|           in the <link xlink:href="ns-config">namespace chapter</link>). You would leave these out |                     about them in the <link xlink:href="ns-config">namespace chapter</link>). You | ||||||
|           of a traditional bean configuration. It's also assumed that you have added a |                     would leave these out of a traditional bean configuration. It's also assumed | ||||||
|             <interfacename>UserDetailsService</interfacename> (called |                     that you have added a <interfacename>UserDetailsService</interfacename> (called | ||||||
|             <quote>userDetailsService</quote>) to your configuration to load the user's roles. |                     <quote>userDetailsService</quote>) to your configuration to load the user's | ||||||
|         </para> |                     roles. </para> | ||||||
|             </section> |             </section> | ||||||
|         </section> |         </section> | ||||||
|         <section> |         <section> | ||||||
|             <title>J2EE Container Authentication</title> |             <title>J2EE Container Authentication</title> | ||||||
|       <para> The class <classname>J2eePreAuthenticatedProcessingFilter</classname> will extract the |             <para> The class <classname>J2eePreAuthenticatedProcessingFilter</classname> will | ||||||
|         username from the <literal>userPrincipal</literal> property of the |                 extract the username from the <literal>userPrincipal</literal> property of the | ||||||
|           <interfacename>HttpServletRequest</interfacename>. Use of this filter would usually be |                 <interfacename>HttpServletRequest</interfacename>. Use of this filter would usually | ||||||
|         combined with the use of J2EE roles as described above in <xref |                 be combined with the use of J2EE roles as described above in <xref | ||||||
|                 linkend="j2ee-preauth-details"/>. </para> |                 linkend="j2ee-preauth-details"/>. </para> | ||||||
|       <para> There is a sample application in the codebase which uses this approach, so get hold of |             <para> There is a sample application in the codebase which uses this approach, so get | ||||||
|         the code from subversion and have a look at the application context file if you are |                 hold of the code from subversion and have a look at the application context file if | ||||||
|         interested. The code is in the <filename>samples/preauth</filename> directory. </para> |                 you are interested. The code is in the <filename>samples/preauth</filename> | ||||||
|  |                 directory. </para> | ||||||
|         </section> |         </section> | ||||||
|     </section> |     </section> | ||||||
| </chapter> | </chapter> | ||||||
|  |  | ||||||
|  | @ -15,10 +15,9 @@ | ||||||
|             One uses hashing to preserve the security of cookie-based tokens and the other uses a |             One uses hashing to preserve the security of cookie-based tokens and the other uses a | ||||||
|             database or other persistent storage mechanism to store the generated tokens. </para> |             database or other persistent storage mechanism to store the generated tokens. </para> | ||||||
|         <para> Note that both implemementations require a |         <para> Note that both implemementations require a | ||||||
|                 <interfacename>UserDetailsService</interfacename>. If you are using an |             <interfacename>UserDetailsService</interfacename>. If you are using an authentication | ||||||
|             authentication provider which doesn't use a |             provider which doesn't use a <interfacename>UserDetailsService</interfacename> (for | ||||||
|                 <interfacename>UserDetailsService</interfacename> (for example, the LDAP provider) |             example, the LDAP provider) then it won't work unless you also have a | ||||||
|             then it won't work unless you also have a |  | ||||||
|             <interfacename>UserDetailsService</interfacename> bean in your application context. |             <interfacename>UserDetailsService</interfacename> bean in your application context. | ||||||
|         </para> |         </para> | ||||||
|     </section> |     </section> | ||||||
|  | @ -63,12 +62,13 @@ | ||||||
|         <title>Persistent Token Approach</title> |         <title>Persistent Token Approach</title> | ||||||
|         <para>This approach is based on the article <link |         <para>This approach is based on the article <link | ||||||
|             xlink:href="http://jaspan.com/improved_persistent_login_cookie_best_practice" |             xlink:href="http://jaspan.com/improved_persistent_login_cookie_best_practice" | ||||||
|                 >http://jaspan.com/improved_persistent_login_cookie_best_practice</link> with some |             >http://jaspan.com/improved_persistent_login_cookie_best_practice</link> with some minor | ||||||
|             minor modifications <footnote><para>Essentially, the username is not included in the |             modifications <footnote> | ||||||
|                     cookie, to prevent exposing a valid login name unecessarily. There is a |             <para>Essentially, the username is not included in the cookie, to prevent exposing a | ||||||
|                     discussion on this in the comments section of this article.</para></footnote>. |                 valid login name unecessarily. There is a discussion on this in the comments section | ||||||
|             To use the this approach with namespace configuration, you would supply a datasource |                 of this article.</para> | ||||||
|             reference: <programlisting><![CDATA[ |             </footnote>. To use the this approach with namespace configuration, you would supply a | ||||||
|  |             datasource reference: <programlisting><![CDATA[ | ||||||
|   <http> |   <http> | ||||||
|     ... |     ... | ||||||
|     <remember-me data-source-ref="someDataSource"/> |     <remember-me data-source-ref="someDataSource"/> | ||||||
|  | @ -91,10 +91,10 @@ | ||||||
|         </info> |         </info> | ||||||
|         <para>Remember-me authentication is not used with basic authentication, given it is often |         <para>Remember-me authentication is not used with basic authentication, given it is often | ||||||
|             not used with <literal>HttpSession</literal>s. Remember-me is used with |             not used with <literal>HttpSession</literal>s. Remember-me is used with | ||||||
|                 <literal>UsernamePasswordAuthenticationFilter</literal>, and is implemented via |             <literal>UsernamePasswordAuthenticationFilter</literal>, and is implemented via hooks in | ||||||
|             hooks in the <literal>AbstractAuthenticationProcessingFilter</literal> superclass. The |             the <literal>AbstractAuthenticationProcessingFilter</literal> superclass. The hooks will | ||||||
|             hooks will invoke a concrete <interfacename>RememberMeServices</interfacename> at the |             invoke a concrete <interfacename>RememberMeServices</interfacename> at the appropriate | ||||||
|             appropriate times. The interface looks like this: |             times. The interface looks like this: | ||||||
|             <programlisting language="java"> |             <programlisting language="java"> | ||||||
|   Authentication autoLogin(HttpServletRequest request, HttpServletResponse response); |   Authentication autoLogin(HttpServletRequest request, HttpServletResponse response); | ||||||
|   void loginFail(HttpServletRequest request, HttpServletResponse response); |   void loginFail(HttpServletRequest request, HttpServletResponse response); | ||||||
|  | @ -122,12 +122,12 @@ | ||||||
|                 <literal>RememberMeAuthenticationProvider</literal>. A <literal>key</literal> is |                 <literal>RememberMeAuthenticationProvider</literal>. A <literal>key</literal> is | ||||||
|                 shared between this authentication provider and the |                 shared between this authentication provider and the | ||||||
|                 <literal>TokenBasedRememberMeServices</literal>. In addition, |                 <literal>TokenBasedRememberMeServices</literal>. In addition, | ||||||
|                     <literal>TokenBasedRememberMeServices</literal> requires A UserDetailsService |                 <literal>TokenBasedRememberMeServices</literal> requires A UserDetailsService from | ||||||
|                 from which it can retrieve the username and password for signature comparison |                 which it can retrieve the username and password for signature comparison purposes, | ||||||
|                 purposes, and generate the <literal>RememberMeAuthenticationToken</literal> to |                 and generate the <literal>RememberMeAuthenticationToken</literal> to contain the | ||||||
|                 contain the correct <interfacename>GrantedAuthority</interfacename>[]s. Some sort of |                 correct <interfacename>GrantedAuthority</interfacename>[]s. Some sort of logout | ||||||
|                 logout command should be provided by the application that invalidates the cookie if |                 command should be provided by the application that invalidates the cookie if the | ||||||
|                 the user requests this. <classname>TokenBasedRememberMeServices</classname> also |                 user requests this. <classname>TokenBasedRememberMeServices</classname> also | ||||||
|                 implements Spring Security's <interfacename>LogoutHandler</interfacename> interface |                 implements Spring Security's <interfacename>LogoutHandler</interfacename> interface | ||||||
|                 so can be used with <classname>LogoutFilter</classname> to have the cookie cleared |                 so can be used with <classname>LogoutFilter</classname> to have the cookie cleared | ||||||
|                 automatically. </para> |                 automatically. </para> | ||||||
|  | @ -162,14 +162,18 @@ | ||||||
|         <section> |         <section> | ||||||
|             <title>PersistentTokenBasedRememberMeServices</title> |             <title>PersistentTokenBasedRememberMeServices</title> | ||||||
|             <para> This class can be used in the same way as |             <para> This class can be used in the same way as | ||||||
|                     <classname>TokenBasedRememberMeServices</classname>, but it additionally needs |                 <classname>TokenBasedRememberMeServices</classname>, but it additionally needs to be | ||||||
|                 to be configured with a <interfacename>PersistentTokenRepository</interfacename> to |                 configured with a <interfacename>PersistentTokenRepository</interfacename> to store | ||||||
|                 store the tokens. There are two standard implementations. |                 the tokens. There are two standard implementations. <itemizedlist> | ||||||
|                                 <itemizedlist><listitem><para><classname>InMemoryTokenRepositoryImpl</classname> |                 <listitem> | ||||||
|                             which is intended for testing |                     <para><classname>InMemoryTokenRepositoryImpl</classname> which is intended for | ||||||
|                                 only.</para></listitem><listitem><para><classname>JdbcTokenRepositoryImpl</classname> |                         testing only.</para> | ||||||
|                             which stores the tokens in a database. </para></listitem></itemizedlist> |                 </listitem> | ||||||
|                 The database schema is described above in <xref |                 <listitem> | ||||||
|  |                     <para><classname>JdbcTokenRepositoryImpl</classname> which stores the tokens in | ||||||
|  |                         a database. </para> | ||||||
|  |                 </listitem> | ||||||
|  |                 </itemizedlist> The database schema is described above in <xref | ||||||
|                 linkend="remember-me-persistent-token"/>. </para> |                 linkend="remember-me-persistent-token"/>. </para> | ||||||
|         </section> |         </section> | ||||||
|     </section> |     </section> | ||||||
|  |  | ||||||
|  | @ -1,92 +1,84 @@ | ||||||
| <chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="runas"><info><title>Run-As Authentication Replacement</title></info> | <chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="runas"> | ||||||
| 
 |     <info> | ||||||
|  |         <title>Run-As Authentication Replacement</title> | ||||||
|  |     </info> | ||||||
| 
 | 
 | ||||||
|     <section xml:id="runas-overview"> |     <section xml:id="runas-overview"> | ||||||
|         <info><title>Overview</title></info> |         <info> | ||||||
|  |             <title>Overview</title> | ||||||
|  |         </info> | ||||||
| 
 | 
 | ||||||
|         <para>The <classname>AbstractSecurityInterceptor</classname> is able to |         <para>The <classname>AbstractSecurityInterceptor</classname> is able to temporarily replace | ||||||
|             temporarily replace the <interfacename>Authentication</interfacename> object in |             the <interfacename>Authentication</interfacename> object in the | ||||||
|             the <interfacename>SecurityContext</interfacename> and |             <interfacename>SecurityContext</interfacename> and | ||||||
|             <classname>SecurityContextHolder</classname> during the secure object |             <classname>SecurityContextHolder</classname> during the secure object callback phase. | ||||||
|             callback phase. This only occurs if the original |             This only occurs if the original <interfacename>Authentication</interfacename> object | ||||||
|             <interfacename>Authentication</interfacename> object was successfully processed by |             was successfully processed by the <interfacename>AuthenticationManager</interfacename> | ||||||
|             the <interfacename>AuthenticationManager</interfacename> and |             and <interfacename>AccessDecisionManager</interfacename>. The | ||||||
|             <interfacename>AccessDecisionManager</interfacename>. The |  | ||||||
|             <literal>RunAsManager</literal> will indicate the replacement |             <literal>RunAsManager</literal> will indicate the replacement | ||||||
|             <interfacename>Authentication</interfacename> object, if any, that should be used |             <interfacename>Authentication</interfacename> object, if any, that should be used during | ||||||
|             during the <literal>SecurityInterceptorCallback</literal>.</para> |             the <literal>SecurityInterceptorCallback</literal>.</para> | ||||||
| 
 | 
 | ||||||
|         <para>By temporarily replacing the <interfacename>Authentication</interfacename> |         <para>By temporarily replacing the <interfacename>Authentication</interfacename> object | ||||||
|             object during the secure object callback phase, the secured invocation |             during the secure object callback phase, the secured invocation will be able to call | ||||||
|             will be able to call other objects which require different |             other objects which require different authentication and authorization credentials. It | ||||||
|             authentication and authorization credentials. It will also be able to |             will also be able to perform any internal security checks for specific | ||||||
|             perform any internal security checks for specific |  | ||||||
|             <interfacename>GrantedAuthority</interfacename> objects. Because Spring Security |             <interfacename>GrantedAuthority</interfacename> objects. Because Spring Security | ||||||
|             provides a number of helper classes that automatically configure |             provides a number of helper classes that automatically configure remoting protocols | ||||||
|             remoting protocols based on the contents of the |             based on the contents of the <classname>SecurityContextHolder</classname>, these run-as | ||||||
|             <classname>SecurityContextHolder</classname>, these run-as replacements |             replacements are particularly useful when calling remote web services</para> | ||||||
|             are particularly useful when calling remote web services</para> |  | ||||||
|     </section> |     </section> | ||||||
| 
 | 
 | ||||||
|     <section xml:id="runas-config"> |     <section xml:id="runas-config"> | ||||||
|         <info><title>Configuration</title></info> |         <info> | ||||||
|  |             <title>Configuration</title> | ||||||
|  |         </info> | ||||||
|         <para>A <literal>RunAsManager</literal> interface is provided by Spring Security: |         <para>A <literal>RunAsManager</literal> interface is provided by Spring Security: | ||||||
|             <programlisting> |             <programlisting> | ||||||
|   Authentication buildRunAs(Authentication authentication, Object object, |   Authentication buildRunAs(Authentication authentication, Object object, | ||||||
|       List<ConfigAttribute> config); |       List<ConfigAttribute> config); | ||||||
|   boolean supports(ConfigAttribute attribute); |   boolean supports(ConfigAttribute attribute); | ||||||
|   boolean supports(Class clazz); |   boolean supports(Class clazz); | ||||||
|             </programlisting> |             </programlisting> </para> | ||||||
|         </para> |  | ||||||
| 
 | 
 | ||||||
|         <para>The first method returns the <interfacename>Authentication</interfacename> |         <para>The first method returns the <interfacename>Authentication</interfacename> object that | ||||||
|             object that should replace the existing |             should replace the existing <interfacename>Authentication</interfacename> object for the | ||||||
|             <interfacename>Authentication</interfacename> object for the duration of the |             duration of the method invocation. If the method returns <literal>null</literal>, it | ||||||
|             method invocation. If the method returns <literal>null</literal>, it |             indicates no replacement should be made. The second method is used by the | ||||||
|             indicates no replacement should be made. The second method is used by |             <classname>AbstractSecurityInterceptor</classname> as part of its startup validation of | ||||||
|             the <classname>AbstractSecurityInterceptor</classname> as part of its |             configuration attributes. The <literal>supports(Class)</literal> method is called by a | ||||||
|             startup validation of configuration attributes. The |             security interceptor implementation to ensure the configured | ||||||
|             <literal>supports(Class)</literal> method is called by a security |             <literal>RunAsManager</literal> supports the type of secure object that the security | ||||||
|             interceptor implementation to ensure the configured |             interceptor will present.</para> | ||||||
|             <literal>RunAsManager</literal> supports the type of secure object |  | ||||||
|             that the security interceptor will present.</para> |  | ||||||
| 
 | 
 | ||||||
|         <para>One concrete implementation of a <literal>RunAsManager</literal> |         <para>One concrete implementation of a <literal>RunAsManager</literal> is provided with | ||||||
|             is provided with Spring Security. The |             Spring Security. The <literal>RunAsManagerImpl</literal> class returns a replacement | ||||||
|             <literal>RunAsManagerImpl</literal> class returns a replacement |             <literal>RunAsUserToken</literal> if any <literal>ConfigAttribute</literal> starts with | ||||||
|             <literal>RunAsUserToken</literal> if any |             <literal>RUN_AS_</literal>. If any such <literal>ConfigAttribute</literal> is found, the | ||||||
|             <literal>ConfigAttribute</literal> starts with |             replacement <literal>RunAsUserToken</literal> will contain the same principal, | ||||||
|             <literal>RUN_AS_</literal>. If any such |  | ||||||
|             <literal>ConfigAttribute</literal> is found, the replacement |  | ||||||
|             <literal>RunAsUserToken</literal> will contain the same principal, |  | ||||||
|             credentials and granted authorities as the original |             credentials and granted authorities as the original | ||||||
|             <interfacename>Authentication</interfacename> object, along with a new |             <interfacename>Authentication</interfacename> object, along with a new | ||||||
|             <literal>GrantedAuthorityImpl</literal> for each |             <literal>GrantedAuthorityImpl</literal> for each <literal>RUN_AS_</literal> | ||||||
|             <literal>RUN_AS_</literal> <literal>ConfigAttribute</literal>. Each |             <literal>ConfigAttribute</literal>. Each new <literal>GrantedAuthorityImpl</literal> | ||||||
|             new <literal>GrantedAuthorityImpl</literal> will be prefixed with |             will be prefixed with <literal>ROLE_</literal>, followed by the | ||||||
|             <literal>ROLE_</literal>, followed by the <literal>RUN_AS</literal> |             <literal>RUN_AS</literal> <literal>ConfigAttribute</literal>. For example, a | ||||||
|             <literal>ConfigAttribute</literal>. For example, a |  | ||||||
|             <literal>RUN_AS_SERVER</literal> will result in the replacement |             <literal>RUN_AS_SERVER</literal> will result in the replacement | ||||||
|             <literal>RunAsUserToken</literal> containing a |             <literal>RunAsUserToken</literal> containing a <literal>ROLE_RUN_AS_SERVER</literal> | ||||||
|             <literal>ROLE_RUN_AS_SERVER</literal> granted authority.</para> |             granted authority.</para> | ||||||
| 
 | 
 | ||||||
|         <para>The replacement <literal>RunAsUserToken</literal> is just like |         <para>The replacement <literal>RunAsUserToken</literal> is just like any other | ||||||
|             any other <interfacename>Authentication</interfacename> object. It needs to be |             <interfacename>Authentication</interfacename> object. It needs to be authenticated by | ||||||
|             authenticated by the <interfacename>AuthenticationManager</interfacename>, |             the <interfacename>AuthenticationManager</interfacename>, probably via delegation to a | ||||||
|             probably via delegation to a suitable |             suitable <classname>AuthenticationProvider</classname>. The | ||||||
|             <classname>AuthenticationProvider</classname>. The |             <literal>RunAsImplAuthenticationProvider</literal> performs such authentication. It | ||||||
|             <literal>RunAsImplAuthenticationProvider</literal> performs such |             simply accepts as valid any <literal>RunAsUserToken</literal> presented.</para> | ||||||
|             authentication. It simply accepts as valid any |  | ||||||
|             <literal>RunAsUserToken</literal> presented.</para> |  | ||||||
| 
 | 
 | ||||||
|         <para>To ensure malicious code does not create a |         <para>To ensure malicious code does not create a <literal>RunAsUserToken</literal> and | ||||||
|             <literal>RunAsUserToken</literal> and present it for guaranteed |             present it for guaranteed acceptance by the | ||||||
|             acceptance by the <literal>RunAsImplAuthenticationProvider</literal>, |             <literal>RunAsImplAuthenticationProvider</literal>, the hash of a key is stored in all | ||||||
|             the hash of a key is stored in all generated tokens. The |             generated tokens. The <literal>RunAsManagerImpl</literal> and | ||||||
|             <literal>RunAsManagerImpl</literal> and |             <literal>RunAsImplAuthenticationProvider</literal> is created in the bean context with | ||||||
|             <literal>RunAsImplAuthenticationProvider</literal> is created in the |             the same key: <programlisting> | ||||||
|             bean context with the same key: |  | ||||||
|             <programlisting> |  | ||||||
| <![CDATA[ | <![CDATA[ | ||||||
| <bean id="runAsManager" | <bean id="runAsManager" | ||||||
|     class="org.springframework.security.access.intercept.RunAsManagerImpl"> |     class="org.springframework.security.access.intercept.RunAsManagerImpl"> | ||||||
|  | @ -97,10 +89,9 @@ | ||||||
|     class="org.springframework.security.access.intercept.RunAsImplAuthenticationProvider"> |     class="org.springframework.security.access.intercept.RunAsImplAuthenticationProvider"> | ||||||
|   <property name="key" value="my_run_as_password"/> |   <property name="key" value="my_run_as_password"/> | ||||||
| </bean>]]></programlisting></para> | </bean>]]></programlisting></para> | ||||||
|         <para>By using the same key, each <literal>RunAsUserToken</literal> |         <para>By using the same key, each <literal>RunAsUserToken</literal> can be validated it was | ||||||
|             can be validated it was created by an approved |             created by an approved <literal>RunAsManagerImpl</literal>. The | ||||||
|             <literal>RunAsManagerImpl</literal>. The |             <literal>RunAsUserToken</literal> is immutable after creation for security | ||||||
|             <literal>RunAsUserToken</literal> is immutable after creation for |             reasons</para> | ||||||
|             security reasons</para> |  | ||||||
|     </section> |     </section> | ||||||
| </chapter> | </chapter> | ||||||
|  |  | ||||||
|  | @ -10,22 +10,22 @@ | ||||||
|         the source as described in <link xlink:href="#get-source">the introduction</link> and it's |         the source as described in <link xlink:href="#get-source">the introduction</link> and it's | ||||||
|         easy to build the project using Maven. There is more information on the project web site at |         easy to build the project using Maven. There is more information on the project web site at | ||||||
|         <link xlink:href="http://www.springsource.org/security/"> |         <link xlink:href="http://www.springsource.org/security/"> | ||||||
|             http://www.springsource.org/security/ </link> if you need it. All paths referred to in |         http://www.springsource.org/security/ </link> if you need it. All paths referred to in this | ||||||
|         this chapter are relative to the project source directory. </para> |         chapter are relative to the project source directory. </para> | ||||||
|     <section xml:id="tutorial-sample"> |     <section xml:id="tutorial-sample"> | ||||||
|         <title>Tutorial Sample</title> |         <title>Tutorial Sample</title> | ||||||
|         <para> The tutorial sample is a nice basic example to get you started. It uses simple |         <para> The tutorial sample is a nice basic example to get you started. It uses simple | ||||||
|             namespace configuration throughout. The compiled application is included in the |             namespace configuration throughout. The compiled application is included in the | ||||||
|             distribution zip file, ready to be deployed into your web container |             distribution zip file, ready to be deployed into your web container | ||||||
|             (<filename>spring-security-samples-tutorial-3.0.x.war</filename>). The <link |             (<filename>spring-security-samples-tutorial-3.0.x.war</filename>). The <link | ||||||
|                 xlink:href="#ns-form-and-basic">form-based</link> authentication mechanism is used |             xlink:href="#ns-form-and-basic">form-based</link> authentication mechanism is used in | ||||||
|             in combination with the commonly-used <link xlink:href="#remember-me">remember-me</link> |             combination with the commonly-used <link xlink:href="#remember-me">remember-me</link> | ||||||
|             authentication provider to automatically remember the login using cookies.</para> |             authentication provider to automatically remember the login using cookies.</para> | ||||||
|         <para>We recommend you start with the tutorial sample, as the XML is minimal and easy to |         <para>We recommend you start with the tutorial sample, as the XML is minimal and easy to | ||||||
|             follow. Most importantly, you can easily add this one XML file (and its corresponding |             follow. Most importantly, you can easily add this one XML file (and its corresponding | ||||||
|                 <literal>web.xml</literal> entries) to your existing application. Only when this |             <literal>web.xml</literal> entries) to your existing application. Only when this basic | ||||||
|             basic integration is achieved do we suggest you attempt adding in method authorization |             integration is achieved do we suggest you attempt adding in method authorization or | ||||||
|             or domain object security.</para> |             domain object security.</para> | ||||||
|     </section> |     </section> | ||||||
|     <section xml:id="contacts-sample"> |     <section xml:id="contacts-sample"> | ||||||
|         <title>Contacts</title> |         <title>Contacts</title> | ||||||
|  | @ -35,11 +35,11 @@ | ||||||
|             administer a simple database of contacts (the domain objects).</para> |             administer a simple database of contacts (the domain objects).</para> | ||||||
|         <para>To deploy, simply copy the WAR file from Spring Security distribution into your |         <para>To deploy, simply copy the WAR file from Spring Security distribution into your | ||||||
|             container’s <literal>webapps</literal> directory. The war should be called |             container’s <literal>webapps</literal> directory. The war should be called | ||||||
|                 <filename>spring-security-samples-contacts-3.0.x.war</filename> (the appended |             <filename>spring-security-samples-contacts-3.0.x.war</filename> (the appended version | ||||||
|             version number will vary depending on what release you are using). </para> |             number will vary depending on what release you are using). </para> | ||||||
|         <para>After starting your container, check the application can load. Visit |         <para>After starting your container, check the application can load. Visit | ||||||
|                 <literal>http://localhost:8080/contacts</literal> (or whichever URL is appropriate |             <literal>http://localhost:8080/contacts</literal> (or whichever URL is appropriate for | ||||||
|             for your web container and the WAR you deployed). </para> |             your web container and the WAR you deployed). </para> | ||||||
|         <para>Next, click "Debug". You will be prompted to authenticate, and a series of usernames |         <para>Next, click "Debug". You will be prompted to authenticate, and a series of usernames | ||||||
|             and passwords are suggested on that page. Simply authenticate with any of these and view |             and passwords are suggested on that page. Simply authenticate with any of these and view | ||||||
|             the resulting page. It should contain a success message similar to the following: |             the resulting page. It should contain a success message similar to the following: | ||||||
|  | @ -71,8 +71,8 @@ Success! Your web filters appear to be properly configured! | ||||||
|         <para>Once you successfully receive the above message, return to the sample application's |         <para>Once you successfully receive the above message, return to the sample application's | ||||||
|             home page and click "Manage". You can then try out the application. Notice that only the |             home page and click "Manage". You can then try out the application. Notice that only the | ||||||
|             contacts available to the currently logged on user are displayed, and only users with |             contacts available to the currently logged on user are displayed, and only users with | ||||||
|                 <literal>ROLE_SUPERVISOR</literal> are granted access to delete their contacts. |             <literal>ROLE_SUPERVISOR</literal> are granted access to delete their contacts. Behind | ||||||
|             Behind the scenes, the <classname>MethodSecurityInterceptor</classname> is securing the |             the scenes, the <classname>MethodSecurityInterceptor</classname> is securing the | ||||||
|             business objects. </para> |             business objects. </para> | ||||||
|         <para>The application allows you to modify the access control lists associated with |         <para>The application allows you to modify the access control lists associated with | ||||||
|             different contacts. Be sure to give this a try and understand how it works by reviewing |             different contacts. Be sure to give this a try and understand how it works by reviewing | ||||||
|  | @ -103,12 +103,12 @@ Success! Your web filters appear to be properly configured! | ||||||
|         <title>CAS Sample</title> |         <title>CAS Sample</title> | ||||||
|         <para> The CAS sample requires that you run both a CAS server and CAS client. It isn't |         <para> The CAS sample requires that you run both a CAS server and CAS client. It isn't | ||||||
|             included in the distribution so you should check out the project code as described in |             included in the distribution so you should check out the project code as described in | ||||||
|                 <link xlink:href="get-source">the introduction</link>. You'll find the relevant |             <link xlink:href="get-source">the introduction</link>. You'll find the relevant files | ||||||
|             files under the <filename>sample/cas</filename> directory. There's also a |             under the <filename>sample/cas</filename> directory. There's also a | ||||||
|                 <filename>Readme.txt</filename> file in there which explains how to run both the |             <filename>Readme.txt</filename> file in there which explains how to run both the server | ||||||
|             server and the client directly from the source tree, complete with SSL support. You have |             and the client directly from the source tree, complete with SSL support. You have to | ||||||
|             to download the CAS Server web application (a war file) from the CAS site and drop it |             download the CAS Server web application (a war file) from the CAS site and drop it into | ||||||
|             into the <filename>samples/cas/server</filename> directory. </para> |             the <filename>samples/cas/server</filename> directory. </para> | ||||||
|     </section> |     </section> | ||||||
|     <section xml:id="preauth-sample"> |     <section xml:id="preauth-sample"> | ||||||
|         <title>Pre-Authentication Sample</title> |         <title>Pre-Authentication Sample</title> | ||||||
|  |  | ||||||
|  | @ -7,26 +7,28 @@ | ||||||
|         <info> |         <info> | ||||||
|             <title>AOP Alliance (MethodInvocation) Security Interceptor</title> |             <title>AOP Alliance (MethodInvocation) Security Interceptor</title> | ||||||
|         </info> |         </info> | ||||||
|     <para> Prior to Spring Security 2.0, securing <classname>MethodInvocation</classname>s needed |         <para> Prior to Spring Security 2.0, securing <classname>MethodInvocation</classname>s | ||||||
|       quite a lot of boiler plate configuration. Now the recommended approach for method security is |             needed quite a lot of boiler plate configuration. Now the recommended approach for | ||||||
|       to use <link xlink:href="#ns-method-security">namespace configuration</link>. This way the |             method security is to use <link xlink:href="#ns-method-security">namespace | ||||||
|       method security infrastructure beans are configured automatically for you so you don't really |             configuration</link>. This way the method security infrastructure beans are configured | ||||||
|       need to know about the implementation classes. We'll just provide a quick overview of the |             automatically for you so you don't really need to know about the implementation classes. | ||||||
|       classes that are involved here. </para> |             We'll just provide a quick overview of the classes that are involved here. </para> | ||||||
|         <para> Method security in enforced using a <classname>MethodSecurityInterceptor</classname>, |         <para> Method security in enforced using a <classname>MethodSecurityInterceptor</classname>, | ||||||
|             which secures <classname>MethodInvocation</classname>s. Depending on the configuration |             which secures <classname>MethodInvocation</classname>s. Depending on the configuration | ||||||
|       approach, an interceptor may be specific to a single bean or shared between multiple beans. |             approach, an interceptor may be specific to a single bean or shared between multiple | ||||||
|       The interceptor uses a <interfacename>MethodSecurityMetadataSource</interfacename> instance to |             beans. The interceptor uses a | ||||||
|       obtain the configuration attributes that apply to a particular method invocation. |             <interfacename>MethodSecurityMetadataSource</interfacename> instance to obtain the | ||||||
|         <classname>MapBasedMethodSecurityMetadataSource</classname> is used to store configuration |             configuration attributes that apply to a particular method invocation. | ||||||
|       attributes keyed by method names (which can be wildcarded) and will be used internally when |             <classname>MapBasedMethodSecurityMetadataSource</classname> is used to store | ||||||
|       the attributes are defined in the application context using the |             configuration attributes keyed by method names (which can be wildcarded) and will be | ||||||
|  |             used internally when the attributes are defined in the application context using the | ||||||
|             <literal><intercept-methods></literal> or <literal><protect-point></literal> |             <literal><intercept-methods></literal> or <literal><protect-point></literal> | ||||||
|             elements. Other implementations will be used to handle annotation-based configuration. </para> |             elements. Other implementations will be used to handle annotation-based configuration. </para> | ||||||
|         <section> |         <section> | ||||||
|             <title>Explicit MethodSecurityInterceptor Configuration</title> |             <title>Explicit MethodSecurityInterceptor Configuration</title> | ||||||
|       <para> You can of course configure a <classname>MethodSecurityIterceptor</classname> directly |             <para> You can of course configure a <classname>MethodSecurityIterceptor</classname> | ||||||
|         in your application context for use with one of Spring AOP's proxying mechanisms: <programlisting><![CDATA[ |                 directly in your application context for use with one of Spring AOP's proxying | ||||||
|  |                 mechanisms: <programlisting><![CDATA[ | ||||||
| <bean id="bankManagerSecurity" class= | <bean id="bankManagerSecurity" class= | ||||||
|     "org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor"> |     "org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor"> | ||||||
|   <property name="authenticationManager" ref="authenticationManager"/> |   <property name="authenticationManager" ref="authenticationManager"/> | ||||||
|  | @ -46,19 +48,20 @@ | ||||||
|         <info> |         <info> | ||||||
|             <title>AspectJ (JoinPoint) Security Interceptor</title> |             <title>AspectJ (JoinPoint) Security Interceptor</title> | ||||||
|         </info> |         </info> | ||||||
|     <para>The AspectJ security interceptor is very similar to the AOP Alliance security interceptor |         <para>The AspectJ security interceptor is very similar to the AOP Alliance security | ||||||
|       discussed in the previous section. Indeed we will only discuss the differences in this |             interceptor discussed in the previous section. Indeed we will only discuss the | ||||||
|       section.</para> |             differences in this section.</para> | ||||||
|     <para>The AspectJ interceptor is named <literal>AspectJSecurityInterceptor</literal>. Unlike the |         <para>The AspectJ interceptor is named <literal>AspectJSecurityInterceptor</literal>. Unlike | ||||||
|       AOP Alliance security interceptor, which relies on the Spring application context to weave in |             the AOP Alliance security interceptor, which relies on the Spring application context to | ||||||
|       the security interceptor via proxying, the <literal>AspectJSecurityInterceptor</literal> is |             weave in the security interceptor via proxying, the | ||||||
|       weaved in via the AspectJ compiler. It would not be uncommon to use both types of security |             <literal>AspectJSecurityInterceptor</literal> is weaved in via the AspectJ compiler. It | ||||||
|       interceptors in the same application, with <literal>AspectJSecurityInterceptor</literal> being |             would not be uncommon to use both types of security interceptors in the same | ||||||
|       used for domain object instance security and the AOP Alliance |             application, with <literal>AspectJSecurityInterceptor</literal> being used for domain | ||||||
|  |             object instance security and the AOP Alliance | ||||||
|             <classname>MethodSecurityInterceptor</classname> being used for services layer |             <classname>MethodSecurityInterceptor</classname> being used for services layer | ||||||
|             security.</para> |             security.</para> | ||||||
|     <para>Let's first consider how the <literal>AspectJSecurityInterceptor</literal> is configured |         <para>Let's first consider how the <literal>AspectJSecurityInterceptor</literal> is | ||||||
|       in the Spring application context:</para> |             configured in the Spring application context:</para> | ||||||
|         <programlisting><![CDATA[ |         <programlisting><![CDATA[ | ||||||
| <bean id="bankManagerSecurity" class= | <bean id="bankManagerSecurity" class= | ||||||
|     "org.springframework.security.access.intercept.aspectj.AspectJSecurityInterceptor"> |     "org.springframework.security.access.intercept.aspectj.AspectJSecurityInterceptor"> | ||||||
|  | @ -77,11 +80,11 @@ | ||||||
|             security interceptor. Indeed the two interceptors can share the same |             security interceptor. Indeed the two interceptors can share the same | ||||||
|             <literal>securityMetadataSource</literal>, as the |             <literal>securityMetadataSource</literal>, as the | ||||||
|             <interfacename>SecurityMetadataSource</interfacename> works with |             <interfacename>SecurityMetadataSource</interfacename> works with | ||||||
|         <literal>java.lang.reflect.Method</literal>s rather than an AOP library-specific class. Of |             <literal>java.lang.reflect.Method</literal>s rather than an AOP library-specific class. | ||||||
|       course, your access decisions have access to the relevant AOP library-specific invocation (ie |             Of course, your access decisions have access to the relevant AOP library-specific | ||||||
|         <classname>MethodInvocation</classname> or <literal>JoinPoint</literal>) and as such can |             invocation (ie <classname>MethodInvocation</classname> or <literal>JoinPoint</literal>) | ||||||
|       consider a range of addition criteria when making access decisions (such as method |             and as such can consider a range of addition criteria when making access decisions (such | ||||||
|       arguments).</para> |             as method arguments).</para> | ||||||
|         <para>Next you'll need to define an AspectJ <literal>aspect</literal>. For example:</para> |         <para>Next you'll need to define an AspectJ <literal>aspect</literal>. For example:</para> | ||||||
|         <programlisting language="java"> |         <programlisting language="java"> | ||||||
| package org.springframework.security.samples.aspectj; | package org.springframework.security.samples.aspectj; | ||||||
|  | @ -127,12 +130,13 @@ public aspect DomainObjectInstanceSecurityAspect implements InitializingBean { | ||||||
| } | } | ||||||
| </programlisting> | </programlisting> | ||||||
|         <para>In the above example, the security interceptor will be applied to every instance of |         <para>In the above example, the security interceptor will be applied to every instance of | ||||||
|         <literal>PersistableEntity</literal>, which is an abstract class not shown (you can use any |             <literal>PersistableEntity</literal>, which is an abstract class not shown (you can use | ||||||
|       other class or <literal>pointcut</literal> expression you like). For those curious, |             any other class or <literal>pointcut</literal> expression you like). For those curious, | ||||||
|             <literal>AspectJCallback</literal> is needed because the <literal>proceed();</literal> |             <literal>AspectJCallback</literal> is needed because the <literal>proceed();</literal> | ||||||
|             statement has special meaning only within an <literal>around()</literal> body. The |             statement has special meaning only within an <literal>around()</literal> body. The | ||||||
|             <literal>AspectJSecurityInterceptor</literal> calls this anonymous |             <literal>AspectJSecurityInterceptor</literal> calls this anonymous | ||||||
|         <literal>AspectJCallback</literal> class when it wants the target object to continue.</para> |             <literal>AspectJCallback</literal> class when it wants the target object to | ||||||
|  |             continue.</para> | ||||||
|         <para>You will need to configure Spring to load the aspect and wire it with the |         <para>You will need to configure Spring to load the aspect and wire it with the | ||||||
|             <literal>AspectJSecurityInterceptor</literal>. A bean declaration which achieves this is |             <literal>AspectJSecurityInterceptor</literal>. A bean declaration which achieves this is | ||||||
|             shown below:</para> |             shown below:</para> | ||||||
|  | @ -144,7 +148,7 @@ public aspect DomainObjectInstanceSecurityAspect implements InitializingBean { | ||||||
| </bean>]]> | </bean>]]> | ||||||
|     </programlisting> |     </programlisting> | ||||||
|         <para>That's it! Now you can create your beans from anywhere within your application, using |         <para>That's it! Now you can create your beans from anywhere within your application, using | ||||||
|       whatever means you think fit (eg <literal>new Person();</literal>) and they will have the |             whatever means you think fit (eg <literal>new Person();</literal>) and they will have | ||||||
|       security interceptor applied.</para> |             the security interceptor applied.</para> | ||||||
|     </section> |     </section> | ||||||
| </chapter> | </chapter> | ||||||
|  |  | ||||||
|  | @ -4,29 +4,29 @@ | ||||||
|         <title>The Security Filter Chain</title> |         <title>The Security Filter Chain</title> | ||||||
|     </info> |     </info> | ||||||
|     <para>Spring Security's web infrastructure is based entirely on standard servlet filters. It |     <para>Spring Security's web infrastructure is based entirely on standard servlet filters. It | ||||||
|     doesn't use servlets or any other servlet-based frameworks (such as Spring MVC) internally, so |         doesn't use servlets or any other servlet-based frameworks (such as Spring MVC) internally, | ||||||
|     it has no strong links to any particular web technology. It deals in |         so it has no strong links to any particular web technology. It deals in | ||||||
|       <classname>HttpServletRequest</classname>s and <classname>HttpServletResponse</classname>s and |         <classname>HttpServletRequest</classname>s and <classname>HttpServletResponse</classname>s | ||||||
|     doesn't care whether the requests come from a browser, a web service client, an |         and doesn't care whether the requests come from a browser, a web service client, an | ||||||
|         <classname>HttpInvoker</classname> or an AJAX application. </para> |         <classname>HttpInvoker</classname> or an AJAX application. </para> | ||||||
|     <para> Spring Security maintains a filter chain internally where each of the filters has a |     <para> Spring Security maintains a filter chain internally where each of the filters has a | ||||||
|     particular responsibility and filters are added or removed from the configuration depending on |         particular responsibility and filters are added or removed from the configuration depending | ||||||
|     which services are required. The ordering of the filters is important as there are dependencies |         on which services are required. The ordering of the filters is important as there are | ||||||
|     between them. If you have been using <link xlink:href="#ns-config">namespace |         dependencies between them. If you have been using <link xlink:href="#ns-config">namespace | ||||||
|       configuration</link>, then the filters are automatically configured for you and you don't have |         configuration</link>, then the filters are automatically configured for you and you don't | ||||||
|     to define any Spring beans explicitly but here may be times when you want full control over the |         have to define any Spring beans explicitly but here may be times when you want full control | ||||||
|     security filter chain, either because you are using features which aren't supported in the |         over the security filter chain, either because you are using features which aren't supported | ||||||
|     namespace, or you are using your own customized versions of classes.</para> |         in the namespace, or you are using your own customized versions of classes.</para> | ||||||
|     <section xml:id="delegating-filter-proxy"> |     <section xml:id="delegating-filter-proxy"> | ||||||
|         <title><classname>DelegatingFilterProxy</classname></title> |         <title><classname>DelegatingFilterProxy</classname></title> | ||||||
|         <para> When using servlet filters, you obviously need to declare them in your |         <para> When using servlet filters, you obviously need to declare them in your | ||||||
|         <filename>web.xml</filename>, or they will be ignored by the servlet container. In Spring |             <filename>web.xml</filename>, or they will be ignored by the servlet container. In | ||||||
|       Security, the filter classes are also Spring beans defined in the application context and thus |             Spring Security, the filter classes are also Spring beans defined in the application | ||||||
|       able to take advantage of Spring's rich dependency-injection facilities and lifecycle |             context and thus able to take advantage of Spring's rich dependency-injection facilities | ||||||
|       interfaces. Spring's <classname>DelegatingFilterProxy</classname> provides the link between |             and lifecycle interfaces. Spring's <classname>DelegatingFilterProxy</classname> provides | ||||||
|         <filename>web.xml</filename> and the application context. </para> |             the link between <filename>web.xml</filename> and the application context. </para> | ||||||
|     <para>When using <classname>DelegatingFilterProxy</classname>, you will see something like this |         <para>When using <classname>DelegatingFilterProxy</classname>, you will see something like | ||||||
|       in the <filename>web.xml</filename> file: <programlisting><![CDATA[ |             this in the <filename>web.xml</filename> file: <programlisting><![CDATA[ | ||||||
|   <filter> |   <filter> | ||||||
|     <filter-name>myFilter</filter-name> |     <filter-name>myFilter</filter-name> | ||||||
|     <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> |     <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> | ||||||
|  | @ -37,29 +37,29 @@ | ||||||
|     <url-pattern>/*</url-pattern> |     <url-pattern>/*</url-pattern> | ||||||
|   </filter-mapping>]]> |   </filter-mapping>]]> | ||||||
|       </programlisting> Notice that the filter is actually a |       </programlisting> Notice that the filter is actually a | ||||||
|         <literal>DelegatingFilterProxy</literal>, and not the class that will actually implement the |             <literal>DelegatingFilterProxy</literal>, and not the class that will actually implement | ||||||
|       logic of the filter. What <classname>DelegatingFilterProxy</classname> does is delegate the |             the logic of the filter. What <classname>DelegatingFilterProxy</classname> does is | ||||||
|         <interfacename>Filter</interfacename>'s methods through to a bean which is obtained from the |             delegate the <interfacename>Filter</interfacename>'s methods through to a bean which is | ||||||
|       Spring application context. This enables the bean to benefit from the Spring web application |             obtained from the Spring application context. This enables the bean to benefit from the | ||||||
|       context lifecycle support and configuration flexibility. The bean must implement |             Spring web application context lifecycle support and configuration flexibility. The bean | ||||||
|         <interfacename>javax.servlet.Filter</interfacename> and it must have the same name as that |             must implement <interfacename>javax.servlet.Filter</interfacename> and it must have the | ||||||
|       in the <literal>filter-name</literal> element. Read the Javadoc for |             same name as that in the <literal>filter-name</literal> element. Read the Javadoc for | ||||||
|             <classname>DelegatingFilterProxy</classname> for more information</para> |             <classname>DelegatingFilterProxy</classname> for more information</para> | ||||||
|     </section> |     </section> | ||||||
|     <section xml:id="filter-chain-proxy"> |     <section xml:id="filter-chain-proxy"> | ||||||
|         <title><classname>FilterChainProxy</classname></title> |         <title><classname>FilterChainProxy</classname></title> | ||||||
|         <para> It should now be clear that you can declare each Spring Security filter bean that you |         <para> It should now be clear that you can declare each Spring Security filter bean that you | ||||||
|             require in your application context file and add a corresponding |             require in your application context file and add a corresponding | ||||||
|         <classname>DelegatingFilterProxy</classname> entry to <filename>web.xml</filename> for each |             <classname>DelegatingFilterProxy</classname> entry to <filename>web.xml</filename> for | ||||||
|       filter, making sure that they are ordered correctly. This is a cumbersome approach and |             each filter, making sure that they are ordered correctly. This is a cumbersome approach | ||||||
|       clutters up the <filename>web.xml</filename> file quickly if we have a lot of filters. We |             and clutters up the <filename>web.xml</filename> file quickly if we have a lot of | ||||||
|       would prefer to just add a single entry to <filename>web.xml</filename> and deal entirely with |             filters. We would prefer to just add a single entry to <filename>web.xml</filename> and | ||||||
|       the application context file for managing our web security beans. This is where Spring |             deal entirely with the application context file for managing our web security beans. | ||||||
|       Secuiryt's <classname>FilterChainProxy</classname> comes in. It is wired using a |             This is where Spring Secuirity's <classname>FilterChainProxy</classname> comes in. It is | ||||||
|         <literal>DelegatingFilterProxy</literal>, just like in the example above, but with the |             wired using a <literal>DelegatingFilterProxy</literal>, just like in the example above, | ||||||
|         <literal>filter-name</literal> set to the bean name <quote>filterChainProxy</quote>. The |             but with the <literal>filter-name</literal> set to the bean name | ||||||
|       filter chain is then declared in the application context with the same bean name. Here's an |             <quote>filterChainProxy</quote>. The filter chain is then declared in the application | ||||||
|       example: <programlisting language="xml"><![CDATA[ |             context with the same bean name. Here's an example: <programlisting language="xml"><![CDATA[ | ||||||
| <bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy"> | <bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy"> | ||||||
|   <sec:filter-chain-map path-type="ant"> |   <sec:filter-chain-map path-type="ant"> | ||||||
|      <sec:filter-chain pattern="/webServices/**" filters=" |      <sec:filter-chain pattern="/webServices/**" filters=" | ||||||
|  | @ -75,104 +75,114 @@ | ||||||
|   </sec:filter-chain-map> |   </sec:filter-chain-map> | ||||||
| </bean> | </bean> | ||||||
| ]]> | ]]> | ||||||
|     </programlisting> The namespace element <literal>filter-chain-map</literal> is used |     </programlisting> The namespace element <literal>filter-chain-map</literal> is used to set | ||||||
|       to set up the security filter chain(s) which are required within the |             up the security filter chain(s) which are required within the application<footnote> | ||||||
|           application<footnote><para>Note that you'll need to include the security namespace in your |             <para>Note that you'll need to include the security namespace in your application | ||||||
|           application context XML file in order to use this syntax.</para></footnote>. It maps a |                 context XML file in order to use this syntax.</para> | ||||||
|       particular URL pattern to a chain of filters built up from the bean names specified in the |             </footnote>. It maps a particular URL pattern to a chain of filters built up from the | ||||||
|         <literal>filters</literal> element. Both regular expressions and Ant Paths are supported, |             bean names specified in the <literal>filters</literal> element. Both regular expressions | ||||||
|       and the most specific URIs appear first. At runtime the |             and Ant Paths are supported, and the most specific URIs appear first. At runtime the | ||||||
|         <classname>FilterChainProxy</classname> will locate the first URI pattern that matches the |             <classname>FilterChainProxy</classname> will locate the first URI pattern that matches | ||||||
|       current web request and the list of filter beans specified by the <literal>filters</literal> |             the current web request and the list of filter beans specified by the | ||||||
|       attribute will be applied to that request. The filters will be invoked in the order they are |             <literal>filters</literal> attribute will be applied to that request. The filters will | ||||||
|       defined, so you have complete control over the filter chain which is applied to a particular |             be invoked in the order they are defined, so you have complete control over the filter | ||||||
|       URL.</para> |             chain which is applied to a particular URL.</para> | ||||||
|         <para>You may have noticed we have declared two |         <para>You may have noticed we have declared two | ||||||
|             <classname>SecurityContextPersistenceFilter</classname>s in the filter chain |             <classname>SecurityContextPersistenceFilter</classname>s in the filter chain | ||||||
|         (<literal>ASC</literal> is short for <literal>allowSessionCreation</literal>, a property of |             (<literal>ASC</literal> is short for <literal>allowSessionCreation</literal>, a property | ||||||
|         <classname>SecurityContextPersistenceFilter</classname>). As web services will never present |             of <classname>SecurityContextPersistenceFilter</classname>). As web services will never | ||||||
|       a <literal>jsessionid</literal> on future requests, creating <literal>HttpSession</literal>s |             present a <literal>jsessionid</literal> on future requests, creating | ||||||
|       for such user agents would be wasteful. If you had a high-volume application which required |             <literal>HttpSession</literal>s for such user agents would be wasteful. If you had a | ||||||
|       maximum scalability, we recommend you use the approach shown above. For smaller applications, |             high-volume application which required maximum scalability, we recommend you use the | ||||||
|       using a single <classname>SecurityContextPersistenceFilter</classname> (with its default |             approach shown above. For smaller applications, using a single | ||||||
|  |             <classname>SecurityContextPersistenceFilter</classname> (with its default | ||||||
|             <literal>allowSessionCreation</literal> as <literal>true</literal>) would likely be |             <literal>allowSessionCreation</literal> as <literal>true</literal>) would likely be | ||||||
|             sufficient.</para> |             sufficient.</para> | ||||||
|     <para>In relation to lifecycle issues, the <classname>FilterChainProxy</classname> will always |  | ||||||
|       delegate <methodname>init(FilterConfig)</methodname> and <methodname>destroy()</methodname> |  | ||||||
|       methods through to the underlaying <interfacename>Filter</interfacename>s if such methods are |  | ||||||
|       called against <classname>FilterChainProxy</classname> itself. In this case, |  | ||||||
|         <classname>FilterChainProxy</classname> guarantees to only initialize and destroy each |  | ||||||
|         <literal>Filter</literal> bean once, no matter how many times it is declared in the filter |  | ||||||
|       chain(s). You control the overall choice as to whether these methods are called or not via the |  | ||||||
|         <literal>targetFilterLifecycle</literal> initialization parameter of |  | ||||||
|         <literal>DelegatingFilterProxy</literal>. By default this property is |  | ||||||
|         <literal>false</literal> and servlet container lifecycle invocations are not delegated |  | ||||||
|       through <literal>DelegatingFilterProxy</literal>.</para> |  | ||||||
|         <para> When we looked at how to set up web security using <link xlink:href="#ns-web-xml" |         <para> When we looked at how to set up web security using <link xlink:href="#ns-web-xml" | ||||||
|         >namespace configuration</link>, we used a <literal>DelegatingFilterProxy</literal> with the |             >namespace configuration</link>, we used a <literal>DelegatingFilterProxy</literal> with | ||||||
|       name <quote>springSecurityFilterChain</quote>. You should now be able to see that this is the |             the name <quote>springSecurityFilterChain</quote>. You should now be able to see that | ||||||
|       name of the <classname>FilterChainProxy</classname> which is created by the namespace. </para> |             this is the name of the <classname>FilterChainProxy</classname> which is created by the | ||||||
|  |             namespace. </para> | ||||||
|         <section> |         <section> | ||||||
|             <title>Bypassing the Filter Chain</title> |             <title>Bypassing the Filter Chain</title> | ||||||
|       <para> As with the namespace, you can use the attribute <literal>filters = "none"</literal> as |             <para> As with the namespace, you can use the attribute <literal>filters = | ||||||
|         an alternative to supplying a filter bean list. This will omit the request pattern from the |                 "none"</literal> as an alternative to supplying a filter bean list. This will omit | ||||||
|         security filter chain entirely. Note that anything matching this path will then have no |                 the request pattern from the security filter chain entirely. Note that anything | ||||||
|         authentication or authorization services applied and will be freely accessible. If you want |                 matching this path will then have no authentication or authorization services | ||||||
|         to make use of the contents of the <classname>SecurityContext</classname> contents during a |                 applied and will be freely accessible. If you want to make use of the contents of | ||||||
|         request, then it must have passed through the security filter chain. Otherwise the |                 the <classname>SecurityContext</classname> contents during a request, then it must | ||||||
|           <classname>SecurityContextHolder</classname> will not have been populated and the contents |                 have passed through the security filter chain. Otherwise the | ||||||
|         will be null.</para> |                 <classname>SecurityContextHolder</classname> will not have been populated and the | ||||||
|  |                 contents will be null.</para> | ||||||
|         </section> |         </section> | ||||||
|     </section> |     </section> | ||||||
|     <section> |     <section> | ||||||
|         <title>Filter Ordering</title> |         <title>Filter Ordering</title> | ||||||
|     <para>The order that filters are defined in the chain is very important. Irrespective of which |         <para>The order that filters are defined in the chain is very important. Irrespective of | ||||||
|       filters you are actually using, the order should be as follows: |             which filters you are actually using, the order should be as follows: <orderedlist> | ||||||
|               <orderedlist><listitem><para><classname>ChannelProcessingFilter</classname>, because |             <listitem> | ||||||
|             it might need to redirect to a different |                 <para><classname>ChannelProcessingFilter</classname>, because it might need to | ||||||
|               protocol</para></listitem><listitem><para><classname>ConcurrentSessionFilter</classname>, |                     redirect to a different protocol</para> | ||||||
|             because it doesn't use any <classname>SecurityContextHolder</classname> functionality |             </listitem> | ||||||
|             but needs to update the <interfacename>SessionRegistry</interfacename> to reflect |             <listitem> | ||||||
|             ongoing requests from the |                 <para><classname>ConcurrentSessionFilter</classname>, because it doesn't use any | ||||||
|               principal</para></listitem><listitem><para><classname>SecurityContextPersistenceFilter</classname>, |                     <classname>SecurityContextHolder</classname> functionality but needs to update | ||||||
|             so a <interfacename>SecurityContext</interfacename> can be set up in the |                     the <interfacename>SessionRegistry</interfacename> to reflect ongoing requests | ||||||
|               <classname>SecurityContextHolder</classname> at the beginning of a web request, and |                     from the principal</para> | ||||||
|             any changes to the <interfacename>SecurityContext</interfacename> can be copied to the |             </listitem> | ||||||
|               <literal>HttpSession</literal> when the web request ends (ready for use with the next |             <listitem> | ||||||
|             web request)</para></listitem><listitem><para>Authentication processing mechanisms - |                 <para><classname>SecurityContextPersistenceFilter</classname>, so a | ||||||
|  |                     <interfacename>SecurityContext</interfacename> can be set up in the | ||||||
|  |                     <classname>SecurityContextHolder</classname> at the beginning of a web request, | ||||||
|  |                     and any changes to the <interfacename>SecurityContext</interfacename> can be | ||||||
|  |                     copied to the <literal>HttpSession</literal> when the web request ends (ready | ||||||
|  |                     for use with the next web request)</para> | ||||||
|  |             </listitem> | ||||||
|  |             <listitem> | ||||||
|  |                 <para>Authentication processing mechanisms - | ||||||
|                     <classname>UsernamePasswordAuthenticationFilter</classname>, |                     <classname>UsernamePasswordAuthenticationFilter</classname>, | ||||||
|                     <classname>CasAuthenticationFilter</classname>, |                     <classname>CasAuthenticationFilter</classname>, | ||||||
|                     <classname>BasicAuthenticationFilter</classname> etc - so that the |                     <classname>BasicAuthenticationFilter</classname> etc - so that the | ||||||
|                     <classname>SecurityContextHolder</classname> can be modified to contain a valid |                     <classname>SecurityContextHolder</classname> can be modified to contain a valid | ||||||
|               <interfacename>Authentication</interfacename> request |                     <interfacename>Authentication</interfacename> request token</para> | ||||||
|             token</para></listitem><listitem><para>The |             </listitem> | ||||||
|               <literal>SecurityContextHolderAwareRequestFilter</literal>, if you are using it to |             <listitem> | ||||||
|             install a Spring Security aware <literal>HttpServletRequestWrapper</literal> into your |                 <para>The <literal>SecurityContextHolderAwareRequestFilter</literal>, if you are | ||||||
|             servlet |                     using it to install a Spring Security aware | ||||||
|               container</para></listitem><listitem><para><classname>RememberMeAuthenticationFilter</classname>, |                     <literal>HttpServletRequestWrapper</literal> into your servlet container</para> | ||||||
|             so that if no earlier authentication processing mechanism updated the |             </listitem> | ||||||
|               <classname>SecurityContextHolder</classname>, and the request presents a cookie that |             <listitem> | ||||||
|             enables remember-me services to take place, a suitable remembered |                 <para><classname>RememberMeAuthenticationFilter</classname>, so that if no earlier | ||||||
|               <interfacename>Authentication</interfacename> object will be put |                     authentication processing mechanism updated the | ||||||
|           there</para></listitem><listitem><para><classname>AnonymousAuthenticationFilter</classname>, |                     <classname>SecurityContextHolder</classname>, and the request presents a cookie | ||||||
|             so that if no earlier authentication processing mechanism updated the |                     that enables remember-me services to take place, a suitable remembered | ||||||
|  |                     <interfacename>Authentication</interfacename> object will be put there</para> | ||||||
|  |             </listitem> | ||||||
|  |             <listitem> | ||||||
|  |                 <para><classname>AnonymousAuthenticationFilter</classname>, so that if no earlier | ||||||
|  |                     authentication processing mechanism updated the | ||||||
|                     <classname>SecurityContextHolder</classname>, an anonymous |                     <classname>SecurityContextHolder</classname>, an anonymous | ||||||
|               <interfacename>Authentication</interfacename> object will be put |                     <interfacename>Authentication</interfacename> object will be put there</para> | ||||||
|           there</para></listitem><listitem><para><classname>ExceptionTranslationFilter</classname>, |             </listitem> | ||||||
|             to catch any Spring Security exceptions so that either an HTTP error response can be |             <listitem> | ||||||
|             returned or an appropriate <interfacename>AuthenticationEntryPoint</interfacename> can |                 <para><classname>ExceptionTranslationFilter</classname>, to catch any Spring | ||||||
|             be |                     Security exceptions so that either an HTTP error response can be returned or an | ||||||
|               launched</para></listitem><listitem><para><classname>FilterSecurityInterceptor</classname>, |                     appropriate <interfacename>AuthenticationEntryPoint</interfacename> can be | ||||||
|             to protect web URIs and raise exceptions when access is |                     launched</para> | ||||||
|         denied</para></listitem></orderedlist></para> |             </listitem> | ||||||
|  |             <listitem> | ||||||
|  |                 <para><classname>FilterSecurityInterceptor</classname>, to protect web URIs and | ||||||
|  |                     raise exceptions when access is denied</para> | ||||||
|  |             </listitem> | ||||||
|  |             </orderedlist></para> | ||||||
|     </section> |     </section> | ||||||
|     <section> |     <section> | ||||||
|         <title>Use with other Filter-Based Frameworks</title> |         <title>Use with other Filter-Based Frameworks</title> | ||||||
|     <para>If you're using some other framework that is also filter-based, then you need to make sure |         <para>If you're using some other framework that is also filter-based, then you need to make | ||||||
|       that the Spring Security filters come first. This enables the |             sure that the Spring Security filters come first. This enables the | ||||||
|         <classname>SecurityContextHolder</classname> to be populated in time for use by the other |             <classname>SecurityContextHolder</classname> to be populated in time for use by the | ||||||
|       filters. Examples are the use of SiteMesh to decorate your web pages or a web framework like |             other filters. Examples are the use of SiteMesh to decorate your web pages or a web | ||||||
|       Wicket which uses a filter to handle its requests. </para> |             framework like Wicket which uses a filter to handle its requests. </para> | ||||||
|     </section> |     </section> | ||||||
|     <!-- |     <!-- | ||||||
|   <section xml:id="taglib"> |   <section xml:id="taglib"> | ||||||
|  |  | ||||||
|  | @ -6,38 +6,41 @@ | ||||||
|     <para>HTTP session related functonality is handled by a combination of the |     <para>HTTP session related functonality is handled by a combination of the | ||||||
|         <classname>SessionManagementFilter</classname> and the |         <classname>SessionManagementFilter</classname> and the | ||||||
|         <interfacename>SessionAuthenticationStrategy</interfacename> interface, which the filter |         <interfacename>SessionAuthenticationStrategy</interfacename> interface, which the filter | ||||||
|     delegates to. Typical usage includes session-fixation protection attack prevention, detection of |         delegates to. Typical usage includes session-fixation protection attack prevention, | ||||||
|     session timeouts and restrictions on how many sessions an authenticated user may have open |         detection of session timeouts and restrictions on how many sessions an authenticated user | ||||||
|     concurrently.</para> |         may have open concurrently.</para> | ||||||
|     <section> |     <section> | ||||||
|         <title>SessionManagementFilter</title> |         <title>SessionManagementFilter</title> | ||||||
|         <para>The <classname>SessionManagementFilter</classname> checks the contents of the |         <para>The <classname>SessionManagementFilter</classname> checks the contents of the | ||||||
|         <interfacename>SecurityContextRepository</interfacename> against the current contents of the |             <interfacename>SecurityContextRepository</interfacename> against the current contents of | ||||||
|         <classname>SecurityContextHolder</classname> to determine whether a user has been |             the <classname>SecurityContextHolder</classname> to determine whether a user has been | ||||||
|             authenticated during the current request, typically by a non-interactive authentication |             authenticated during the current request, typically by a non-interactive authentication | ||||||
|       mechanism, such as pre-authentication or remember-me <footnote><para>Authentication by |             mechanism, such as pre-authentication or remember-me <footnote> | ||||||
|           mechanisms which perform a redirect after authenticating (such as form-login) will not be |             <para>Authentication by mechanisms which perform a redirect after authenticating (such | ||||||
|           detected by <classname>SessionManagementFilter</classname>, as the filter will not be |                 as form-login) will not be detected by | ||||||
|           invoked during the authenticating request. Session-management functionality has to be |                 <classname>SessionManagementFilter</classname>, as the filter will not be invoked | ||||||
|           handled separately in these cases. </para></footnote>. If the repository contains a |                 during the authenticating request. Session-management functionality has to be | ||||||
|       security context, the filter does nothing. If it doesn't, and the thread-local |                 handled separately in these cases. </para> | ||||||
|         <interfacename>SecurityContext</interfacename> contains a (non-anonymous) |             </footnote>. If the repository contains a security context, the filter does nothing. If | ||||||
|         <interfacename>Authentication</interfacename> object, the filter assumes they have been |             it doesn't, and the thread-local <interfacename>SecurityContext</interfacename> contains | ||||||
|       authenticated by a previous filter in the stack. It will then invoke the configured |             a (non-anonymous) <interfacename>Authentication</interfacename> object, the filter | ||||||
|  |             assumes they have been authenticated by a previous filter in the stack. It will then | ||||||
|  |             invoke the configured | ||||||
|             <interfacename>SessionAuthenticationStrategy</interfacename>.</para> |             <interfacename>SessionAuthenticationStrategy</interfacename>.</para> | ||||||
|         <para>If the user is not currently authenticated, the filter will check whether an invalid |         <para>If the user is not currently authenticated, the filter will check whether an invalid | ||||||
|       session ID has been requested (because of a timeout, for example) and will redirect to the |             session ID has been requested (because of a timeout, for example) and will redirect to | ||||||
|       configured <literal>invalidSessionUrl</literal> if set. The easiest way to configure this is |             the configured <literal>invalidSessionUrl</literal> if set. The easiest way to configure | ||||||
|       through the namespace, <link xlink:href="#ns-session-mgmt">as described earlier</link>.</para> |             this is through the namespace, <link xlink:href="#ns-session-mgmt">as described | ||||||
|  |             earlier</link>.</para> | ||||||
|     </section> |     </section> | ||||||
|     <section> |     <section> | ||||||
|         <title><interfacename>SessionAuthenticationStrategy</interfacename></title> |         <title><interfacename>SessionAuthenticationStrategy</interfacename></title> | ||||||
|     <para> |         <para> <interfacename>SessionAuthenticationStrategy</interfacename> is used by both | ||||||
|       <interfacename>SessionAuthenticationStrategy</interfacename> is used by both |  | ||||||
|             <classname>SessionManagementFilter</classname> and |             <classname>SessionManagementFilter</classname> and | ||||||
|             <classname>AbstractAuthenticationProcessingFilter</classname>, so if you are using a |             <classname>AbstractAuthenticationProcessingFilter</classname>, so if you are using a | ||||||
|       customized form-login class, for example, you will need to inject it into both of these. In |             customized form-login class, for example, you will need to inject it into both of these. | ||||||
|       this case, a typical configuration, combining the namespace and custom beans might look like this:<programlisting><![CDATA[ |             In this case, a typical configuration, combining the namespace and custom beans might | ||||||
|  |             look like this:<programlisting><![CDATA[ | ||||||
| <http> | <http> | ||||||
|   <custom-filter position="FORM_LOGIN_FILTER" ref="myAuthFilter" /> |   <custom-filter position="FORM_LOGIN_FILTER" ref="myAuthFilter" /> | ||||||
|   <session-management session-authentication-strategy-ref="sas"/> |   <session-management session-authentication-strategy-ref="sas"/> | ||||||
|  | @ -60,27 +63,31 @@ | ||||||
|     <section xml:id="concurrent-sessions"> |     <section xml:id="concurrent-sessions"> | ||||||
|         <title>Concurrency Control</title> |         <title>Concurrency Control</title> | ||||||
|         <para>Spring Security is able to prevent a principal from concurrently authenticating to the |         <para>Spring Security is able to prevent a principal from concurrently authenticating to the | ||||||
|       same application more than a specified number of times. Many ISVs take advantage of this to |             same application more than a specified number of times. Many ISVs take advantage of this | ||||||
|       enforce licensing, whilst network administrators like this feature because it helps prevent |             to enforce licensing, whilst network administrators like this feature because it helps | ||||||
|       people from sharing login names. You can, for example, stop user <quote>Batman</quote> from |             prevent people from sharing login names. You can, for example, stop user | ||||||
|       logging onto the web application from two different sessions. You can either expire their |             <quote>Batman</quote> from logging onto the web application from two different sessions. | ||||||
|       previous login or you can report an error when they try to log in again, preventing the second |             You can either expire their previous login or you can report an error when they try to | ||||||
|       login. Note that if you are using the second approach, a user who has not explicitly logged |             log in again, preventing the second login. Note that if you are using the second | ||||||
|       out (but who has just closed their browser, for example) will not be able to log in again |             approach, a user who has not explicitly logged out (but who has just closed their | ||||||
|       until their original session expires.</para> |             browser, for example) will not be able to log in again until their original session | ||||||
|     <para>Concurrency control is supported by the namespace, so please check the earlier namespace |             expires.</para> | ||||||
|       chapter for the simplest configuration. Sometimes you need to customize things though. </para> |         <para>Concurrency control is supported by the namespace, so please check the earlier | ||||||
|  |             namespace chapter for the simplest configuration. Sometimes you need to customize things | ||||||
|  |             though. </para> | ||||||
|         <para>The implementation uses a specialized version of |         <para>The implementation uses a specialized version of | ||||||
|             <interfacename>SessionAuthenticationStrategy</interfacename>, called |             <interfacename>SessionAuthenticationStrategy</interfacename>, called | ||||||
|         <classname>ConcurrentSessionControlStrategy</classname>. <note><para>Previously the |             <classname>ConcurrentSessionControlStrategy</classname>. <note> | ||||||
|           concurrent authentication check was made by the <classname>ProviderManager</classname>, |             <para>Previously the concurrent authentication check was made by the | ||||||
|           which could be injected with a <literal>ConcurrentSessionController</literal>. The latter |                 <classname>ProviderManager</classname>, which could be injected with a | ||||||
|           would check if the user was attempting to exceed the number of permitted sessions. |                 <literal>ConcurrentSessionController</literal>. The latter would check if the user | ||||||
|           However, this approach required that an HTTP session be created in advance, which is |                 was attempting to exceed the number of permitted sessions. However, this approach | ||||||
|           undesirable. In Spring Security 3, the user is first authenticated by the |                 required that an HTTP session be created in advance, which is undesirable. In Spring | ||||||
|  |                 Security 3, the user is first authenticated by the | ||||||
|                 <interfacename>AuthenticationManager</interfacename> and once they are successfully |                 <interfacename>AuthenticationManager</interfacename> and once they are successfully | ||||||
|           authenticated, a session is created and the check is made whether they are allowed to have |                 authenticated, a session is created and the check is made whether they are allowed | ||||||
|           another session open.</para></note></para> |                 to have another session open.</para> | ||||||
|  |             </note></para> | ||||||
|         <para>To use concurrent session support, you'll need to add the following to |         <para>To use concurrent session support, you'll need to add the following to | ||||||
|             <literal>web.xml</literal>: <programlisting><![CDATA[ |             <literal>web.xml</literal>: <programlisting><![CDATA[ | ||||||
|   <listener> |   <listener> | ||||||
|  | @ -89,13 +96,14 @@ | ||||||
|     </listener-class> |     </listener-class> | ||||||
|   </listener> ]]> |   </listener> ]]> | ||||||
|         </programlisting></para> |         </programlisting></para> | ||||||
|     <para>In addition, you will need to add the <literal>ConcurrentSessionFilter</literal> to your |         <para>In addition, you will need to add the <literal>ConcurrentSessionFilter</literal> to | ||||||
|         <classname>FilterChainProxy</classname>. The <classname>ConcurrentSessionFilter</classname> |             your <classname>FilterChainProxy</classname>. The | ||||||
|       requires two properties, <literal>sessionRegistry</literal>, which generally points to an |             <classname>ConcurrentSessionFilter</classname> requires two properties, | ||||||
|       instance of <classname>SessionRegistryImpl</classname>, and <literal>expiredUrl</literal>, which |             <literal>sessionRegistry</literal>, which generally points to an instance of | ||||||
|       points to the page to display when a session has expired. A configuration using the namespace |             <classname>SessionRegistryImpl</classname>, and <literal>expiredUrl</literal>, which | ||||||
|       to create the <classname>FilterChainProxy</classname> and other default beans might look like |             points to the page to display when a session has expired. A configuration using the | ||||||
|       this: <programlisting><![CDATA[ |             namespace to create the <classname>FilterChainProxy</classname> and other default beans | ||||||
|  |             might look like this: <programlisting><![CDATA[ | ||||||
| <http> | <http> | ||||||
|   <custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter" /> |   <custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter" /> | ||||||
|   <custom-filter position="FORM_LOGIN_FILTER" ref="myAuthFilter" /> |   <custom-filter position="FORM_LOGIN_FILTER" ref="myAuthFilter" /> | ||||||
|  | @ -127,10 +135,10 @@ | ||||||
|     </programlisting></para> |     </programlisting></para> | ||||||
|         <para>Adding the listener to <filename>web.xml</filename> causes an |         <para>Adding the listener to <filename>web.xml</filename> causes an | ||||||
|             <literal>ApplicationEvent</literal> to be published to the Spring |             <literal>ApplicationEvent</literal> to be published to the Spring | ||||||
|         <literal>ApplicationContext</literal> every time a <literal>HttpSession</literal> commences |             <literal>ApplicationContext</literal> every time a <literal>HttpSession</literal> | ||||||
|       or terminates. This is critical, as it allows the <classname>SessionRegistryImpl</classname> |             commences or terminates. This is critical, as it allows the | ||||||
|       to be notified when a session ends. Without it, a user will never be able to log back in again |             <classname>SessionRegistryImpl</classname> to be notified when a session ends. Without | ||||||
|       once they have exceeded their session allowance, even if they log out of another session or it |             it, a user will never be able to log back in again once they have exceeded their session | ||||||
|       times out.</para> |             allowance, even if they log out of another session or it times out.</para> | ||||||
|     </section> |     </section> | ||||||
| </chapter> | </chapter> | ||||||
|  |  | ||||||
|  | @ -1,7 +1,10 @@ | ||||||
| <?xml version="1.0" encoding="UTF-8"?> | <?xml version="1.0" encoding="UTF-8"?> | ||||||
| <book version="5.0" xml:id="spring-security-reference-guide" xmlns="http://docbook.org/ns/docbook" | <book version="5.0" xml:id="spring-security-reference-guide" xmlns="http://docbook.org/ns/docbook" | ||||||
|     xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xi="http://www.w3.org/2001/XInclude"> |     xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xi="http://www.w3.org/2001/XInclude"> | ||||||
|   <info><title>Spring Security</title><subtitle>Reference Documentation</subtitle><authorgroup> |     <info> | ||||||
|  |         <title>Spring Security</title> | ||||||
|  |         <subtitle>Reference Documentation</subtitle> | ||||||
|  |         <authorgroup> | ||||||
|             <author> |             <author> | ||||||
|                 <personname>Ben Alex</personname> |                 <personname>Ben Alex</personname> | ||||||
|             </author> |             </author> | ||||||
|  | @ -16,72 +19,78 @@ | ||||||
|     <preface xml:id="preface"> |     <preface xml:id="preface"> | ||||||
|         <title>Preface</title> |         <title>Preface</title> | ||||||
|         <para>Spring Security provides a comprehensive security solution for J2EE-based enterprise |         <para>Spring Security provides a comprehensive security solution for J2EE-based enterprise | ||||||
|       software applications. As you will discover as you venture through this reference guide, we |             software applications. As you will discover as you venture through this reference guide, | ||||||
|       have tried to provide you a useful and highly configurable security system.</para> |             we have tried to provide you a useful and highly configurable security system.</para> | ||||||
|         <para>Security is an ever-moving target, and it's important to pursue a comprehensive, |         <para>Security is an ever-moving target, and it's important to pursue a comprehensive, | ||||||
|       system-wide approach. In security circles we encourage you to adopt "layers of security", so |             system-wide approach. In security circles we encourage you to adopt "layers of | ||||||
|       that each layer tries to be as secure as possible in its own right, with successive layers |             security", so that each layer tries to be as secure as possible in its own right, with | ||||||
|       providing additional security. The "tighter" the security of each layer, the more robust and |             successive layers providing additional security. The "tighter" the security of each | ||||||
|       safe your application will be. At the bottom level you'll need to deal with issues such as |             layer, the more robust and safe your application will be. At the bottom level you'll | ||||||
|       transport security and system identification, in order to mitigate man-in-the-middle attacks. |             need to deal with issues such as transport security and system identification, in order | ||||||
|       Next you'll generally utilise firewalls, perhaps with VPNs or IP security to ensure only |             to mitigate man-in-the-middle attacks. Next you'll generally utilise firewalls, perhaps | ||||||
|       authorised systems can attempt to connect. In corporate environments you may deploy a DMZ to |             with VPNs or IP security to ensure only authorised systems can attempt to connect. In | ||||||
|       separate public-facing servers from backend database and application servers. Your operating |             corporate environments you may deploy a DMZ to separate public-facing servers from | ||||||
|       system will also play a critical part, addressing issues such as running processes as |             backend database and application servers. Your operating system will also play a | ||||||
|       non-privileged users and maximising file system security. An operating system will usually |             critical part, addressing issues such as running processes as non-privileged users and | ||||||
|       also be configured with its own firewall. Hopefully somewhere along the way you'll be trying |             maximising file system security. An operating system will usually also be configured | ||||||
|       to prevent denial of service and brute force attacks against the system. An intrusion |             with its own firewall. Hopefully somewhere along the way you'll be trying to prevent | ||||||
|       detection system will also be especially useful for monitoring and responding to attacks, with |             denial of service and brute force attacks against the system. An intrusion detection | ||||||
|       such systems able to take protective action such as blocking offending TCP/IP addresses in |             system will also be especially useful for monitoring and responding to attacks, with | ||||||
|       real-time. Moving to the higher layers, your Java Virtual Machine will hopefully be configured |             such systems able to take protective action such as blocking offending TCP/IP addresses | ||||||
|       to minimize the permissions granted to different Java types, and then your application will |             in real-time. Moving to the higher layers, your Java Virtual Machine will hopefully be | ||||||
|       add its own problem domain-specific security configuration. Spring Security makes this latter |             configured to minimize the permissions granted to different Java types, and then your | ||||||
|       area - application security - much easier. </para> |             application will add its own problem domain-specific security configuration. Spring | ||||||
|     <para>Of course, you will need to properly address all security layers mentioned above, together |             Security makes this latter area - application security - much easier. </para> | ||||||
|       with managerial factors that encompass every layer. A non-exhaustive list of such managerial |         <para>Of course, you will need to properly address all security layers mentioned above, | ||||||
|       factors would include security bulletin monitoring, patching, personnel vetting, audits, |             together with managerial factors that encompass every layer. A non-exhaustive list of | ||||||
|       change control, engineering management systems, data backup, disaster recovery, performance |             such managerial factors would include security bulletin monitoring, patching, personnel | ||||||
|       benchmarking, load monitoring, centralised logging, incident response procedures etc.</para> |             vetting, audits, change control, engineering management systems, data backup, disaster | ||||||
|     <para>With Spring Security being focused on helping you with the enterprise application security |             recovery, performance benchmarking, load monitoring, centralised logging, incident | ||||||
|       layer, you will find that there are as many different requirements as there are business |             response procedures etc.</para> | ||||||
|       problem domains. A banking application has different needs from an ecommerce application. An |         <para>With Spring Security being focused on helping you with the enterprise application | ||||||
|       ecommerce application has different needs from a corporate sales force automation tool. These |             security layer, you will find that there are as many different requirements as there are | ||||||
|       custom requirements make application security interesting, challenging and rewarding. </para> |             business problem domains. A banking application has different needs from an ecommerce | ||||||
|     <para>Please read <xref linkend="getting-started"/>, in its entirety to begin with. This will |             application. An ecommerce application has different needs from a corporate sales force | ||||||
|       introduce you to the framework and the namespace-based configuration system with which you can |             automation tool. These custom requirements make application security interesting, | ||||||
|       get up and running quite quickly. To get more of an understanding of how Spring Security |             challenging and rewarding. </para> | ||||||
|       works, and some of the classes you might need to use, you should then read <xref |         <para>Please read <xref linkend="getting-started"/>, in its entirety to begin with. This | ||||||
|         linkend="overall-architecture"/>. The remaining parts of this guide are structured in a more |             will introduce you to the framework and the namespace-based configuration system with | ||||||
|       traditional reference style, designed to be read on an as-required basis. We'd also recommend |             which you can get up and running quite quickly. To get more of an understanding of how | ||||||
|       that you read up as much as possible on application security issues in general. Spring |             Spring Security works, and some of the classes you might need to use, you should then | ||||||
|       Security is not a panacea which will solve all security issues. It is important that the |             read <xref linkend="overall-architecture"/>. The remaining parts of this guide are | ||||||
|       application is designed with security in mind from the start. Attempting to retrofit it is not |             structured in a more traditional reference style, designed to be read on an as-required | ||||||
|       a good idea. In particular, if you are building a web application, you should be aware of the |             basis. We'd also recommend that you read up as much as possible on application security | ||||||
|       many potential vulnerabilities such as cross-site scripting, request-forgery and |             issues in general. Spring Security is not a panacea which will solve all security | ||||||
|       session-hijacking which you should be taking into account from the start. The OWASP web site |             issues. It is important that the application is designed with security in mind from the | ||||||
|       (http://www.owasp.org/) maintains a top ten list of web application vulnerabilities as well as |             start. Attempting to retrofit it is not a good idea. In particular, if you are building | ||||||
|       a lot of useful reference information. </para> |             a web application, you should be aware of the many potential vulnerabilities such as | ||||||
|     <para>We hope that you find this reference guide useful, and we welcome your feedback and <link |             cross-site scripting, request-forgery and session-hijacking which you should be taking | ||||||
|         xlink:href="#jira">suggestions</link>. </para> |             into account from the start. The OWASP web site (http://www.owasp.org/) maintains a top | ||||||
|     <para>Finally, welcome to the Spring Security <link xlink:href="#community">community</link>. |             ten list of web application vulnerabilities as well as a lot of useful reference | ||||||
|     </para> |             information. </para> | ||||||
|  |         <para>We hope that you find this reference guide useful, and we welcome your feedback and | ||||||
|  |                 <link xlink:href="#jira">suggestions</link>. </para> | ||||||
|  |         <para>Finally, welcome to the Spring Security <link xlink:href="#community" | ||||||
|  |             >community</link>. </para> | ||||||
|     </preface> |     </preface> | ||||||
|     <part xml:id="getting-started"> |     <part xml:id="getting-started"> | ||||||
|         <title>Getting Started</title> |         <title>Getting Started</title> | ||||||
|         <partintro> |         <partintro> | ||||||
|             <para>The later parts of this guide provide an in-depth discussion of the framework |             <para>The later parts of this guide provide an in-depth discussion of the framework | ||||||
|         architecture and implementation classes, which you need to understand if you want to do any |                 architecture and implementation classes, which you need to understand if you want to | ||||||
|         serious customization. In this part, we'll introduce Spring Security 3.0, give a brief |                 do any serious customization. In this part, we'll introduce Spring Security 3.0, | ||||||
|         overview of the project's history and take a slightly gentler look at how to get started |                 give a brief overview of the project's history and take a slightly gentler look at | ||||||
|         using the framework. In particular, we'll look at namespace configuration which provides a |                 how to get started using the framework. In particular, we'll look at namespace | ||||||
|         much simpler way of securing your application compared to the traditional Spring bean |                 configuration which provides a much simpler way of securing your application | ||||||
|         approach where you have to wire up all the implementation classes individually. </para> |                 compared to the traditional Spring bean approach where you have to wire up all the | ||||||
|       <para> We'll also take a look at the sample applications that are available. It's worth trying |                 implementation classes individually. </para> | ||||||
|         to run these and experimenting with them a bit even before you read the later sections - you |             <para> We'll also take a look at the sample applications that are available. It's worth | ||||||
|         can dip back into them as your understanding of the framework increases. Please also check |                 trying to run these and experimenting with them a bit even before you read the later | ||||||
|         out the <link xlink:href="http://static.springsource.org/spring-security/site/index.html" |                 sections - you can dip back into them as your understanding of the framework | ||||||
|           >project website</link> as it has useful information on building the project, plus links |                 increases. Please also check out the <link | ||||||
|         to articles, videos and tutorials. </para> |                     xlink:href="http://static.springsource.org/spring-security/site/index.html" | ||||||
|  |                     >project website</link> as it has useful information on building the project, | ||||||
|  |                 plus links to articles, videos and tutorials. </para> | ||||||
|         </partintro> |         </partintro> | ||||||
|         <xi:include href="introduction.xml"/> |         <xi:include href="introduction.xml"/> | ||||||
|         <xi:include href="namespace-config.xml"/> |         <xi:include href="namespace-config.xml"/> | ||||||
|  | @ -91,13 +100,13 @@ | ||||||
|     <part xml:id="overall-architecture"> |     <part xml:id="overall-architecture"> | ||||||
|         <title>Architecture and Implementation</title> |         <title>Architecture and Implementation</title> | ||||||
|         <partintro> |         <partintro> | ||||||
|       <para>Once you are familiar with setting up and running some namespace-configuration based |             <para>Once you are familiar with setting up and running some namespace-configuration | ||||||
|         applications, you may wish to develop more of an understanding of how the framework actually |                 based applications, you may wish to develop more of an understanding of how the | ||||||
|         works behind the namespace facade. Like most software, Spring Security has certain central |                 framework actually works behind the namespace facade. Like most software, Spring | ||||||
|         interfaces, classes and conceptual abstractions that are commonly used throughout the |                 Security has certain central interfaces, classes and conceptual abstractions that | ||||||
|         framework. In this part of the reference guide we will look at some of these and see how |                 are commonly used throughout the framework. In this part of the reference guide we | ||||||
|         they work together to support authentication and access-control within Spring |                 will look at some of these and see how they work together to support authentication | ||||||
|         Security.</para> |                 and access-control within Spring Security.</para> | ||||||
|         </partintro> |         </partintro> | ||||||
|         <xi:include href="technical-overview.xml"/> |         <xi:include href="technical-overview.xml"/> | ||||||
|         <xi:include href="core-services.xml"/> |         <xi:include href="core-services.xml"/> | ||||||
|  | @ -105,13 +114,14 @@ | ||||||
|     <part xml:id="web-app-security"> |     <part xml:id="web-app-security"> | ||||||
|         <title>Web Application Security</title> |         <title>Web Application Security</title> | ||||||
|         <partintro> |         <partintro> | ||||||
|       <para> Most Spring Security users will be using the framework in applications which make user |             <para> Most Spring Security users will be using the framework in applications which make | ||||||
|         of HTTP and the Servlet API. In this part, we'll take a look at how Spring Security provides |                 user of HTTP and the Servlet API. In this part, we'll take a look at how Spring | ||||||
|         authentication and access-control features for the web layer of an application. We'll look |                 Security provides authentication and access-control features for the web layer of an | ||||||
|         behind the facade of the namespace and see which classes and interfaces are actually |                 application. We'll look behind the facade of the namespace and see which classes and | ||||||
|         assembled to provide web-layer security. In some situations it is necessary to use |                 interfaces are actually assembled to provide web-layer security. In some situations | ||||||
|         traditional bean configuration to provide full control over the configuration, so we'll also |                 it is necessary to use traditional bean configuration to provide full control over | ||||||
|         see how to configure these classes directly without the namespace.</para> |                 the configuration, so we'll also see how to configure these classes directly without | ||||||
|  |                 the namespace.</para> | ||||||
|         </partintro> |         </partintro> | ||||||
|         <xi:include href="security-filter-chain.xml"/> |         <xi:include href="security-filter-chain.xml"/> | ||||||
|         <xi:include href="core-filters.xml"/> |         <xi:include href="core-filters.xml"/> | ||||||
|  | @ -148,16 +158,16 @@ | ||||||
|     <part xml:id="authorization"> |     <part xml:id="authorization"> | ||||||
|         <title>Authorization</title> |         <title>Authorization</title> | ||||||
|         <partintro> |         <partintro> | ||||||
|       <para>The advanced authorization capabilities within Spring Security represent one of the most |             <para>The advanced authorization capabilities within Spring Security represent one of | ||||||
|         compelling reasons for its popularity. Irrespective of how you choose to authenticate - |                 the most compelling reasons for its popularity. Irrespective of how you choose to | ||||||
|         whether using a Spring Security-provided mechanism and provider, or integrating with a |                 authenticate - whether using a Spring Security-provided mechanism and provider, or | ||||||
|         container or other non-Spring Security authentication authority - you will find the |                 integrating with a container or other non-Spring Security authentication authority - | ||||||
|         authorization services can be used within your application in a consistent and simple |                 you will find the authorization services can be used within your application in a | ||||||
|         way.</para> |                 consistent and simple way.</para> | ||||||
|             <para>In this part we'll explore the different |             <para>In this part we'll explore the different | ||||||
|           <classname>AbstractSecurityInterceptor</classname> implementations, which were introduced |                     <classname>AbstractSecurityInterceptor</classname> implementations, which were | ||||||
|         in Part I. We then move on to explore how to fine-tune authorization through use of domain |                 introduced in Part I. We then move on to explore how to fine-tune authorization | ||||||
|         access control lists.</para> |                 through use of domain access control lists.</para> | ||||||
|         </partintro> |         </partintro> | ||||||
|         <xi:include href="authorization-common.xml"/> |         <xi:include href="authorization-common.xml"/> | ||||||
|         <xi:include href="secured-objects.xml"/> |         <xi:include href="secured-objects.xml"/> | ||||||
|  | @ -169,8 +179,9 @@ | ||||||
|       Essentially standalone features which do not have to follow on directly from earlier chapters |       Essentially standalone features which do not have to follow on directly from earlier chapters | ||||||
|     --> |     --> | ||||||
|         <partintro> |         <partintro> | ||||||
|       <para> In this part we cover features which require a knowledge of previous chapters  as well |             <para> In this part we cover features which require a knowledge of previous chapters as | ||||||
|         as some of the more advanced and less-commonly used features of the framework.</para> |                 well as some of the more advanced and less-commonly used features of the | ||||||
|  |                 framework.</para> | ||||||
|         </partintro> |         </partintro> | ||||||
|         <xi:include href="domain-acls.xml"/> |         <xi:include href="domain-acls.xml"/> | ||||||
|         <xi:include href="preauth.xml"/> |         <xi:include href="preauth.xml"/> | ||||||
|  |  | ||||||
|  | @ -17,12 +17,12 @@ | ||||||
|             <para>The legacy options from Spring Security 2.0 are also supported, but |             <para>The legacy options from Spring Security 2.0 are also supported, but | ||||||
|                 discouraged.</para> |                 discouraged.</para> | ||||||
|             </footnote>. The first approach uses a <link xlink:href="el-access-we">web-security |             </footnote>. The first approach uses a <link xlink:href="el-access-we">web-security | ||||||
|                 expression</link>, specified in the <literal>access</literal> attribute of the tag. |             expression</link>, specified in the <literal>access</literal> attribute of the tag. The | ||||||
|             The expression evaluation will be delegated to the |             expression evaluation will be delegated to the | ||||||
|                 <interfacename>WebSecurityExpressionHandler</interfacename> defined in the |             <interfacename>WebSecurityExpressionHandler</interfacename> defined in the application | ||||||
|             application context (you should have web expressions enabled in your |             context (you should have web expressions enabled in your <literal><http></literal> | ||||||
|                 <literal><http></literal> namespace configuration to make sure this service is |             namespace configuration to make sure this service is available). So, for example, you | ||||||
|             available). So, for example, you might |             might | ||||||
|             have<programlisting><sec:authorize access="hasRole('supervisor')"> |             have<programlisting><sec:authorize access="hasRole('supervisor')"> | ||||||
| 
 | 
 | ||||||
| This content will only be visible to users who have | This content will only be visible to users who have | ||||||
|  | @ -58,13 +58,13 @@ This content will only be visible to users who are authorized to send requests t | ||||||
|             the JSP. So, for example, if the <literal>principal</literal> property of the |             the JSP. So, for example, if the <literal>principal</literal> property of the | ||||||
|             <interfacename>Authentication</interfacename> is an instance of Spring Security's |             <interfacename>Authentication</interfacename> is an instance of Spring Security's | ||||||
|             <interfacename>UserDetails</interfacename> object, then using |             <interfacename>UserDetails</interfacename> object, then using | ||||||
|                 <literal><sec:authentication property="principal.username" /></literal> will |             <literal><sec:authentication property="principal.username" /></literal> will render | ||||||
|             render the name of the current user.</para> |             the name of the current user.</para> | ||||||
|         <para>Of course, it isn't necessary to use JSP tags for this kind of thing and some people |         <para>Of course, it isn't necessary to use JSP tags for this kind of thing and some people | ||||||
|             prefer to keep as little logic as possible in the view. You can access the |             prefer to keep as little logic as possible in the view. You can access the | ||||||
|                 <interfacename>Authentication</interfacename> object in your MVC controller (by |             <interfacename>Authentication</interfacename> object in your MVC controller (by calling | ||||||
|             calling <code>SecurityContextHolder.getContext().getAuthentication()</code>) and add the |             <code>SecurityContextHolder.getContext().getAuthentication()</code>) and add the data | ||||||
|             data directly to your model for rendering by the view.</para> |             directly to your model for rendering by the view.</para> | ||||||
|     </section> |     </section> | ||||||
|     <section> |     <section> | ||||||
|         <title>The <literal>accesscontrollist</literal> Tag</title> |         <title>The <literal>accesscontrollist</literal> Tag</title> | ||||||
|  | @ -80,13 +80,13 @@ represented by the values "1" or "2" on the given object. | ||||||
| </sec:accesscontrollist></programlisting></para> | </sec:accesscontrollist></programlisting></para> | ||||||
|         <para>The permissions are passed to the <interfacename>PermissionFactory</interfacename> |         <para>The permissions are passed to the <interfacename>PermissionFactory</interfacename> | ||||||
|             defined in the application context, converting them to ACL |             defined in the application context, converting them to ACL | ||||||
|                 <interfacename>Permission</interfacename> instances, so they may be any format which |             <interfacename>Permission</interfacename> instances, so they may be any format which is | ||||||
|             is supported by the factory - they don't have to be integers, they could be strings like |             supported by the factory - they don't have to be integers, they could be strings like | ||||||
|             <literal>READ</literal> or <literal>WRITE</literal>. If no |             <literal>READ</literal> or <literal>WRITE</literal>. If no | ||||||
|             <interfacename>PermissionFactory</interfacename> is found, an instance of |             <interfacename>PermissionFactory</interfacename> is found, an instance of | ||||||
|             <classname>DefaultPermissionFactory</classname> will be used. The |             <classname>DefaultPermissionFactory</classname> will be used. The | ||||||
|                 <interfacename>AclService</interfacename>from the application context will be used |             <interfacename>AclService</interfacename>from the application context will be used to | ||||||
|             to load the <interfacename>Acl</interfacename> instance for the supplied object. The |             load the <interfacename>Acl</interfacename> instance for the supplied object. The | ||||||
|             <interfacename>Acl</interfacename> will be invoked with the required permissions to |             <interfacename>Acl</interfacename> will be invoked with the required permissions to | ||||||
|             check if any of them are granted.</para> |             check if any of them are granted.</para> | ||||||
|     </section> |     </section> | ||||||
|  |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -7,29 +7,32 @@ | ||||||
|     <section xml:id="filters"> |     <section xml:id="filters"> | ||||||
|         <title>The Security Filter Chain</title> |         <title>The Security Filter Chain</title> | ||||||
|         <para>Spring Security's web infrastructure is based entirely on standard servlet filters. It |         <para>Spring Security's web infrastructure is based entirely on standard servlet filters. It | ||||||
|       doesn't use servlets or any other servlet-based frameworks (such as Spring MVC) internally, so |             doesn't use servlets or any other servlet-based frameworks (such as Spring MVC) | ||||||
|       it has no strong links to any particular web technology. It deals in |             internally, so it has no strong links to any particular web technology. It deals in | ||||||
|         <classname>HttpServletRequest</classname>s and <classname>HttpServletResponse</classname>s |             <classname>HttpServletRequest</classname>s and | ||||||
|       and doesn't care whether the requests come from a browser, a web service client, an |             <classname>HttpServletResponse</classname>s and doesn't care whether the requests come | ||||||
|         <classname>HttpInvoker</classname> or an AJAX application. </para> |             from a browser, a web service client, an <classname>HttpInvoker</classname> or an AJAX | ||||||
|  |             application. </para> | ||||||
|         <para> Spring Security maintains a filter chain internally where each of the filters has a |         <para> Spring Security maintains a filter chain internally where each of the filters has a | ||||||
|       particular responsibility and filters are added or removed from the configuration depending on |             particular responsibility and filters are added or removed from the configuration | ||||||
|       which services are required. The ordering of the filters is important as there are |             depending on which services are required. The ordering of the filters is important as | ||||||
|       dependencies between them. If you have been using <link xlink:href="#ns-config">namespace |             there are dependencies between them. If you have been using <link | ||||||
|         configuration</link>, then the filters are automatically configured for you and you don't |             xlink:href="#ns-config">namespace configuration</link>, then the filters are | ||||||
|       have to define any Spring beans explicitly but here may be times when you want full control |             automatically configured for you and you don't have to define any Spring beans | ||||||
|       over the security filter chain, either because you are using features which aren't supported |             explicitly but here may be times when you want full control over the security filter | ||||||
|       in the namespace, or you are using your own customized versions of classes.</para> |             chain, either because you are using features which aren't supported in the namespace, or | ||||||
|  |             you are using your own customized versions of classes.</para> | ||||||
|         <section xml:id="delegating-filter-proxy"> |         <section xml:id="delegating-filter-proxy"> | ||||||
|             <title><classname>DelegatingFilterProxy</classname></title> |             <title><classname>DelegatingFilterProxy</classname></title> | ||||||
|             <para> When using servlet filters, you obviously need to declare them in your |             <para> When using servlet filters, you obviously need to declare them in your | ||||||
|           <filename>web.xml</filename>, or they will be ignored by the servlet container. In Spring |                 <filename>web.xml</filename>, or they will be ignored by the servlet container. In | ||||||
|         Security, the filter classes are also Spring beans defined in the application context and |                 Spring Security, the filter classes are also Spring beans defined in the application | ||||||
|         thus able to take advantage of Spring's rich dependency-injection facilities and lifecycle |                 context and thus able to take advantage of Spring's rich dependency-injection | ||||||
|         interfaces. Spring's <classname>DelegatingFilterProxy</classname> provides the link between |                 facilities and lifecycle interfaces. Spring's | ||||||
|  |                 <classname>DelegatingFilterProxy</classname> provides the link between | ||||||
|                 <filename>web.xml</filename> and the application context. </para> |                 <filename>web.xml</filename> and the application context. </para> | ||||||
|       <para>When using <classname>DelegatingFilterProxy</classname>, you will see something like |             <para>When using <classname>DelegatingFilterProxy</classname>, you will see something | ||||||
|         this in the <filename>web.xml</filename> file: <programlisting><![CDATA[ |                 like this in the <filename>web.xml</filename> file: <programlisting><![CDATA[ | ||||||
|   <filter> |   <filter> | ||||||
|     <filter-name>myFilter</filter-name> |     <filter-name>myFilter</filter-name> | ||||||
|     <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> |     <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> | ||||||
|  | @ -40,29 +43,31 @@ | ||||||
|     <url-pattern>/*</url-pattern> |     <url-pattern>/*</url-pattern> | ||||||
|   </filter-mapping>]]> |   </filter-mapping>]]> | ||||||
|         </programlisting> Notice that the filter is actually a |         </programlisting> Notice that the filter is actually a | ||||||
|           <literal>DelegatingFilterProxy</literal>, and not the class that will actually implement |                 <literal>DelegatingFilterProxy</literal>, and not the class that will actually | ||||||
|         the logic of the filter. What <classname>DelegatingFilterProxy</classname> does is delegate |                 implement the logic of the filter. What <classname>DelegatingFilterProxy</classname> | ||||||
|         the <interfacename>Filter</interfacename>'s methods through to a bean which is obtained from |                 does is delegate the <interfacename>Filter</interfacename>'s methods through to a | ||||||
|         the Spring application context. This enables the bean to benefit from the Spring web |                 bean which is obtained from the Spring application context. This enables the bean to | ||||||
|         application context lifecycle support and configuration flexibility. The bean must implement |                 benefit from the Spring web application context lifecycle support and configuration | ||||||
|           <interfacename>javax.servlet.Filter</interfacename> and it must have the same name as that |                 flexibility. The bean must implement | ||||||
|         in the <literal>filter-name</literal> element. Read the Javadoc for |                 <interfacename>javax.servlet.Filter</interfacename> and it must have the same name | ||||||
|  |                 as that in the <literal>filter-name</literal> element. Read the Javadoc for | ||||||
|                 <classname>DelegatingFilterProxy</classname> for more information</para> |                 <classname>DelegatingFilterProxy</classname> for more information</para> | ||||||
|         </section> |         </section> | ||||||
|         <section xml:id="filter-chain-proxy"> |         <section xml:id="filter-chain-proxy"> | ||||||
|             <title><classname>FilterChainProxy</classname></title> |             <title><classname>FilterChainProxy</classname></title> | ||||||
|       <para> It should now be clear that you can declare each Spring Security filter bean that you |             <para> It should now be clear that you can declare each Spring Security filter bean that | ||||||
|         require in your application context file and add a corresponding |                 you require in your application context file and add a corresponding | ||||||
|           <classname>DelegatingFilterProxy</classname> entry to <filename>web.xml</filename> for |                 <classname>DelegatingFilterProxy</classname> entry to <filename>web.xml</filename> | ||||||
|         each filter, making sure that they are ordered correctly. This is a cumbersome approach and |                 for each filter, making sure that they are ordered correctly. This is a cumbersome | ||||||
|         clutters up the <filename>web.xml</filename> file quickly if we have a lot of filters. We |                 approach and clutters up the <filename>web.xml</filename> file quickly if we have a | ||||||
|         would prefer to just add a single entry to <filename>web.xml</filename> and deal entirely |                 lot of filters. We would prefer to just add a single entry to | ||||||
|         with the application context file for managing our web security beans. This is where Spring |                 <filename>web.xml</filename> and deal entirely with the application context file for | ||||||
|         Secuiryt's <classname>FilterChainProxy</classname> comes in. It is wired using a |                 managing our web security beans. This is where Spring Secuiryt's | ||||||
|           <literal>DelegatingFilterProxy</literal>, just like in the example above, but with the |                 <classname>FilterChainProxy</classname> comes in. It is wired using a | ||||||
|           <literal>filter-name</literal> set to the bean name <quote>filterChainProxy</quote>. The |                 <literal>DelegatingFilterProxy</literal>, just like in the example above, but with | ||||||
|         filter chain is then declared in the application context with the same bean name. Here's an |                 the <literal>filter-name</literal> set to the bean name | ||||||
|         example: <programlisting language="xml"><![CDATA[ |                 <quote>filterChainProxy</quote>. The filter chain is then declared in the | ||||||
|  |                 application context with the same bean name. Here's an example: <programlisting language="xml"><![CDATA[ | ||||||
| <bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy"> | <bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy"> | ||||||
|   <sec:filter-chain-map path-type="ant"> |   <sec:filter-chain-map path-type="ant"> | ||||||
|      <sec:filter-chain pattern="/webServices/**" filters=" |      <sec:filter-chain pattern="/webServices/**" filters=" | ||||||
|  | @ -78,127 +83,134 @@ | ||||||
|   </sec:filter-chain-map> |   </sec:filter-chain-map> | ||||||
| </bean> | </bean> | ||||||
| ]]> | ]]> | ||||||
|       </programlisting> The namespace element <literal>filter-chain-map</literal> is |       </programlisting> The namespace element <literal>filter-chain-map</literal> is used to set | ||||||
|         used to set up the security filter chain(s) which are required within the application<footnote> |                 up the security filter chain(s) which are required within the application<footnote> | ||||||
|           <para>Note that you'll need to include the security namespace in your application context |                 <para>Note that you'll need to include the security namespace in your application | ||||||
|             XML file in order to use this syntax.</para> |                     context XML file in order to use this syntax.</para> | ||||||
|         </footnote>. It maps a particular URL pattern to a chain of filters built up from the bean |                 </footnote>. It maps a particular URL pattern to a chain of filters built up from | ||||||
|         names specified in the <literal>filters</literal> element. Both regular expressions and Ant |                 the bean names specified in the <literal>filters</literal> element. Both regular | ||||||
|         Paths are supported, and the most specific URIs appear first. At runtime the |                 expressions and Ant Paths are supported, and the most specific URIs appear first. At | ||||||
|           <classname>FilterChainProxy</classname> will locate the first URI pattern that matches the |                 runtime the <classname>FilterChainProxy</classname> will locate the first URI | ||||||
|         current web request and the list of filter beans specified by the <literal>filters</literal> |                 pattern that matches the current web request and the list of filter beans specified | ||||||
|         attribute will be applied to that request. The filters will be invoked in the order they are |                 by the <literal>filters</literal> attribute will be applied to that request. The | ||||||
|         defined, so you have complete control over the filter chain which is applied to a particular |                 filters will be invoked in the order they are defined, so you have complete control | ||||||
|         URL.</para> |                 over the filter chain which is applied to a particular URL.</para> | ||||||
|             <para>You may have noticed we have declared two |             <para>You may have noticed we have declared two | ||||||
|                 <classname>SecurityContextPersistenceFilter</classname>s in the filter chain |                 <classname>SecurityContextPersistenceFilter</classname>s in the filter chain | ||||||
|           (<literal>ASC</literal> is short for <literal>allowSessionCreation</literal>, a property |                 (<literal>ASC</literal> is short for <literal>allowSessionCreation</literal>, a | ||||||
|         of <classname>SecurityContextPersistenceFilter</classname>). As web services will never |                 property of <classname>SecurityContextPersistenceFilter</classname>). As web | ||||||
|         present a <literal>jsessionid</literal> on future requests, creating |                 services will never present a <literal>jsessionid</literal> on future requests, | ||||||
|           <literal>HttpSession</literal>s for such user agents would be wasteful. If you had a |                 creating <literal>HttpSession</literal>s for such user agents would be wasteful. If | ||||||
|         high-volume application which required maximum scalability, we recommend you use the |                 you had a high-volume application which required maximum scalability, we recommend | ||||||
|         approach shown above. For smaller applications, using a single |                 you use the approach shown above. For smaller applications, using a single | ||||||
|                 <classname>SecurityContextPersistenceFilter</classname> (with its default |                 <classname>SecurityContextPersistenceFilter</classname> (with its default | ||||||
|                 <literal>allowSessionCreation</literal> as <literal>true</literal>) would likely be |                 <literal>allowSessionCreation</literal> as <literal>true</literal>) would likely be | ||||||
|                 sufficient.</para> |                 sufficient.</para> | ||||||
|       <para>In relation to lifecycle issues, the <classname>FilterChainProxy</classname> will always |             <para>In relation to lifecycle issues, the <classname>FilterChainProxy</classname> will | ||||||
|         delegate <methodname>init(FilterConfig)</methodname> and <methodname>destroy()</methodname> |                 always delegate <methodname>init(FilterConfig)</methodname> and | ||||||
|         methods through to the underlaying <interfacename>Filter</interfacename>s if such methods |                 <methodname>destroy()</methodname> methods through to the underlaying | ||||||
|         are called against <classname>FilterChainProxy</classname> itself. In this case, |                 <interfacename>Filter</interfacename>s if such methods are called against | ||||||
|           <classname>FilterChainProxy</classname> guarantees to only initialize and destroy each |                 <classname>FilterChainProxy</classname> itself. In this case, | ||||||
|           <literal>Filter</literal> bean once, no matter how many times it is declared in the filter |                 <classname>FilterChainProxy</classname> guarantees to only initialize and destroy | ||||||
|         chain(s). You control the overall choice as to whether these methods are called or not via |                 each <literal>Filter</literal> bean once, no matter how many times it is declared in | ||||||
|         the <literal>targetFilterLifecycle</literal> initialization parameter of |                 the filter chain(s). You control the overall choice as to whether these methods are | ||||||
|           <literal>DelegatingFilterProxy</literal>. By default this property is |                 called or not via the <literal>targetFilterLifecycle</literal> initialization | ||||||
|           <literal>false</literal> and servlet container lifecycle invocations are not delegated |                 parameter of <literal>DelegatingFilterProxy</literal>. By default this property is | ||||||
|         through <literal>DelegatingFilterProxy</literal>.</para> |                 <literal>false</literal> and servlet container lifecycle invocations are not | ||||||
|  |                 delegated through <literal>DelegatingFilterProxy</literal>.</para> | ||||||
|             <para> When we looked at how to set up web security using <link |             <para> When we looked at how to set up web security using <link | ||||||
|                 xlink:href="#namespace-auto-config">namespace configuration</link>, we used a |                 xlink:href="#namespace-auto-config">namespace configuration</link>, we used a | ||||||
|                 <literal>DelegatingFilterProxy</literal> with the name |                 <literal>DelegatingFilterProxy</literal> with the name | ||||||
|           <quote>springSecurityFilterChain</quote>. You should now be able to see that this is the |                 <quote>springSecurityFilterChain</quote>. You should now be able to see that this is | ||||||
|         name of the <classname>FilterChainProxy</classname> which is created by the namespace. </para> |                 the name of the <classname>FilterChainProxy</classname> which is created by the | ||||||
|  |                 namespace. </para> | ||||||
|             <section> |             <section> | ||||||
|                 <title>Bypassing the Filter Chain</title> |                 <title>Bypassing the Filter Chain</title> | ||||||
|         <para> As with the namespace, you can use the attribute <literal>filters = "none"</literal> |                 <para> As with the namespace, you can use the attribute <literal>filters = | ||||||
|           as an alternative to supplying a filter bean list. This will omit the request pattern from |                     "none"</literal> as an alternative to supplying a filter bean list. This will | ||||||
|           the security filter chain entirely. Note that anything matching this path will then have |                     omit the request pattern from the security filter chain entirely. Note that | ||||||
|           no authentication or authorization services applied and will be freely accessible. If you |                     anything matching this path will then have no authentication or authorization | ||||||
|           want to make use of the contents of the <classname>SecurityContext</classname> contents |                     services applied and will be freely accessible. If you want to make use of the | ||||||
|           during a request, then it must have passed through the security filter chain. Otherwise |                     contents of the <classname>SecurityContext</classname> contents during a | ||||||
|           the <classname>SecurityContextHolder</classname> will not have been populated and the |                     request, then it must have passed through the security filter chain. Otherwise | ||||||
|           contents will be null.</para> |                     the <classname>SecurityContextHolder</classname> will not have been populated | ||||||
|  |                     and the contents will be null.</para> | ||||||
|             </section> |             </section> | ||||||
|         </section> |         </section> | ||||||
|         <section> |         <section> | ||||||
|             <title>Filter Ordering</title> |             <title>Filter Ordering</title> | ||||||
|       <para>The order that filters are defined in the chain is very important. Irrespective of which |             <para>The order that filters are defined in the chain is very important. Irrespective of | ||||||
|         filters you are actually using, the order should be as follows: |                 which filters you are actually using, the order should be as follows: <orderedlist> | ||||||
|         <orderedlist> |  | ||||||
|                 <listitem> |                 <listitem> | ||||||
|             <para><classname>ChannelProcessingFilter</classname>, because it might need to redirect |                     <para><classname>ChannelProcessingFilter</classname>, because it might need to | ||||||
|               to a different protocol</para> |                         redirect to a different protocol</para> | ||||||
|                 </listitem> |                 </listitem> | ||||||
|                 <listitem> |                 <listitem> | ||||||
|                     <para><classname>ConcurrentSessionFilter</classname>, because it doesn't use any |                     <para><classname>ConcurrentSessionFilter</classname>, because it doesn't use any | ||||||
|                 <classname>SecurityContextHolder</classname> functionality but needs to update the |                         <classname>SecurityContextHolder</classname> functionality but needs to | ||||||
|                 <interfacename>SessionRegistry</interfacename> to reflect ongoing requests from the |                         update the <interfacename>SessionRegistry</interfacename> to reflect ongoing | ||||||
|               principal</para> |                         requests from the principal</para> | ||||||
|                 </listitem> |                 </listitem> | ||||||
|                 <listitem> |                 <listitem> | ||||||
|                     <para><classname>SecurityContextPersistenceFilter</classname>, so a |                     <para><classname>SecurityContextPersistenceFilter</classname>, so a | ||||||
|                         <interfacename>SecurityContext</interfacename> can be set up in the |                         <interfacename>SecurityContext</interfacename> can be set up in the | ||||||
|                 <classname>SecurityContextHolder</classname> at the beginning of a web request, and |                         <classname>SecurityContextHolder</classname> at the beginning of a web | ||||||
|               any changes to the <interfacename>SecurityContext</interfacename> can be copied to the |                         request, and any changes to the | ||||||
|                 <literal>HttpSession</literal> when the web request ends (ready for use with the |                         <interfacename>SecurityContext</interfacename> can be copied to the | ||||||
|               next web request)</para> |                         <literal>HttpSession</literal> when the web request ends (ready for use with | ||||||
|  |                         the next web request)</para> | ||||||
|                 </listitem> |                 </listitem> | ||||||
|                 <listitem> |                 <listitem> | ||||||
|                     <para>Authentication processing mechanisms - |                     <para>Authentication processing mechanisms - | ||||||
|                         <classname>UsernamePasswordAuthenticationFilter</classname>, |                         <classname>UsernamePasswordAuthenticationFilter</classname>, | ||||||
|                         <classname>CasProcessingFilter</classname>, |                         <classname>CasProcessingFilter</classname>, | ||||||
|                         <classname>BasicProcessingFilter</classname> etc - so that the |                         <classname>BasicProcessingFilter</classname> etc - so that the | ||||||
|                 <classname>SecurityContextHolder</classname> can be modified to contain a valid |                         <classname>SecurityContextHolder</classname> can be modified to contain a | ||||||
|                 <interfacename>Authentication</interfacename> request token</para> |                         valid <interfacename>Authentication</interfacename> request token</para> | ||||||
|                 </listitem> |                 </listitem> | ||||||
|                 <listitem> |                 <listitem> | ||||||
|             <para>The <literal>SecurityContextHolderAwareRequestFilter</literal>, if you are using |                     <para>The <literal>SecurityContextHolderAwareRequestFilter</literal>, if you are | ||||||
|               it to install a Spring Security aware <literal>HttpServletRequestWrapper</literal> |                         using it to install a Spring Security aware | ||||||
|               into your servlet container</para> |                         <literal>HttpServletRequestWrapper</literal> into your servlet | ||||||
|  |                         container</para> | ||||||
|                 </listitem> |                 </listitem> | ||||||
|                 <listitem> |                 <listitem> | ||||||
|                     <para><classname>RememberMeProcessingFilter</classname>, so that if no earlier |                     <para><classname>RememberMeProcessingFilter</classname>, so that if no earlier | ||||||
|                         authentication processing mechanism updated the |                         authentication processing mechanism updated the | ||||||
|                 <classname>SecurityContextHolder</classname>, and the request presents a cookie that |                         <classname>SecurityContextHolder</classname>, and the request presents a | ||||||
|               enables remember-me services to take place, a suitable remembered |                         cookie that enables remember-me services to take place, a suitable | ||||||
|                 <interfacename>Authentication</interfacename> object will be put there</para> |                         remembered <interfacename>Authentication</interfacename> object will be put | ||||||
|  |                         there</para> | ||||||
|                 </listitem> |                 </listitem> | ||||||
|                 <listitem> |                 <listitem> | ||||||
|                     <para><classname>AnonymousProcessingFilter</classname>, so that if no earlier |                     <para><classname>AnonymousProcessingFilter</classname>, so that if no earlier | ||||||
|                         authentication processing mechanism updated the |                         authentication processing mechanism updated the | ||||||
|                         <classname>SecurityContextHolder</classname>, an anonymous |                         <classname>SecurityContextHolder</classname>, an anonymous | ||||||
|                 <interfacename>Authentication</interfacename> object will be put there</para> |                         <interfacename>Authentication</interfacename> object will be put | ||||||
|  |                         there</para> | ||||||
|                 </listitem> |                 </listitem> | ||||||
|                 <listitem> |                 <listitem> | ||||||
|             <para><classname>ExceptionTranslationFilter</classname>, to catch any Spring Security |                     <para><classname>ExceptionTranslationFilter</classname>, to catch any Spring | ||||||
|               exceptions so that either an HTTP error response can be returned or an appropriate |                         Security exceptions so that either an HTTP error response can be returned or | ||||||
|                 <interfacename>AuthenticationEntryPoint</interfacename> can be launched</para> |                         an appropriate <interfacename>AuthenticationEntryPoint</interfacename> can | ||||||
|  |                         be launched</para> | ||||||
|                 </listitem> |                 </listitem> | ||||||
|                 <listitem> |                 <listitem> | ||||||
|             <para><classname>FilterSecurityInterceptor</classname>, to protect web URIs and raise |                     <para><classname>FilterSecurityInterceptor</classname>, to protect web URIs and | ||||||
|               exceptions when access is denied</para> |                         raise exceptions when access is denied</para> | ||||||
|                 </listitem> |                 </listitem> | ||||||
|                 </orderedlist></para> |                 </orderedlist></para> | ||||||
|         </section> |         </section> | ||||||
|         <section> |         <section> | ||||||
|             <title>Use with other Filter-Based Frameworks</title> |             <title>Use with other Filter-Based Frameworks</title> | ||||||
|       <para>If you're using some other framework that is also filter-based, then you need to make |             <para>If you're using some other framework that is also filter-based, then you need to | ||||||
|         sure that the Spring Security filters come first. This enables the |                 make sure that the Spring Security filters come first. This enables the | ||||||
|           <classname>SecurityContextHolder</classname> to be populated in time for use by the other |                 <classname>SecurityContextHolder</classname> to be populated in time for use by the | ||||||
|         filters. Examples are the use of SiteMesh to decorate your web pages or a web framework like |                 other filters. Examples are the use of SiteMesh to decorate your web pages or a web | ||||||
|         Wicket which uses a filter to handle its requests. </para> |                 framework like Wicket which uses a filter to handle its requests. </para> | ||||||
|         </section> |         </section> | ||||||
|     </section> |     </section> | ||||||
| <!-- |     <!-- | ||||||
|   <section xml:id="taglib"> |   <section xml:id="taglib"> | ||||||
|     <info> |     <info> | ||||||
|       <title>Tag Libraries</title> |       <title>Tag Libraries</title> | ||||||
|  |  | ||||||
|  | @ -1,7 +1,12 @@ | ||||||
| <chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="x509"> | <chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="x509"> | ||||||
|     <info><title>X.509 Authentication</title></info> |     <info> | ||||||
|  |         <title>X.509 Authentication</title> | ||||||
|  |     </info> | ||||||
| 
 | 
 | ||||||
|     <section xml:id="x509-overview"><info><title>Overview</title></info> |     <section xml:id="x509-overview"> | ||||||
|  |         <info> | ||||||
|  |             <title>Overview</title> | ||||||
|  |         </info> | ||||||
| 
 | 
 | ||||||
|         <para>The most common use of X.509 certificate authentication is in verifying the identity |         <para>The most common use of X.509 certificate authentication is in verifying the identity | ||||||
|             of a server when using SSL, most commonly when using HTTPS from a browser. The browser |             of a server when using SSL, most commonly when using HTTPS from a browser. The browser | ||||||
|  | @ -10,37 +15,46 @@ | ||||||
|             maintains.</para> |             maintains.</para> | ||||||
|         <para>You can also use SSL with <quote>mutual authentication</quote>; the server will then |         <para>You can also use SSL with <quote>mutual authentication</quote>; the server will then | ||||||
|             request a valid certificate from the client as part of the SSL handshake. The server |             request a valid certificate from the client as part of the SSL handshake. The server | ||||||
|             will authenticate the client by checking that its certificate is signed by an |             will authenticate the client by checking that its certificate is signed by an acceptable | ||||||
|             acceptable authority. If a valid certificate has been provided, it can be obtained |             authority. If a valid certificate has been provided, it can be obtained through the | ||||||
|             through the servlet API in an application. Spring Security X.509 module extracts the |             servlet API in an application. Spring Security X.509 module extracts the certificate | ||||||
|             certificate using a filter. It maps the certificate to an application user and loads that |             using a filter. It maps the certificate to an application user and loads that user's set | ||||||
|             user's set of granted authorities for use with the standard Spring Security infrastructure.</para> |             of granted authorities for use with the standard Spring Security infrastructure.</para> | ||||||
|         <para>You should be familiar with using certificates and setting up client authentication |         <para>You should be familiar with using certificates and setting up client authentication | ||||||
|             for your servlet container before attempting to use it with Spring Security. Most of the |             for your servlet container before attempting to use it with Spring Security. Most of the | ||||||
|             work is in creating and installing suitable certificates and keys. For example, if |             work is in creating and installing suitable certificates and keys. For example, if | ||||||
|             you're using Tomcat then read the instructions here <uri xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tomcat.apache.org/tomcat-6.0-doc/ssl-howto.html">http://tomcat.apache.org/tomcat-6.0-doc/ssl-howto.html</uri>. It's important that |             you're using Tomcat then read the instructions here <uri | ||||||
|             you get this working before trying it out with Spring Security</para> |             xmlns:xlink="http://www.w3.org/1999/xlink" | ||||||
|  |             xlink:href="http://tomcat.apache.org/tomcat-6.0-doc/ssl-howto.html" | ||||||
|  |             >http://tomcat.apache.org/tomcat-6.0-doc/ssl-howto.html</uri>. It's important that you | ||||||
|  |             get this working before trying it out with Spring Security</para> | ||||||
|     </section> |     </section> | ||||||
|     <section><info><title>Adding X.509 Authentication to Your Web Application</title></info> |     <section> | ||||||
|  |         <info> | ||||||
|  |             <title>Adding X.509 Authentication to Your Web Application</title> | ||||||
|  |         </info> | ||||||
| 
 | 
 | ||||||
|         <para> Enabling X.509 client authentication is very straightforward. Just add the <literal><x509/></literal> element to your http security namespace configuration. <programlisting> |         <para> Enabling X.509 client authentication is very straightforward. Just add the | ||||||
|  |             <literal><x509/></literal> element to your http security namespace configuration. | ||||||
|  |             <programlisting> | ||||||
| <http> | <http> | ||||||
|  ... |  ... | ||||||
|     <x509 subject-principal-regex="CN=(.*?)," user-service-ref="userService"/> |     <x509 subject-principal-regex="CN=(.*?)," user-service-ref="userService"/> | ||||||
|  ... |  ... | ||||||
| </http> | </http> | ||||||
|             </programlisting> The element has two optional attributes: <itemizedlist> |             </programlisting> | ||||||
|  |             The element has two optional attributes: <itemizedlist> | ||||||
|             <listitem> |             <listitem> | ||||||
|                 <para><literal>subject-principal-regex</literal>. The regular expression used to |                 <para><literal>subject-principal-regex</literal>. The regular expression used to | ||||||
|                     extract a username from the certificate's subject name. The default value is |                     extract a username from the certificate's subject name. The default value is | ||||||
|                         shown above. This is the username which will be passed to the <interfacename>UserDetailsService</interfacename> to load the authorities for the |                     shown above. This is the username which will be passed to the | ||||||
|                     user.</para> |                     <interfacename>UserDetailsService</interfacename> to load the authorities for | ||||||
|  |                     the user.</para> | ||||||
|             </listitem> |             </listitem> | ||||||
|             <listitem> |             <listitem> | ||||||
|                 <para><literal>user-service-ref</literal>. This is the bean Id of the |                 <para><literal>user-service-ref</literal>. This is the bean Id of the | ||||||
|                             <interfacename>UserDetailsService</interfacename> to be used with X.509. |                     <interfacename>UserDetailsService</interfacename> to be used with X.509. It | ||||||
|                         It isn't needed if there is only one defined in your application |                     isn't needed if there is only one defined in your application context.</para> | ||||||
|                     context.</para> |  | ||||||
|             </listitem> |             </listitem> | ||||||
|             </itemizedlist> The <literal>subject-principal-regex</literal> should contain a single |             </itemizedlist> The <literal>subject-principal-regex</literal> should contain a single | ||||||
|             group. For example the default expression "CN=(.*?)," matches the common name field. So |             group. For example the default expression "CN=(.*?)," matches the common name field. So | ||||||
|  | @ -54,19 +68,19 @@ | ||||||
|             authentication with other options such as a form-based login. </para> |             authentication with other options such as a form-based login. </para> | ||||||
|     </section> |     </section> | ||||||
|     <section xml:id="x509-ssl-config"> |     <section xml:id="x509-ssl-config"> | ||||||
|         <info><title>Setting up SSL in Tomcat</title></info> |         <info> | ||||||
|  |             <title>Setting up SSL in Tomcat</title> | ||||||
|  |         </info> | ||||||
| 
 | 
 | ||||||
|         <para>There are some pre-generated certificates in the |         <para>There are some pre-generated certificates in the | ||||||
|             <filename>samples/certificate</filename> directory in the Spring Security project. |             <filename>samples/certificate</filename> directory in the Spring Security project. You | ||||||
|             You can use these to enable SSL for testing if you don't want to generate your own. The file |             can use these to enable SSL for testing if you don't want to generate your own. The file | ||||||
|             <filename>server.jks</filename> contains the server certificate, private key and the |             <filename>server.jks</filename> contains the server certificate, private key and the | ||||||
|             issuing certificate authority certificate. There are also some client certificate files |             issuing certificate authority certificate. There are also some client certificate files | ||||||
|             for the users from the sample applications. You can install these in your browser to enable |             for the users from the sample applications. You can install these in your browser to | ||||||
|             SSL client authentication. |             enable SSL client authentication. </para> | ||||||
|         </para> |         <para> To run tomcat with SSL support, drop the <filename>server.jks</filename> file into | ||||||
|         <para> |             the tomcat <filename>conf</filename> directory and add the following connector to the | ||||||
|             To run tomcat with SSL support, drop the <filename>server.jks</filename> file into the |  | ||||||
|             tomcat <filename>conf</filename> directory and add the following connector to the |  | ||||||
|             <filename>server.xml</filename> file |             <filename>server.xml</filename> file | ||||||
|             <programlisting> |             <programlisting> | ||||||
| <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" scheme="https" secure="true" | <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" scheme="https" secure="true" | ||||||
|  | @ -77,10 +91,10 @@ | ||||||
|             truststoreType="JKS" truststorePass="password" |             truststoreType="JKS" truststorePass="password" | ||||||
| /> | /> | ||||||
|                 </programlisting> |                 </programlisting> | ||||||
|             <parameter>clientAuth</parameter> can also be set to <parameter>want</parameter> if you still |             <parameter>clientAuth</parameter> can also be set to <parameter>want</parameter> if you | ||||||
|             want SSL connections to succeed even if the client doesn't provide a certificate. |             still want SSL connections to succeed even if the client doesn't provide a certificate. | ||||||
|             Clients which don't present a certificate won't be able to access any objects secured by |             Clients which don't present a certificate won't be able to access any objects secured by | ||||||
|             Spring Security unless you use a non-X.509 authentication mechanism, such as form authentication. |             Spring Security unless you use a non-X.509 authentication mechanism, such as form | ||||||
|         </para> |             authentication. </para> | ||||||
|     </section> |     </section> | ||||||
| </chapter> | </chapter> | ||||||
		Loading…
	
		Reference in New Issue