Manual formatting.
This commit is contained in:
		
							parent
							
								
									ae8027fa47
								
							
						
					
					
						commit
						90caf1bb37
					
				|  | @ -8,17 +8,17 @@ | |||
|             <title>Overview</title> | ||||
|         </info> | ||||
|         <para>It's generally considered good security practice to adopt a | ||||
|                 <quote>deny-by-default</quote> where you explicitly specify what is allowed and | ||||
|             disallow everything else. Defining what is accessible to unauthenticated users is a | ||||
|             similar situation, particularly for web applications. Many sites require that users must | ||||
|             be authenticated for anything other than a few URLs (for example the home and login | ||||
|             pages). In this case it is easiest to define access configuration attributes for these | ||||
|             specific URLs rather than have for every secured resource. Put differently, sometimes it | ||||
|             is nice to say <literal>ROLE_SOMETHING</literal> is required by default and only allow | ||||
|             certain exceptions to this rule, such as for login, logout and home pages of an | ||||
|             application. You could also omit these pages from the filter chain entirely, thus | ||||
|             bypassing the access control checks, but this may be undesirable for other reasons, | ||||
|             particularly if the pages behave differently for authenticated users.</para> | ||||
|             <quote>deny-by-default</quote> where you explicitly specify what is allowed and disallow | ||||
|             everything else. Defining what is accessible to unauthenticated users is a similar | ||||
|             situation, particularly for web applications. Many sites require that users must be | ||||
|             authenticated for anything other than a few URLs (for example the home and login pages). | ||||
|             In this case it is easiest to define access configuration attributes for these specific | ||||
|             URLs rather than have for every secured resource. Put differently, sometimes it is nice | ||||
|             to say <literal>ROLE_SOMETHING</literal> is required by default and only allow certain | ||||
|             exceptions to this rule, such as for login, logout and home pages of an application. You | ||||
|             could also omit these pages from the filter chain entirely, thus bypassing the access | ||||
|             control checks, but this may be undesirable for other reasons, particularly if the pages | ||||
|             behave differently for authenticated users.</para> | ||||
|         <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 | ||||
|             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. | ||||
|             <literal>AnonymousAuthenticationToken</literal> is an implementation of | ||||
|             <interfacename>Authentication</interfacename>, and stores the | ||||
|                 <interfacename>GrantedAuthority</interfacename>s which apply to the anonymous | ||||
|             principal. There is a corresponding <literal>AnonymousAuthenticationProvider</literal>, | ||||
|             which is chained into the <literal>ProviderManager</literal> so that | ||||
|             <interfacename>GrantedAuthority</interfacename>s which apply to the anonymous principal. | ||||
|             There is a corresponding <literal>AnonymousAuthenticationProvider</literal>, which is | ||||
|             chained into the <literal>ProviderManager</literal> so that | ||||
|             <literal>AnonymousAuthenticationToken</literal>s are accepted. Finally, there is an | ||||
|                 <classname>AnonymousAuthenticationFilter</classname>, which is chained after the | ||||
|             normal authentication mechanisms and automatically adds an | ||||
|             <classname>AnonymousAuthenticationFilter</classname>, which is chained after the normal | ||||
|             authentication mechanisms and automatically adds an | ||||
|             <literal>AnonymousAuthenticationToken</literal> to the | ||||
|             <classname>SecurityContextHolder</classname> if there is no existing | ||||
|                 <interfacename>Authentication</interfacename> held there. The definition of the | ||||
|             filter and authentication provider appears as follows:</para> | ||||
|         <para> | ||||
|             <programlisting> | ||||
|             <interfacename>Authentication</interfacename> held there. The definition of the filter | ||||
|             and authentication provider appears as follows:</para> | ||||
|         <para> <programlisting> | ||||
| <![CDATA[ | ||||
| <bean id="anonymousAuthFilter" | ||||
|     class="org.springframework.security.web.authentication.AnonymousAuthenticationFilter"> | ||||
|  | @ -67,32 +66,30 @@ | |||
|     class="org.springframework.security.authentication.AnonymousAuthenticationProvider"> | ||||
|   <property name="key" value="foobar"/> | ||||
| </bean>]]> | ||||
|     </programlisting> | ||||
|         </para> | ||||
|     </programlisting> </para> | ||||
|         <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 | ||||
|                     of the <literal>key</literal> property should not be regarded as providing any | ||||
|                     real security here. It is merely a book-keeping exercise. If you are sharing a | ||||
|             so that tokens created by the former are accepted by the latter<footnote> | ||||
|             <para>The use of the <literal>key</literal> property should not be regarded as providing | ||||
|                 any real security here. It is merely a book-keeping exercise. If you are sharing a | ||||
|                 <classname>ProviderManager</classname> which contains an | ||||
|                         <classname>AnonymousAuthenticationProvider</classname> in a scenario where | ||||
|                     it is possible for an authenticating client to construct the | ||||
|                         <interfacename>Authentication</interfacename> object (such as with RMI | ||||
|                     invocations), then a malicious client could submit an | ||||
|                         <classname>AnonymousAuthenticationToken</classname> which it had created | ||||
|                     itself (with chosen username and authority list). If the <literal>key</literal> | ||||
|                     is guessable or can be found out, then the token would be accepted by the | ||||
|                     anonymous provider. This isn't a problem with normal usage but if you are using | ||||
|                     RMI you would be best to use a customized <classname>ProviderManager</classname> | ||||
|                     which omits the anonymous provider rather than sharing the one you use for your | ||||
|                     HTTP authentication mechanisms.</para></footnote>. The | ||||
|                 <literal>userAttribute</literal> is expressed in the form of | ||||
|                 <classname>AnonymousAuthenticationProvider</classname> in a scenario where it is | ||||
|                 possible for an authenticating client to construct the | ||||
|                 <interfacename>Authentication</interfacename> object (such as with RMI invocations), | ||||
|                 then a malicious client could submit an | ||||
|                 <classname>AnonymousAuthenticationToken</classname> which it had created itself | ||||
|                 (with chosen username and authority list). If the <literal>key</literal> is | ||||
|                 guessable or can be found out, then the token would be accepted by the anonymous | ||||
|                 provider. This isn't a problem with normal usage but if you are using RMI you would | ||||
|                 be best to use a customized <classname>ProviderManager</classname> which omits the | ||||
|                 anonymous provider rather than sharing the one you use for your HTTP authentication | ||||
|                 mechanisms.</para> | ||||
|             </footnote>. The <literal>userAttribute</literal> is expressed in the form of | ||||
|             <literal>usernameInTheAuthenticationToken,grantedAuthority[,grantedAuthority]</literal>. | ||||
|             This is the same syntax as used after the equals sign for | ||||
|             <literal>InMemoryDaoImpl</literal>'s <literal>userMap</literal> property.</para> | ||||
|         <para>As explained earlier, the benefit of anonymous authentication is that all URI patterns | ||||
|             can have security applied to them. For example:</para> | ||||
|         <para> | ||||
|             <programlisting> | ||||
|         <para> <programlisting> | ||||
| <![CDATA[ | ||||
| <bean id="filterSecurityInterceptor" | ||||
|     class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor"> | ||||
|  | @ -108,8 +105,7 @@ | |||
|     </security:filter-security-metadata-source>" + | ||||
|   </property> | ||||
| </bean>]]> | ||||
|     </programlisting> | ||||
|         </para> | ||||
|     </programlisting> </para> | ||||
|     </section> | ||||
|     <section xml:id="anonymous-auth-trust-resolver"> | ||||
|         <title><interfacename>AuthenticationTrustResolver</interfacename></title> | ||||
|  | @ -131,12 +127,12 @@ | |||
|             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 | ||||
|             xlink:href="#authz-authenticated-voter">authorization chapter</link>. It uses an | ||||
|                 <interfacename>AuthenticationTrustResolver</interfacename> to process this | ||||
|             particular configuration attribute and grant access to anonymous users. The | ||||
|                 <classname>AuthenticatedVoter</classname> approach is more powerful, since it allows | ||||
|             you to differentiate between anonymous, remember-me and fully-authenticated users. If | ||||
|             you don't need this functionality though, then you can stick with | ||||
|                 <literal>ROLE_ANONYMOUS</literal>, which will be processed by Spring Security's | ||||
|             standard <classname>RoleVoter</classname>. </para> | ||||
|             <interfacename>AuthenticationTrustResolver</interfacename> to process this particular | ||||
|             configuration attribute and grant access to anonymous users. The | ||||
|             <classname>AuthenticatedVoter</classname> approach is more powerful, since it allows you | ||||
|             to differentiate between anonymous, remember-me and fully-authenticated users. If you | ||||
|             don't need this functionality though, then you can stick with | ||||
|             <literal>ROLE_ANONYMOUS</literal>, which will be processed by Spring Security's standard | ||||
|             <classname>RoleVoter</classname>. </para> | ||||
|     </section> | ||||
| </chapter> | ||||
|  |  | |||
|  | @ -4,16 +4,17 @@ | |||
|     <info> | ||||
|         <title>Security Database Schema</title> | ||||
|     </info> | ||||
|   <para> There are various database schema used by the framework and this appendix provides a single | ||||
|     reference point to them all. You only need to provide the tables for the areas of functonality | ||||
|     you require. </para> | ||||
|     <para> There are various database schema used by the framework and this appendix provides a | ||||
|         single reference point to them all. You only need to provide the tables for the areas of | ||||
|         functonality you require. </para> | ||||
|     <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> | ||||
|     <section> | ||||
|         <title>User Schema</title> | ||||
|     <para> The standard JDBC implementation of the <interfacename>UserDetailsService</interfacename> | ||||
|         (<classname>JdbcDaoImpl</classname>) requires tables to load the password, account status | ||||
|       (enabled or disabled) and a list of authorities (roles) for the user. | ||||
|         <para> The standard JDBC implementation of the | ||||
|             <interfacename>UserDetailsService</interfacename> (<classname>JdbcDaoImpl</classname>) | ||||
|             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"> | ||||
|   create table users( | ||||
|       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" | ||||
|             >ACL</link> implementation. <orderedlist> | ||||
|             <listitem> | ||||
|           <para><literal>acl_sid</literal> stores the security identities recognised by the ACL | ||||
|             system. These can be unique principals or authorities which may apply to multiple | ||||
|             principals.</para> | ||||
|                 <para><literal>acl_sid</literal> stores the security identities recognised by the | ||||
|                     ACL system. These can be unique principals or authorities which may apply to | ||||
|                     multiple principals.</para> | ||||
|             </listitem> | ||||
|             <listitem> | ||||
|           <para><literal>acl_class</literal> defines the domain object types to which ACLs apply. | ||||
|             The <literal>class</literal> column stores the Java class name of the object. </para> | ||||
|                 <para><literal>acl_class</literal> defines the domain object types to which ACLs | ||||
|                     apply. The <literal>class</literal> column stores the Java class name of the | ||||
|                     object. </para> | ||||
|             </listitem> | ||||
|             <listitem> | ||||
|           <para><literal>acl_object_identity</literal> stores the object identity definitions of | ||||
|             specific domai objects.</para> | ||||
|                 <para><literal>acl_object_identity</literal> stores the object identity definitions | ||||
|                     of specific domai objects.</para> | ||||
|             </listitem> | ||||
|             <listitem> | ||||
|           <para><literal>acl_entry</literal> stores the ACL permissions which apply to a specific | ||||
|             object identity and security identity.</para> | ||||
|                 <para><literal>acl_entry</literal> stores the ACL permissions which apply to a | ||||
|                     specific object identity and security identity.</para> | ||||
|             </listitem> | ||||
|             </orderedlist></para> | ||||
|         <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 | ||||
|       it has created a new row in the <literal>acl_sid</literal> or <literal>acl_class</literal> | ||||
|       tables. It has two properties which define the SQL needed to retrieve these values | ||||
|         <literal>classIdentityQuery</literal> and <literal>sidIdentityQuery</literal>. Both of these | ||||
|       default to <literal>call identity()</literal></para> | ||||
|             identities. The <literal>JdbcMutableAclService</literal> has to be able to retrieve | ||||
|             these when it has created a new row in the <literal>acl_sid</literal> or | ||||
|             <literal>acl_class</literal> tables. It has two properties which define the SQL needed | ||||
|             to retrieve these values <literal>classIdentityQuery</literal> and | ||||
|             <literal>sidIdentityQuery</literal>. Both of these default to <literal>call | ||||
|             identity()</literal></para> | ||||
|         <section> | ||||
|             <title>Hypersonic SQL</title> | ||||
|       <para>The default schema works with the embedded HSQLDB database that is used in unit tests | ||||
|         within the | ||||
|             <para>The default schema works with the embedded HSQLDB database that is used in unit | ||||
|                 tests within the | ||||
|                 framework.<programlisting xml:id="dbschema-acl-hsql"> | ||||
| create table acl_sid ( | ||||
|   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) | ||||
|       references acl_object_identity(id), | ||||
|   constraint foreign_fk_5 foreign key(sid) references acl_sid(id)); | ||||
| </programlisting> | ||||
|         </para> | ||||
| </programlisting> </para> | ||||
|                 <para>You will have to set the <literal>classIdentityQuery</literal> and | ||||
|                     <literal>sidIdentityQuery</literal> properties of | ||||
|             <classname>JdbcMutableAclService</classname> to the following values, respectively: <itemizedlist> | ||||
|                     <classname>JdbcMutableAclService</classname> to the following values, | ||||
|                     respectively: <itemizedlist> | ||||
|                     <listitem> | ||||
|                         <para><literal>select currval(pg_get_serial_sequence('acl_class', | ||||
|                             'id'))</literal></para> | ||||
|  |  | |||
|  | @ -4,37 +4,37 @@ | |||
|     <info> | ||||
|         <title>The Security Namespace</title> | ||||
|     </info> | ||||
|   <para> This appendix provides a reference to the elements available in the security namespace and | ||||
|     information on the underlying beans they create (a knowledge of the individual classes and how | ||||
|     they work together is assumed - you can find more information in the project Javadoc and | ||||
|     elsewhere in this document). If you haven't used the namespace before, please read the <link | ||||
|       xlink:href="#ns-config">introductory chapter</link> on namespace configuration, as this is | ||||
|     intended as a supplement to the information there. Using a good quality XML editor while editing | ||||
|     a configuration based on the schema is recommended as this will provide contextual information | ||||
|     on which elements and attributes are available as well as comments explaining their purpose. The | ||||
|     namespace is written in <link xlink:href="http://www.relaxng.org/">RELAX NG</link> Compact | ||||
|     format and later converted into an XSD schema. If you are familiar with this format, you may | ||||
|     wish to examine the <link | ||||
|     <para> This appendix provides a reference to the elements available in the security namespace | ||||
|         and information on the underlying beans they create (a knowledge of the individual classes | ||||
|         and how they work together is assumed - you can find more information in the project Javadoc | ||||
|         and elsewhere in this document). If you haven't used the namespace before, please read the | ||||
|         <link xlink:href="#ns-config">introductory chapter</link> on namespace configuration, as | ||||
|         this is intended as a supplement to the information there. Using a good quality XML editor | ||||
|         while editing a configuration based on the schema is recommended as this will provide | ||||
|         contextual information on which elements and attributes are available as well as comments | ||||
|         explaining their purpose. The namespace is written in <link | ||||
|         xlink:href="http://www.relaxng.org/">RELAX NG</link> Compact format and later converted into | ||||
|         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" | ||||
|         >schema file</link> directly.</para> | ||||
|     <section xml:id="nsa-http"> | ||||
|         <title>Web Application Security - the <literal><http></literal> Element</title> | ||||
|     <para> The <literal><http></literal> element encapsulates the security configuration for | ||||
|       the web layer of your application. It creates a <classname>FilterChainProxy</classname> bean | ||||
|       named "springSecurityFilterChain" which 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 | ||||
|           the mapping from your <literal>web.xml</literal></para> | ||||
|         <para> The <literal><http></literal> element encapsulates the security configuration | ||||
|             for the web layer of your application. It creates a | ||||
|             <classname>FilterChainProxy</classname> bean named "springSecurityFilterChain" which | ||||
|             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 the mapping from your <literal>web.xml</literal></para> | ||||
|             </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 | ||||
|       filters are fixed (see <link xlink:href="#filter-stack">the filter order table</link> in the | ||||
|       namespace introduction), removing a common source of errors with previous versions of the | ||||
|       framework when users had to configure the filter chain explicitly in | ||||
|         the<classname>FilterChainProxy</classname> bean. You can, of course, still do this if you | ||||
|       need full control of the configuration. </para> | ||||
|             depending on the attributes child elements which are present. The positions of the | ||||
|             standard filters are fixed (see <link xlink:href="#filter-stack">the filter order | ||||
|             table</link> in the namespace introduction), removing a common source of errors with | ||||
|             previous versions of the framework when users had to configure the filter chain | ||||
|             explicitly in the<classname>FilterChainProxy</classname> bean. You can, of course, still | ||||
|             do this if you need full control of the configuration. </para> | ||||
|         <para> All filters which require a reference to the | ||||
|         <interfacename>AuthenticationManager</interfacename> will be automatically injected with the | ||||
|       internal instance created by the namespace configuration (see the <link | ||||
|             <interfacename>AuthenticationManager</interfacename> will be automatically injected with | ||||
|             the internal instance created by the namespace configuration (see the <link | ||||
|             xlink:href="#ns-auth-manager"> introductory chapter</link> for more on the | ||||
|             <interfacename>AuthenticationManager</interfacename>). </para> | ||||
|         <para> The <literal><http></literal> namespace block always creates an | ||||
|  | @ -48,48 +48,53 @@ | |||
|                 properties on the core filters. </para> | ||||
|             <section xml:id="nsa-servlet-api-provision"> | ||||
|                 <title><literal>servlet-api-provision</literal></title> | ||||
|         <para> Provides versions of <literal>HttpServletRequest</literal> security methods such as | ||||
|             <literal>isUserInRole()</literal> and <literal>getPrincipal()</literal> which are | ||||
|           implemented by adding a <classname>SecurityContextHolderAwareRequestFilter</classname> | ||||
|           bean to the stack. Defaults to "true". </para> | ||||
|                 <para> Provides versions of <literal>HttpServletRequest</literal> security methods | ||||
|                     such as <literal>isUserInRole()</literal> and <literal>getPrincipal()</literal> | ||||
|                     which are implemented by adding a | ||||
|                     <classname>SecurityContextHolderAwareRequestFilter</classname> bean to the | ||||
|                     stack. Defaults to "true". </para> | ||||
|             </section> | ||||
|             <section xml:id="nsa-path-type"> | ||||
|         <title><literal>path-type</literal></title> | ||||
|         <para> Controls whether URL patterns are interpreted as ant paths (the default) or regular | ||||
|           expressions. In practice this sets a particular <interfacename>UrlMatcher</interfacename> | ||||
|           instance on the <classname>FilterChainProxy</classname>. </para> | ||||
|       </section> | ||||
|       <section xml:id="nsa-lowercase-comparisons"> | ||||
|         <title><literal>lowercase-comparisons</literal></title> | ||||
|         <para> Whether test URLs should be converted to lower case prior to comparing with defined | ||||
|           path patterns. If unspecified, defaults to "true" </para> | ||||
|                 <title><literal>request-matcher</literal></title> | ||||
|                 <para> Defines the <interfacename>RequestMatcher</interfacename> strategy used in | ||||
|                     the <classname>FilterChainProxy</classname> and the beans created by the | ||||
|                     <literal>intercept-url</literal> to match incoming requests. Options are | ||||
|                     currently <literal>ant</literal>, <literal>regex</literal> and | ||||
|                     <literal>ciRegex</literal>, for ant, regular-expression and case-insensitive | ||||
|                     regular-expression repsectively. A separate instance is created for each | ||||
|                     <literal>intercept-url</literal> element using its <literal>pattern</literal> | ||||
|                     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 xml:id="nsa-realm"> | ||||
|                 <title><literal>realm</literal></title> | ||||
|         <para> Sets the realm name used for basic authentication (if enabled). Corresponds to the | ||||
|             <literal>realmName</literal> property on | ||||
|                 <para> Sets the realm name used for basic authentication (if enabled). Corresponds | ||||
|                     to the <literal>realmName</literal> property on | ||||
|                     <classname>BasicAuthenticationEntryPoint</classname>. </para> | ||||
|             </section> | ||||
|             <section xml:id="nsa-entry-point-ref"> | ||||
|                 <title><literal>entry-point-ref</literal></title> | ||||
|         <para> Normally the <interfacename>AuthenticationEntryPoint</interfacename> used will be set | ||||
|           depending on which authentication mechanisms have been configured. This attribute allows | ||||
|           this behaviour to be overridden by defining a customized | ||||
|             <interfacename>AuthenticationEntryPoint</interfacename> bean which will start the | ||||
|           authentication process. </para> | ||||
|                 <para> Normally the <interfacename>AuthenticationEntryPoint</interfacename> used | ||||
|                     will be set depending on which authentication mechanisms have been configured. | ||||
|                     This attribute allows this behaviour to be overridden by defining a customized | ||||
|                     <interfacename>AuthenticationEntryPoint</interfacename> bean which will start | ||||
|                     the authentication process. </para> | ||||
|             </section> | ||||
|             <section xml:id="nsa-access-decision-manager-ref"> | ||||
|                 <title><literal>access-decision-manager-ref</literal></title> | ||||
|                 <para> Optional attribute specifying the ID of the | ||||
|             <interfacename>AccessDecisionManager</interfacename> implementation which should be used | ||||
|           for authorizing HTTP requests. By default an <classname>AffirmativeBased</classname> | ||||
|           implementation is used for with a <classname>RoleVoter</classname> and an | ||||
|                     <interfacename>AccessDecisionManager</interfacename> implementation which should | ||||
|                     be used for authorizing HTTP requests. By default an | ||||
|                     <classname>AffirmativeBased</classname> implementation is used for with a | ||||
|                     <classname>RoleVoter</classname> and an | ||||
|                     <classname>AuthenticatedVoter</classname>. </para> | ||||
|             </section> | ||||
|             <section xml:id="nsa-access-denied-page"> | ||||
|                 <title><literal>access-denied-page</literal></title> | ||||
|         <para> Deprecated in favour of the <literal>access-denied-handler</literal> child element. | ||||
|         </para> | ||||
|                 <para> Deprecated in favour of the <literal>access-denied-handler</literal> child | ||||
|                     element. </para> | ||||
|             </section> | ||||
|             <section xml:id="nsa-once-per-request"> | ||||
|                 <title><literal>once-per-request</literal></title> | ||||
|  | @ -98,17 +103,18 @@ | |||
|             </section> | ||||
|             <section xml:id="create-session"> | ||||
|                 <title><literal>create-session</literal></title> | ||||
|         <para> Controls the eagerness with which an HTTP session is created. If not set, defaults to | ||||
|           "ifRequired". Other options are "always" and "never". The setting of this attribute affect | ||||
|           the <literal>allowSessionCreation</literal> and | ||||
|                 <para> Controls the eagerness with which an HTTP session is created. If not set, | ||||
|                     defaults to "ifRequired". Other options are "always" and "never". The setting of | ||||
|                     this attribute affect the <literal>allowSessionCreation</literal> and | ||||
|                     <literal>forceEagerSessionCreation</literal> properties of | ||||
|                     <classname>HttpSessionContextIntegrationFilter</classname>. | ||||
|             <literal>allowSessionCreation</literal> will always be true unless this attribute is set | ||||
|           to "never". <literal>forceEagerSessionCreation</literal> is "false" unless it is set to | ||||
|           "always". So the default configuration allows session creation but does not force it. The | ||||
|           exception is if concurrent session control is enabled, when | ||||
|             <literal>forceEagerSessionCreation</literal> will be set to true, regardless of what the | ||||
|           setting is here. Using "never" would then cause an exception during the initialization of | ||||
|                     <literal>allowSessionCreation</literal> will always be true unless this | ||||
|                     attribute is set to "never". <literal>forceEagerSessionCreation</literal> is | ||||
|                     "false" unless it is set to "always". So the default configuration allows | ||||
|                     session creation but does not force it. The exception is if concurrent session | ||||
|                     control is enabled, when <literal>forceEagerSessionCreation</literal> will be | ||||
|                     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> | ||||
|             </section> | ||||
|         </section> | ||||
|  | @ -117,89 +123,93 @@ | |||
|             <para> This element allows you to set the <literal>errorPage</literal> property for the | ||||
|                 default <interfacename>AccessDeniedHandler</interfacename> used by the | ||||
|                 <classname>ExceptionTranslationFilter</classname>, (using the | ||||
|           <literal>error-page</literal> attribute, or to supply your own implementation using the | ||||
|           <literal>ref</literal> attribute. This is discussed in more detail in the section on <link | ||||
|           xlink:href="#access-denied-handler">the | ||||
|                 <literal>error-page</literal> attribute, or to supply your own implementation using | ||||
|                 the <literal>ref</literal> attribute. This is discussed in more detail in the | ||||
|                 section on <link xlink:href="#access-denied-handler">the | ||||
|                 <classname>ExceptionTranslationFilter</classname></link>.</para> | ||||
|         </section> | ||||
|         <section> | ||||
|             <title>The <literal><intercept-url></literal> Element</title> | ||||
|             <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 | ||||
|           <interfacename>FilterInvocationSecurityMetadataSource</interfacename> used by the | ||||
|           <classname>FilterSecurityInterceptor</classname> and to exclude particular patterns from | ||||
|         the filter chain entirely (by setting the attribute <literal>filters="none"</literal>). It | ||||
|         is also responsible for configuring a <classname>ChannelAuthenticationFilter</classname> if | ||||
|         particular URLs need to be accessed by HTTPS, for example. When matching the specified | ||||
|         patterns against an 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 | ||||
|                 interested in and to configure how they should be handled. It is used to construct | ||||
|                 the <interfacename>FilterInvocationSecurityMetadataSource</interfacename> used by | ||||
|                 the <classname>FilterSecurityInterceptor</classname> and to exclude particular | ||||
|                 patterns from the filter chain entirely (by setting the attribute | ||||
|                 <literal>filters="none"</literal>). It is also responsible for configuring a | ||||
|                 <classname>ChannelAuthenticationFilter</classname> if particular URLs need to be | ||||
|                 accessed by HTTPS, for example. When matching the specified patterns against an | ||||
|                 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> | ||||
|             <section xml:id="nsa-pattern"> | ||||
|                 <title><literal>pattern</literal></title> | ||||
|                 <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 | ||||
|           to ant path syntax. </para> | ||||
|                     <literal>path-type</literal> attribute from the containing http element, so will | ||||
|                     default to ant path syntax. </para> | ||||
|             </section> | ||||
|             <section xml:id="nsa-method"> | ||||
|                 <title><literal>method</literal></title> | ||||
|         <para> The HTTP Method which will be used in combination with the pattern to match an | ||||
|           incoming request. If omitted, any method will match. If an identical pattern is specified | ||||
|           with and without a method, the method-specific match will take precedence.</para> | ||||
|                 <para> The HTTP Method which will be used in combination with the pattern to match | ||||
|                     an incoming request. If omitted, any method will match. If an identical pattern | ||||
|                     is specified with and without a method, the method-specific match will take | ||||
|                     precedence.</para> | ||||
|             </section> | ||||
|             <section xml:id="nsa-access"> | ||||
|                 <title><literal>access</literal></title> | ||||
|                 <para> Lists the access attributes which will be stored in the | ||||
|             <interfacename>FilterInvocationSecurityMetadataSource</interfacename> for the defined URL | ||||
|           pattern/method combination. This should be a comma-separated list of the security | ||||
|           configuration attributes (such as role names). </para> | ||||
|                     <interfacename>FilterInvocationSecurityMetadataSource</interfacename> for the | ||||
|                     defined URL pattern/method combination. This should be a comma-separated list of | ||||
|                     the security configuration attributes (such as role names). </para> | ||||
|             </section> | ||||
|             <section xml:id="nsa-requires-channel"> | ||||
|                 <title><literal>requires-channel</literal></title> | ||||
|         <para> Can be <quote>http</quote> or <quote>https</quote> depending on whether a particular | ||||
|           URL pattern should be accessed over HTTP or HTTPS respectively. Alternatively the value | ||||
|             <quote>any</quote> can be used when there is no preference. If this attribute is present | ||||
|           on any <literal><intercept-url></literal> element, then a | ||||
|             <classname>ChannelAuthenticationFilter</classname> will be added to the filter stack and | ||||
|           its additional dependencies added to the application | ||||
|                 <para> Can be <quote>http</quote> or <quote>https</quote> depending on whether a | ||||
|                     particular URL pattern should be accessed over HTTP or HTTPS respectively. | ||||
|                     Alternatively the value <quote>any</quote> can be used when there is no | ||||
|                     preference. If this attribute is present on any | ||||
|                     <literal><intercept-url></literal> element, then a | ||||
|                     <classname>ChannelAuthenticationFilter</classname> will be added to the filter | ||||
|                     stack and its additional dependencies added to the application | ||||
|                     context.<!--See the chapter on <link | ||||
|             xlink:href="#channel-security-config">channel security</link> for an example | ||||
|           configuration using traditional beans. --></para> | ||||
|         <para> If a <literal><port-mappings></literal> configuration is added, this will be | ||||
|           used to by the <classname>SecureChannelProcessor</classname> and | ||||
|             <classname>InsecureChannelProcessor</classname> beans to determine the ports used for | ||||
|           redirecting to HTTP/HTTPS. </para> | ||||
|                 <para> If a <literal><port-mappings></literal> configuration is added, this | ||||
|                     will be used to by the <classname>SecureChannelProcessor</classname> and | ||||
|                     <classname>InsecureChannelProcessor</classname> beans to determine the ports | ||||
|                     used for redirecting to HTTP/HTTPS. </para> | ||||
|             </section> | ||||
|             <section> | ||||
|                 <title><literal>filters</literal></title> | ||||
|         <para>Can only take the value <quote>none</quote>. This will cause any matching request to | ||||
|           bypass the Spring Security filter chain entirely. None of the rest of the | ||||
|             <literal><http></literal> configuration will have any effect on the request and there | ||||
|           will be no security context available for its duration. Access to secured methods during | ||||
|           the request will fail.</para> | ||||
|                 <para>Can only take the value <quote>none</quote>. This will cause any matching | ||||
|                     request to bypass the Spring Security filter chain entirely. None of the rest of | ||||
|                     the <literal><http></literal> configuration will have any effect on the | ||||
|                     request and there will be no security context available for its duration. Access | ||||
|                     to secured methods during the request will fail.</para> | ||||
|             </section> | ||||
|         </section> | ||||
|         <section> | ||||
|             <title>The <literal><port-mappings></literal> Element</title> | ||||
|       <para> By default, an instance of <classname>PortMapperImpl</classname> will be added to the | ||||
|         configuration for use in redirecting to secure and insecure URLs. This element can | ||||
|         optionally be used to override the default mappings which that class defines. Each child | ||||
|           <literal><port-mapping></literal> element defines a pair of HTTP:HTTPS ports. The | ||||
|         default mappings are 80:443 and 8080:8443. An example of overriding these can be found in | ||||
|         the <link xlink:href="#ns-requires-channel">namespace introduction</link>. </para> | ||||
|             <para> By default, an instance of <classname>PortMapperImpl</classname> will be added to | ||||
|                 the configuration for use in redirecting to secure and insecure URLs. This element | ||||
|                 can optionally be used to override the default mappings which that class defines. | ||||
|                 Each child <literal><port-mapping></literal> element defines a pair of | ||||
|                 HTTP:HTTPS ports. The default mappings are 80:443 and 8080:8443. An example of | ||||
|                 overriding these can be found in the <link xlink:href="#ns-requires-channel" | ||||
|                 >namespace introduction</link>. </para> | ||||
|         </section> | ||||
|         <section xml:id="nsa-form-login"> | ||||
|             <title>The <literal><form-login></literal> Element</title> | ||||
|             <para> Used to add an <classname>UsernamePasswordAuthenticationFilter</classname> to the | ||||
|                 filter stack and an <classname>LoginUrlAuthenticationEntryPoint</classname> to the | ||||
|         application context to provide authentication on demand. This will always take precedence | ||||
|         over other namespace-created entry points. If no attributes are supplied, a login page will | ||||
|         be generated automatically at the URL "/spring-security-login" <footnote> | ||||
|                 application context to provide authentication on demand. This will always take | ||||
|                 precedence over other namespace-created entry points. If no attributes are supplied, | ||||
|                 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 | ||||
|             production (where a view technology will have been chosen and can be used to render a | ||||
|             customized login page). The class | ||||
|               <classname>DefaultLoginPageGeneratingFilter</classname> is responsible for rendering | ||||
|             the login page and will provide login forms for both normal form login and/or OpenID if | ||||
|             required.</para> | ||||
|                     production (where a view technology will have been chosen and can be used to | ||||
|                     render a customized login page). The class | ||||
|                     <classname>DefaultLoginPageGeneratingFilter</classname> is responsible for | ||||
|                     rendering the login page and will provide login forms for both normal form login | ||||
|                     and/or OpenID if required.</para> | ||||
|                 </footnote> The behaviour can be customized using the following attributes. </para> | ||||
|             <section> | ||||
|                 <title><literal>login-page</literal></title> | ||||
|  | @ -211,108 +221,117 @@ | |||
|             <section> | ||||
|                 <title><literal>login-processing-url</literal></title> | ||||
|                 <para> Maps to the <literal>filterProcessesUrl</literal> property of | ||||
|             <classname>UsernamePasswordAuthenticationFilter</classname>. The default value is | ||||
|           "/j_spring_security_check". </para> | ||||
|                     <classname>UsernamePasswordAuthenticationFilter</classname>. The default value | ||||
|                     is "/j_spring_security_check". </para> | ||||
|             </section> | ||||
|             <section> | ||||
|                 <title><literal>default-target-url</literal></title> | ||||
|                 <para>Maps to the <literal>defaultTargetUrl</literal> property of | ||||
|             <classname>UsernamePasswordAuthenticationFilter</classname>. If not set, the default | ||||
|           value is "/" (the application root). A user will be taken to this URL after logging in, | ||||
|           provided they were not asked to login while attempting to access a secured resource, when | ||||
|           they will be taken to the originally requested URL. </para> | ||||
|                     <classname>UsernamePasswordAuthenticationFilter</classname>. If not set, the | ||||
|                     default value is "/" (the application root). A user will be taken to this URL | ||||
|                     after logging in, provided they were not asked to login while attempting to | ||||
|                     access a secured resource, when they will be taken to the originally requested | ||||
|                     URL. </para> | ||||
|             </section> | ||||
|             <section> | ||||
|                 <title><literal>always-use-default-target</literal></title> | ||||
|                 <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. | ||||
|           Maps to the <literal>alwaysUseDefaultTargetUrl</literal> property of | ||||
|             <classname>UsernamePasswordAuthenticationFilter</classname>. Default value is "false". | ||||
|         </para> | ||||
|                     <literal>default-target-url</literal>, regardless of how they arrived at the | ||||
|                     login page. Maps to the <literal>alwaysUseDefaultTargetUrl</literal> property of | ||||
|                     <classname>UsernamePasswordAuthenticationFilter</classname>. Default value is | ||||
|                     "false". </para> | ||||
|             </section> | ||||
|             <section> | ||||
|                 <title><literal>authentication-failure-url</literal></title> | ||||
|                 <para> Maps to the <literal>authenticationFailureUrl</literal> property of | ||||
|             <classname>UsernamePasswordAuthenticationFilter</classname>. Defines the URL the browser | ||||
|           will be redirected to on login failure. Defaults to "/spring_security_login?login_error", | ||||
|           which will be automatically handled by the automatic login page generator, re-rendering | ||||
|           the login page with an error message. </para> | ||||
|                     <classname>UsernamePasswordAuthenticationFilter</classname>. Defines the URL the | ||||
|                     browser will be redirected to on login failure. Defaults to | ||||
|                     "/spring_security_login?login_error", which will be automatically handled by the | ||||
|                     automatic login page generator, re-rendering the login page with an error | ||||
|                     message. </para> | ||||
|             </section> | ||||
|             <section> | ||||
|                 <title><literal>authentication-success-handler-ref</literal></title> | ||||
|         <para>This can be used as an alternative to <literal>default-target-url</literal> and | ||||
|             <literal>always-use-default-target</literal>, giving you full control over the | ||||
|           navigation flow after a successful authentication. The value should be he name of an | ||||
|             <interfacename>AuthenticationSuccessHandler</interfacename> bean in the application | ||||
|           context. </para> | ||||
|                 <para>This can be used as an alternative to <literal>default-target-url</literal> | ||||
|                     and <literal>always-use-default-target</literal>, giving you full control over | ||||
|                     the navigation flow after a successful authentication. The value should be he | ||||
|                     name of an <interfacename>AuthenticationSuccessHandler</interfacename> bean in | ||||
|                     the application context. </para> | ||||
|             </section> | ||||
|             <section> | ||||
|                 <title><literal>authentication-failure-handler-ref</literal></title> | ||||
|         <para>Can be used as an alternative to <literal>authentication-failure-url</literal>, giving | ||||
|           you full control over the navigation flow after an authentication failure. The value | ||||
|           should be he name of an <interfacename>AuthenticationFailureHandler</interfacename> bean | ||||
|           in the application context. </para> | ||||
|                 <para>Can be used as an alternative to | ||||
|                     <literal>authentication-failure-url</literal>, giving you full control over the | ||||
|                     navigation flow after an authentication failure. The value should be he name of | ||||
|                     an <interfacename>AuthenticationFailureHandler</interfacename> bean in the | ||||
|                     application context. </para> | ||||
|             </section> | ||||
|         </section> | ||||
|         <section xml:id="nsa-http-basic"> | ||||
|             <title>The <literal><http-basic></literal> Element</title> | ||||
|             <para> Adds a <classname>BasicAuthenticationFilter</classname> and | ||||
|           <classname>BasicAuthenticationEntryPoint</classname> to the configuration. The latter will | ||||
|         only be used as the configuration entry point if form-based login is not enabled. </para> | ||||
|                 <classname>BasicAuthenticationEntryPoint</classname> to the configuration. The | ||||
|                 latter will only be used as the configuration entry point if form-based login is not | ||||
|                 enabled. </para> | ||||
|         </section> | ||||
|         <section xml:id="nsa-remember-me"> | ||||
|             <title>The <literal><remember-me></literal> Element</title> | ||||
|       <para> Adds the <classname>RememberMeAuthenticationFilter</classname> to the stack. This in | ||||
|         turn will be configured with either a <classname>TokenBasedRememberMeServices</classname>, a | ||||
|           <classname>PersistentTokenBasedRememberMeServices</classname> or a user-specified bean | ||||
|         implementing <interfacename>RememberMeServices</interfacename> depending on the attribute | ||||
|         settings. </para> | ||||
|             <para> Adds the <classname>RememberMeAuthenticationFilter</classname> to the stack. This | ||||
|                 in turn will be configured with either a | ||||
|                 <classname>TokenBasedRememberMeServices</classname>, a | ||||
|                 <classname>PersistentTokenBasedRememberMeServices</classname> or a user-specified | ||||
|                 bean implementing <interfacename>RememberMeServices</interfacename> depending on the | ||||
|                 attribute settings. </para> | ||||
|             <section> | ||||
|                 <title><literal>data-source-ref</literal></title> | ||||
|         <para> If this is set, <classname>PersistentTokenBasedRememberMeServices</classname> will be | ||||
|           used and configured with a <classname>JdbcTokenRepositoryImpl</classname> instance. | ||||
|         </para> | ||||
|                 <para> If this is set, <classname>PersistentTokenBasedRememberMeServices</classname> | ||||
|                     will be used and configured with a | ||||
|                     <classname>JdbcTokenRepositoryImpl</classname> instance. </para> | ||||
|             </section> | ||||
|             <section> | ||||
|                 <title><literal>token-repository-ref</literal></title> | ||||
|         <para> Configures a <classname>PersistentTokenBasedRememberMeServices</classname> but allows | ||||
|           the use of a custom <interfacename>PersistentTokenRepository</interfacename> bean. </para> | ||||
|                 <para> Configures a <classname>PersistentTokenBasedRememberMeServices</classname> | ||||
|                     but allows the use of a custom | ||||
|                     <interfacename>PersistentTokenRepository</interfacename> bean. </para> | ||||
|             </section> | ||||
|             <section> | ||||
|                 <title><literal>services-ref</literal></title> | ||||
|         <para> Allows complete control of the <interfacename>RememberMeServices</interfacename> | ||||
|           implementation that will be used by the filter. The value should be the Id of a bean in | ||||
|           the application context which implements this interface. </para> | ||||
|                 <para> Allows complete control of the | ||||
|                     <interfacename>RememberMeServices</interfacename> implementation that will be | ||||
|                     used by the filter. The value should be the Id of a bean in the application | ||||
|                     context which implements this interface. </para> | ||||
|             </section> | ||||
|             <section> | ||||
|                 <title><literal>token-repository-ref</literal></title> | ||||
|         <para> Configures a <classname>PersistentTokenBasedRememberMeServices</classname> but allows | ||||
|           the use of a custom <interfacename>PersistentTokenRepository</interfacename> bean. </para> | ||||
|                 <para> Configures a <classname>PersistentTokenBasedRememberMeServices</classname> | ||||
|                     but allows the use of a custom | ||||
|                     <interfacename>PersistentTokenRepository</interfacename> bean. </para> | ||||
|             </section> | ||||
|             <section> | ||||
|                 <title>The <literal>key</literal> Attribute</title> | ||||
|         <para>Maps to the "key" property of <classname>AbstractRememberMeServices</classname>. | ||||
|           Should be set to a unique value to ensure that remember-me cookies are only valid within | ||||
|           the one application <footnote> | ||||
|                 <para>Maps to the "key" property of | ||||
|                     <classname>AbstractRememberMeServices</classname>. Should be set to a unique | ||||
|                     value to ensure that remember-me cookies are only valid within the one | ||||
|                     application <footnote> | ||||
|                     <para>This doesn't affect the use of | ||||
|                 <classname>PersistentTokenBasedRememberMeServices</classname>, where the tokens are | ||||
|               stored on the server side.</para> | ||||
|                         <classname>PersistentTokenBasedRememberMeServices</classname>, where the | ||||
|                         tokens are stored on the server side.</para> | ||||
|                     </footnote>. </para> | ||||
|             </section> | ||||
|             <section> | ||||
|                 <title><literal>token-validity-seconds</literal></title> | ||||
|                 <para> Maps to the <literal>tokenValiditySeconds</literal> property of | ||||
|             <classname>AbstractRememberMeServices</classname>. Specifies the period in seconds for | ||||
|           which the remember-me cookie should be valid. By default it will be valid for 14 days. | ||||
|         </para> | ||||
|                     <classname>AbstractRememberMeServices</classname>. Specifies the period in | ||||
|                     seconds for which the remember-me cookie should be valid. By default it will be | ||||
|                     valid for 14 days. </para> | ||||
|             </section> | ||||
|             <section> | ||||
|                 <title><literal>user-service-ref</literal></title> | ||||
|                 <para> The remember-me services implementations require access to a | ||||
|             <interfacename>UserDetailsService</interfacename>, so there has to be one defined in the | ||||
|           application context. If there is only one, it will be selected and used automatically by | ||||
|           the namespace configuration. If there are multiple instances, you can specify a bean Id | ||||
|           explicitly using this attribute. </para> | ||||
|                     <interfacename>UserDetailsService</interfacename>, so there has to be one | ||||
|                     defined in the application context. If there is only one, it will be selected | ||||
|                     and used automatically by the namespace configuration. If there are multiple | ||||
|                     instances, you can specify a bean Id explicitly using this attribute. </para> | ||||
|             </section> | ||||
|         </section> | ||||
|         <section xml:id="nsa-session-mgmt"> | ||||
|  | @ -321,26 +340,29 @@ | |||
|                 <classname>SessionManagementFilter</classname> to the filter stack.</para> | ||||
|             <section xml:id="session-fixation-protection"> | ||||
|                 <title><literal>session-fixation-protection</literal></title> | ||||
|         <para> Indicates whether an existing session should be invalidated when a user authenticates | ||||
|           and a new session started. If set to "none" no change will be made. "newSession" will | ||||
|           create a new empty session. "migrateSession" will create a new session and copy the | ||||
|           session attributes to the new session. Defaults to "migrateSession".</para> | ||||
|                 <para> Indicates whether an existing session should be invalidated when a user | ||||
|                     authenticates and a new session started. If set to "none" no change will be | ||||
|                     made. "newSession" will create a new empty session. "migrateSession" will create | ||||
|                     a new session and copy the session attributes to the new session. Defaults to | ||||
|                     "migrateSession".</para> | ||||
|                 <para> If session fixation protection is enabled, the | ||||
|                     <classname>SessionManagementFilter</classname> is inected with a appropriately | ||||
|           configured <classname>DefaultSessionAuthenticationStrategy</classname>. See the Javadoc | ||||
|           for this class for more details. </para> | ||||
|                     configured <classname>DefaultSessionAuthenticationStrategy</classname>. See the | ||||
|                     Javadoc for this class for more details. </para> | ||||
|             </section> | ||||
|         </section> | ||||
|         <section xml:id="nsa-concurrent-session-control"> | ||||
|             <title>The <literal><concurrency-control></literal> Element</title> | ||||
|       <para> Adds support for concurrent session control, allowing limits to be placed on the number | ||||
|         of active sessions a user can have. A <classname>ConcurrentSessionFilter</classname> will be | ||||
|         created, and a <classname>ConcurrentSessionControlStrategy</classname> will be used with the | ||||
|           <classname>SessionManagementFilter</classname>. If a <literal>form-login</literal> element | ||||
|         has been declared, the strategy object will also be injected into the created authentication | ||||
|         filter. An instance of <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> | ||||
|             <para> Adds support for concurrent session control, allowing limits to be placed on the | ||||
|                 number of active sessions a user can have. A | ||||
|                 <classname>ConcurrentSessionFilter</classname> will be created, and a | ||||
|                 <classname>ConcurrentSessionControlStrategy</classname> will be used with the | ||||
|                 <classname>SessionManagementFilter</classname>. If a <literal>form-login</literal> | ||||
|                 element has been declared, the strategy object will also be injected into the | ||||
|                 created authentication filter. An instance of | ||||
|                 <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> | ||||
|                 <title>The <literal>max-sessions</literal> attribute</title> | ||||
|                 <para>Maps to the <literal>maximumSessions</literal> property of | ||||
|  | @ -348,87 +370,92 @@ | |||
|             </section> | ||||
|             <section> | ||||
|                 <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 | ||||
|           "expired" by the concurrent session controller because the user has exceeded the number of | ||||
|           allowed sessions and has logged in again elsewhere. Should be set unless | ||||
|             <literal>exception-if-maximum-exceeded</literal> is set. If no value is supplied, an | ||||
|           expiry message will just be written directly back to the response. </para> | ||||
|                 <para> The URL a user will be redirected to if they attempt to use a session which | ||||
|                     has been "expired" by the concurrent session controller because the user has | ||||
|                     exceeded the number of allowed sessions and has logged in again elsewhere. | ||||
|                     Should be set unless <literal>exception-if-maximum-exceeded</literal> is set. If | ||||
|                     no value is supplied, an expiry message will just be written directly back to | ||||
|                     the response. </para> | ||||
|             </section> | ||||
|             <section> | ||||
|                 <title>The <literal>error-if-maximum-exceeded</literal> attribute</title> | ||||
|         <para>If set to "true" a <exceptionname>SessionAuthenticationException</exceptionname> will | ||||
|           be raised when a user attempts to exceed the maximum allowed number of sessions. The | ||||
|                 <para>If set to "true" a | ||||
|                     <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> | ||||
|             </section> | ||||
|             <section> | ||||
|                 <title>The <literal>session-registry-alias</literal> and | ||||
|                     <literal>session-registry-ref</literal> attributes</title> | ||||
|                 <para> The user can supply their own <interfacename>SessionRegistry</interfacename> | ||||
|           implementation using the <literal>session-registry-ref</literal> attribute. The 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 | ||||
|           your own beans or an admin interface. You can expose the interal bean using the | ||||
|             <literal>session-registry-alias</literal> attribute, giving it a name that you can use | ||||
|           elsewhere in your configuration. </para> | ||||
|                     implementation using the <literal>session-registry-ref</literal> attribute. The | ||||
|                     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 your own beans or an admin interface. You can expose the interal bean | ||||
|                     using the <literal>session-registry-alias</literal> attribute, giving it a name | ||||
|                     that you can use elsewhere in your configuration. </para> | ||||
|             </section> | ||||
|         </section> | ||||
|         <section xml:id="nsa-anonymous"> | ||||
|             <title>The <literal><anonymous></literal> Element</title> | ||||
|             <para> Adds an <classname>AnonymousAuthenticationFilter</classname> to the stack and an | ||||
|           <classname>AnonymousAuthenticationProvider</classname>. Required if you are using the | ||||
|           <literal>IS_AUTHENTICATED_ANONYMOUSLY</literal> attribute. </para> | ||||
|                 <classname>AnonymousAuthenticationProvider</classname>. Required if you are using | ||||
|                 the <literal>IS_AUTHENTICATED_ANONYMOUSLY</literal> attribute. </para> | ||||
|         </section> | ||||
|         <section xml:id="nsa-x509"> | ||||
|             <title>The <literal><x509></literal> Element</title> | ||||
|             <para> Adds support for X.509 authentication. An | ||||
|                 <classname>X509AuthenticationFilter</classname> will be added to the stack and an | ||||
|           <classname>Http403ForbiddenEntryPoint</classname> bean will be created. The latter will | ||||
|         only be used if no other authentication mechanisms are in use (it's only functionality is to | ||||
|         return an HTTP 403 error code). A | ||||
|           <classname>PreAuthenticatedAuthenticationProvider</classname> will also be created which | ||||
|         delegates the loading of user authorities to a | ||||
|                 <classname>Http403ForbiddenEntryPoint</classname> bean will be created. The latter | ||||
|                 will only be used if no other authentication mechanisms are in use (it's only | ||||
|                 functionality is to return an HTTP 403 error code). A | ||||
|                 <classname>PreAuthenticatedAuthenticationProvider</classname> will also be created | ||||
|                 which delegates the loading of user authorities to a | ||||
|                 <interfacename>UserDetailsService</interfacename>. </para> | ||||
|             <section> | ||||
|                 <title>The <literal>subject-principal-regex</literal> attribute</title> | ||||
|         <para> Defines a regular expression which will be used to extract the username from the | ||||
|           certificate (for use with the <interfacename>UserDetailsService</interfacename>). </para> | ||||
|                 <para> Defines a regular expression which will be used to extract the username from | ||||
|                     the certificate (for use with the | ||||
|                     <interfacename>UserDetailsService</interfacename>). </para> | ||||
|             </section> | ||||
|             <section> | ||||
|                 <title>The <literal>user-service-ref</literal> attribute</title> | ||||
|         <para> Allows a specific <interfacename>UserDetailsService</interfacename> to be used with | ||||
|           X.509 in the case where multiple instances are configured. If not set, an attempt will be | ||||
|           made to locate a suitable instance automatically and use that. </para> | ||||
|                 <para> Allows a specific <interfacename>UserDetailsService</interfacename> to be | ||||
|                     used with X.509 in the case where multiple instances are configured. If not set, | ||||
|                     an attempt will be made to locate a suitable instance automatically and use | ||||
|                     that. </para> | ||||
|             </section> | ||||
|         </section> | ||||
|         <section xml:id="nsa-openid-login"> | ||||
|             <title>The <literal><openid-login></literal> Element</title> | ||||
|             <para> Similar to <literal><form-login></literal> and has the same attributes. The | ||||
|                 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 | ||||
|         requires a reference to a <interfacename>UserDetailsService</interfacename>. Again, this can | ||||
|         be specified by Id, using the <literal>user-service-ref</literal> attribute, or will be | ||||
|         located automatically in the application context. </para> | ||||
|                 requires a reference to a <interfacename>UserDetailsService</interfacename>. Again, | ||||
|                 this can be specified by Id, using the <literal>user-service-ref</literal> | ||||
|                 attribute, or will be located automatically in the application context. </para> | ||||
|         </section> | ||||
|         <section xml:id="nsa-logout"> | ||||
|             <title>The <literal><logout></literal> Element</title> | ||||
|       <para> Adds a <classname>LogoutFilter</classname> to the filter stack. This is configured with | ||||
|         a <classname>SecurityContextLogoutHandler</classname>. </para> | ||||
|             <para> Adds a <classname>LogoutFilter</classname> to the filter stack. This is | ||||
|                 configured with a <classname>SecurityContextLogoutHandler</classname>. </para> | ||||
|             <section> | ||||
|                 <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). | ||||
|           Defaults to "/j_spring_security_logout". </para> | ||||
|                 <para> The URL which will cause a logout (i.e. which will be processed by the | ||||
|                     filter). Defaults to "/j_spring_security_logout". </para> | ||||
|             </section> | ||||
|             <section> | ||||
|                 <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> | ||||
|                 <para> The destination URL which the user will be taken to after logging out. | ||||
|                     Defaults to "/". </para> | ||||
|             </section> | ||||
|             <section> | ||||
|                 <title>The <literal>invalidate-session</literal> attribute</title> | ||||
|                 <para> Maps to the <literal>invalidateHttpSession</literal> of the | ||||
|             <classname>SecurityContextLogoutHandler</classname>. Defaults to "true", so the session | ||||
|           will be invalidated on logout. </para> | ||||
|                     <classname>SecurityContextLogoutHandler</classname>. Defaults to "true", so the | ||||
|                     session will be invalidated on logout. </para> | ||||
|             </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 | ||||
|                 additional beans but is used to select a bean of type | ||||
|                 <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 | ||||
|         Spring Security. Full details can be found in the namespace chapter.</para> | ||||
|                 appllication context and add that at a particular position in the filter chain | ||||
|                 maintained by Spring Security. Full details can be found in the namespace | ||||
|                 chapter.</para> | ||||
|         </section> | ||||
|     </section> | ||||
|     <section> | ||||
|         <title>Authentication Services</title> | ||||
|     <para> Before Spring Security 3.0, an <interfacename>AuthenticationManager</interfacename> was | ||||
|       automatically registered internally. Now you must register one explicitly using the | ||||
|         <para> Before Spring Security 3.0, an <interfacename>AuthenticationManager</interfacename> | ||||
|             was automatically registered internally. Now you must register one explicitly using the | ||||
|             <literal><authentication-manager></literal> element. This creates an instance of | ||||
|       Spring Security's <classname>ProviderManager</classname> class, which needs to be configured | ||||
|       with a list of one or more <interfacename>AuthenticationProvider</interfacename> instances. | ||||
|       These can either be created using syntax elements provided by the namespace, or they can be | ||||
|       standard bean definitions, marked for addition to the list using the | ||||
|             Spring Security's <classname>ProviderManager</classname> class, which needs to be | ||||
|             configured with a list of one or more | ||||
|             <interfacename>AuthenticationProvider</interfacename> instances. These can either be | ||||
|             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> | ||||
|         <section> | ||||
|             <title>The <literal><authentication-manager></literal> Element</title> | ||||
|             <para> Every Spring Security application which uses the namespace must have include this | ||||
|                 element somewhere. It is responsible for registering the | ||||
|                 <interfacename>AuthenticationManager</interfacename> which provides authentication | ||||
|         services to the application. It also allows you to define an alias name for 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 | ||||
|           <interfacename>AuthenticationProvider</interfacename> instances should be children of this | ||||
|         element.</para> | ||||
|                 services to the application. It also allows you to define an alias name for 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 <interfacename>AuthenticationProvider</interfacename> instances should | ||||
|                 be children of this element.</para> | ||||
|             <section> | ||||
|                 <title>The <literal><authentication-provider></literal> Element</title> | ||||
|         <para> Unless used with a <literal>ref</literal> attribute, this element is shorthand for configuring a | ||||
|             <link xlink:href="#core-services-dao-provider"><classname>DaoAuthenticationProvider</classname></link>. | ||||
|                 <para> Unless used with a <literal>ref</literal> attribute, this element is | ||||
|                     shorthand for configuring a <link xlink:href="#core-services-dao-provider" | ||||
|                     ><classname>DaoAuthenticationProvider</classname></link>. | ||||
|                     <classname>DaoAuthenticationProvider</classname> loads user information from a | ||||
|             <interfacename>UserDetailsService</interfacename> and compares the username/password | ||||
|           combination with the values supplied at login. The | ||||
|             <interfacename>UserDetailsService</interfacename> instance can be defined either by | ||||
|           using an available namespace element (<literal>jdbc-user-service</literal> or by using the | ||||
|             <literal>user-service-ref</literal> attribute to point to a bean defined elsewhere in | ||||
|           the application context). You can find examples of these variations in the <link | ||||
|             xlink:href="#ns-auth-providers">namespace introduction</link>. </para> | ||||
|                     <interfacename>UserDetailsService</interfacename> and compares the | ||||
|                     username/password combination with the values supplied at login. The | ||||
|                     <interfacename>UserDetailsService</interfacename> instance can be defined either | ||||
|                     by using an available namespace element (<literal>jdbc-user-service</literal> or | ||||
|                     by using the <literal>user-service-ref</literal> attribute to point to a bean | ||||
|                     defined elsewhere in the application context). You can find examples of these | ||||
|                     variations in the <link xlink:href="#ns-auth-providers">namespace | ||||
|                     introduction</link>. </para> | ||||
|                 <section> | ||||
|                     <title>The <literal><password-encoder></literal> Element</title> | ||||
|           <para>Authentication providers can optionally be configured to use a password encoder as | ||||
|             described in the <link xlink:href="#ns-password-encoder">namespace introduction</link>. | ||||
|             This will result in the bean being injected with the appropriate | ||||
|               <interfacename>PasswordEncoder</interfacename> instance, potentially with an | ||||
|             accompanying <interfacename>SaltSource</interfacename> bean to provide salt values for | ||||
|                     <para>Authentication providers can optionally be configured to use a password | ||||
|                         encoder as described in the <link xlink:href="#ns-password-encoder" | ||||
|                         >namespace introduction</link>. This will result in the bean being injected | ||||
|                         with the appropriate <interfacename>PasswordEncoder</interfacename> | ||||
|                         instance, potentially with an accompanying | ||||
|                         <interfacename>SaltSource</interfacename> bean to provide salt values for | ||||
|                         hashing. </para> | ||||
|                 </section> | ||||
|             </section> | ||||
|             <section> | ||||
|                 <title>Using <literal><authentication-provider></literal> to refer to an | ||||
|                     <interfacename>AuthenticationProvider</interfacename> Bean</title> | ||||
|         <para> If you have written your own <interfacename>AuthenticationProvider</interfacename> | ||||
|           implementation (or want to configure one of Spring Security's own implementations as a | ||||
|           traditional bean for some reason, then you can use the following syntax to add it to the | ||||
|           internal <classname>ProviderManager</classname>'s list: <programlisting><![CDATA[ | ||||
|                 <para> If you have written your own | ||||
|                     <interfacename>AuthenticationProvider</interfacename> implementation (or want to | ||||
|                     configure one of Spring Security's own implementations as a traditional bean for | ||||
|                     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-provider ref="myAuthenticationProvider" /> | ||||
|   </security:authentication-manager> | ||||
|  | @ -501,132 +534,144 @@ | |||
|         <title>Method Security</title> | ||||
|         <section> | ||||
|             <title>The <literal><global-method-security></literal> Element</title> | ||||
|       <para> This element is the primary means of adding support for securing methods on Spring | ||||
|         Security beans. Methods can be secured by the use of annotations (defined at the interface | ||||
|         or class level) or by defining a set of pointcuts as child elements, using AspectJ syntax. </para> | ||||
|       <para> Method security uses the same <interfacename>AccessDecisionManager</interfacename> | ||||
|         configuration as web security, but this can be overridden as explained above <xref | ||||
|             <para> This element is the primary means of adding support for securing methods on | ||||
|                 Spring Security beans. Methods can be secured by the use of annotations (defined at | ||||
|                 the interface or class level) or by defining a set of pointcuts as child elements, | ||||
|                 using AspectJ syntax. </para> | ||||
|             <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> | ||||
|             <section> | ||||
|         <title>The <literal>secured-annotations</literal> and <literal>jsr250-annotations</literal> | ||||
|           Attributes</title> | ||||
|                 <title>The <literal>secured-annotations</literal> and | ||||
|                     <literal>jsr250-annotations</literal> Attributes</title> | ||||
|                 <para> Setting these to "true" will enable support for Spring Security's own | ||||
|             <literal>@Secured</literal> annotations and JSR-250 annotations, respectively. They are | ||||
|           both disabled by default. Use of JSR-250 annotations also adds a | ||||
|                     <literal>@Secured</literal> annotations and JSR-250 annotations, respectively. | ||||
|                     They are both disabled by default. Use of JSR-250 annotations also adds a | ||||
|                     <classname>Jsr250Voter</classname> to the | ||||
|             <interfacename>AccessDecisionManager</interfacename>, so you need to make sure you do | ||||
|           this if you are using a custom implementation and want to use these annotations. </para> | ||||
|                     <interfacename>AccessDecisionManager</interfacename>, so you need to make sure | ||||
|                     you do this if you are using a custom implementation and want to use these | ||||
|                     annotations. </para> | ||||
|             </section> | ||||
|             <section> | ||||
|                 <title>Securing Methods using <literal><protect-pointcut></literal></title> | ||||
|         <para> Rather than defining security attributes on an individual method or class basis using | ||||
|           the <literal>@Secured</literal> annotation, you can define cross-cutting security | ||||
|           constraints across whole sets of methods and interfaces in your service layer using the | ||||
|             <literal><protect-pointcut></literal> element. This has two attributes: <itemizedlist> | ||||
|                 <para> Rather than defining security attributes on an individual method or class | ||||
|                     basis using the <literal>@Secured</literal> annotation, you can define | ||||
|                     cross-cutting security constraints across whole sets of methods and interfaces | ||||
|                     in your service layer using the <literal><protect-pointcut></literal> | ||||
|                     element. This has two attributes: <itemizedlist> | ||||
|                     <listitem> | ||||
|                         <para><literal>expression</literal> - the pointcut expression</para> | ||||
|                     </listitem> | ||||
|                     <listitem> | ||||
|                         <para><literal>access</literal> - the security attributes which apply</para> | ||||
|                     </listitem> | ||||
|           </itemizedlist> You can find an example in the <link xlink:href="#ns-protect-pointcut" | ||||
|             >namespace introduction</link>. </para> | ||||
|                     </itemizedlist> You can find an example in the <link | ||||
|                     xlink:href="#ns-protect-pointcut">namespace introduction</link>. </para> | ||||
|             </section> | ||||
|             <section xml:id="nsa-custom-after-invocation"> | ||||
|                 <title>The <literal><after-invocation-provider></literal> Element</title> | ||||
|                 <para> This element can be used to decorate an | ||||
|                     <interfacename>AfterInvocationProvider</interfacename> for use by the security | ||||
|           interceptor maintained by the <literal><global-method-security></literal> namespace. | ||||
|           You can define zero or more of these within the <literal>global-method-security</literal> | ||||
|           element, each with a <literal>ref</literal> attribute pointing to an | ||||
|                     interceptor maintained by the <literal><global-method-security></literal> | ||||
|                     namespace. You can define zero or more of these within the | ||||
|                     <literal>global-method-security</literal> element, each with a | ||||
|                     <literal>ref</literal> attribute pointing to an | ||||
|                     <interfacename>AfterInvocationProvider</interfacename> bean instance within your | ||||
|                     application context. </para> | ||||
|             </section> | ||||
|         </section> | ||||
|         <section> | ||||
|             <title>LDAP Namespace Options</title> | ||||
|       <para> LDAP is covered in some details in <link xlink:href="#ldap">its own chapter</link>. We | ||||
|         will expand on that here with some explanation of how the namespace options map to Spring | ||||
|         beans. The LDAP implementation uses Spring LDAP extensively, so some familiarity with that | ||||
|         project's API may be useful. </para> | ||||
|             <para> LDAP is covered in some details in <link xlink:href="#ldap">its own | ||||
|                 chapter</link>. We will expand on that here with some explanation of how the | ||||
|                 namespace options map to Spring beans. The LDAP implementation uses Spring LDAP | ||||
|                 extensively, so some familiarity with that project's API may be useful. </para> | ||||
|             <section> | ||||
|                 <title>Defining the LDAP Server using the <literal><ldap-server></literal> | ||||
|                     Element</title> | ||||
|         <para> This element sets up a Spring LDAP <interfacename>ContextSource</interfacename> for | ||||
|           use by the other LDAP beans, defining the location of the LDAP server and other | ||||
|           information (such as a username and password, if it doesn't allow anonymous access) for | ||||
|           connecting to it. It can also be used to create an embedded server for testing. Details of | ||||
|           the syntax for both options are covered in the <link xlink:href="#ldap-server">LDAP | ||||
|             chapter</link>. The actual <interfacename>ContextSource</interfacename> implementation | ||||
|           is <classname>DefaultSpringSecurityContextSource</classname> which extends Spring LDAP's | ||||
|             <classname>LdapContextSource</classname> class. The <literal>manager-dn</literal> and | ||||
|             <literal>manager-password</literal> attributes map to the latter's | ||||
|             <literal>userDn</literal> and <literal>password</literal> properties respectively. </para> | ||||
|         <para> If you only have one server defined in your application context, the other LDAP | ||||
|           namespace-defined beans will use it automatically. Otherwise, you can give the element an | ||||
|           "id" attribute and refer to it from other namespace beans using 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> | ||||
|                 <para> This element sets up a Spring LDAP | ||||
|                     <interfacename>ContextSource</interfacename> for use by the other LDAP beans, | ||||
|                     defining the location of the LDAP server and other information (such as a | ||||
|                     username and password, if it doesn't allow anonymous access) for connecting to | ||||
|                     it. It can also be used to create an embedded server for testing. Details of the | ||||
|                     syntax for both options are covered in the <link xlink:href="#ldap-server">LDAP | ||||
|                     chapter</link>. The actual <interfacename>ContextSource</interfacename> | ||||
|                     implementation is <classname>DefaultSpringSecurityContextSource</classname> | ||||
|                     which extends Spring LDAP's <classname>LdapContextSource</classname> class. The | ||||
|                     <literal>manager-dn</literal> and <literal>manager-password</literal> attributes | ||||
|                     map to the latter's <literal>userDn</literal> and <literal>password</literal> | ||||
|                     properties respectively. </para> | ||||
|                 <para> If you only have one server defined in your application context, the other | ||||
|                     LDAP namespace-defined beans will use it automatically. Otherwise, you can give | ||||
|                     the element an "id" attribute and refer to it from other namespace beans using | ||||
|                     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> | ||||
|                 <title>The <literal><ldap-provider></literal> Element</title> | ||||
|                 <para> This element is shorthand for the creation of an | ||||
|             <classname>LdapAuthenticationProvider</classname> instance. By default this will be | ||||
|           configured with a <classname>BindAuthenticator</classname> instance and a | ||||
|             <classname>DefaultAuthoritiesPopulator</classname>. As with all namespace authentication | ||||
|           providers, it must be included as a child of the | ||||
|                     <classname>LdapAuthenticationProvider</classname> instance. By default this will | ||||
|                     be configured with a <classname>BindAuthenticator</classname> instance and a | ||||
|                     <classname>DefaultAuthoritiesPopulator</classname>. As with all namespace | ||||
|                     authentication providers, it must be included as a child of the | ||||
|                     <literal>authentication-provider</literal> element.</para> | ||||
|                 <section> | ||||
|                     <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 | ||||
|             DN directly from the username without doing a directory search), you can use this | ||||
|             attribute to map directly to the DN. It maps directly to the | ||||
|                     <para> If your users are at a fixed location in the directory (i.e. you can work | ||||
|                         out the DN directly from the username without doing a directory search), you | ||||
|                         can use this attribute to map directly to the DN. It maps directly to the | ||||
|                         <literal>userDnPatterns</literal> property of | ||||
|                         <classname>AbstractLdapAuthenticator</classname>. </para> | ||||
|                 </section> | ||||
|                 <section> | ||||
|           <title>The <literal>user-search-base</literal> and <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 | ||||
|             set these attributes to control the search. The <classname>BindAuthenticator</classname> | ||||
|             will be configured with a <classname>FilterBasedLdapUserSearch</classname> and the | ||||
|             attribute values map directly to the first two arguments of that bean's constructor. If | ||||
|             these attributes aren't set and no <literal>user-dn-pattern</literal> has been supplied | ||||
|             as an alternative, then the default search values of | ||||
|                     <title>The <literal>user-search-base</literal> and | ||||
|                         <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 set these attributes to control the search. The | ||||
|                         <classname>BindAuthenticator</classname> will be configured with a | ||||
|                         <classname>FilterBasedLdapUserSearch</classname> and the attribute values | ||||
|                         map directly to the first two arguments of that bean's constructor. If these | ||||
|                         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-base=""</literal> will be used. </para> | ||||
|                 </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> | ||||
|                         Attributes</title> | ||||
|                     <para> The value of <literal>group-search-base</literal> is mapped to the | ||||
|                         <literal>groupSearchBase</literal> constructor argument of | ||||
|               <classname>DefaultAuthoritiesPopulator</classname> and defaults to "ou=groups". The | ||||
|             default filter value is "(uniqueMember={0})", which assumes that the entry is of type | ||||
|             "groupOfUniqueNames". <literal>group-role-attribute</literal> maps to the | ||||
|               <literal>groupRoleAttribute</literal> attribute and defaults to "cn". Similarly | ||||
|               <literal>role-prefix</literal> maps to <literal>rolePrefix</literal> and defaults to | ||||
|             "ROLE_". </para> | ||||
|                         <classname>DefaultAuthoritiesPopulator</classname> and defaults to | ||||
|                         "ou=groups". The default filter value is "(uniqueMember={0})", which assumes | ||||
|                         that the entry is of type "groupOfUniqueNames". | ||||
|                         <literal>group-role-attribute</literal> maps to the | ||||
|                         <literal>groupRoleAttribute</literal> attribute and defaults to "cn". | ||||
|                         Similarly <literal>role-prefix</literal> maps to | ||||
|                         <literal>rolePrefix</literal> and defaults to "ROLE_". </para> | ||||
|                 </section> | ||||
|                 <section> | ||||
|                     <title>The <literal><password-compare></literal> Element</title> | ||||
|           <para> This is used as child element to <literal><ldap-provider></literal> and | ||||
|             switches the authentication strategy from <classname>BindAuthenticator</classname> to | ||||
|               <classname>PasswordComparisonAuthenticator</classname>. This can optionally be | ||||
|             supplied with a <literal>hash</literal> attribute or with a child | ||||
|               <literal><password-encoder></literal> element to hash the password before | ||||
|             submitting it to the directory for comparison. </para> | ||||
|                     <para> This is used as child element to <literal><ldap-provider></literal> | ||||
|                         and switches the authentication strategy from | ||||
|                         <classname>BindAuthenticator</classname> to | ||||
|                         <classname>PasswordComparisonAuthenticator</classname>. This can optionally | ||||
|                         be supplied with a <literal>hash</literal> attribute or with a child | ||||
|                         <literal><password-encoder></literal> element to hash the password | ||||
|                         before submitting it to the directory for comparison. </para> | ||||
|                 </section> | ||||
|             </section> | ||||
|             <section> | ||||
|                 <title>The <literal><ldap-user-service></literal> Element</title> | ||||
|         <para> This element configures an LDAP <interfacename>UserDetailsService</interfacename>. | ||||
|           The class used is <classname>LdapUserDetailsService</classname> which is a combination of | ||||
|           a <classname>FilterBasedLdapUserSearch</classname> and a | ||||
|             <classname>DefaultAuthoritiesPopulator</classname>. The attributes it supports have the | ||||
|           same usage as in <literal><ldap-provider></literal>. </para> | ||||
|                 <para> This element configures an LDAP | ||||
|                     <interfacename>UserDetailsService</interfacename>. The class used is | ||||
|                     <classname>LdapUserDetailsService</classname> which is a combination of a | ||||
|                     <classname>FilterBasedLdapUserSearch</classname> and a | ||||
|                     <classname>DefaultAuthoritiesPopulator</classname>. The attributes it supports | ||||
|                     have the same usage as in <literal><ldap-provider></literal>. </para> | ||||
|             </section> | ||||
|         </section> | ||||
|     </section> | ||||
|  |  | |||
|  | @ -7,11 +7,12 @@ | |||
|         <info> | ||||
|             <title>Authorities</title> | ||||
|         </info> | ||||
|     <para>As we saw in the <link xlink:href="#tech-granted-authority">technical overview</link>, all | ||||
|         <interfacename>Authentication</interfacename> implementations store a list of | ||||
|         <para>As we saw in the <link xlink:href="#tech-granted-authority">technical overview</link>, | ||||
|             all <interfacename>Authentication</interfacename> implementations store a list of | ||||
|             <interfacename>GrantedAuthority</interfacename> objects. These represent the authorities | ||||
|       that have been granted to the principal. The <interfacename>GrantedAuthority</interfacename> | ||||
|       objects are inserted into the <interfacename>Authentication</interfacename> object by the | ||||
|             that have been granted to the principal. The | ||||
|             <interfacename>GrantedAuthority</interfacename> objects are inserted into the | ||||
|             <interfacename>Authentication</interfacename> object by the | ||||
|             <interfacename>AuthenticationManager</interfacename> and are later read by | ||||
|             <interfacename>AccessDecisionManager</interfacename>s when making authorization | ||||
|             decisions.</para> | ||||
|  | @ -22,74 +23,79 @@ | |||
|             <interfacename>AccessDecisionManager</interfacename>s to obtain a precise | ||||
|             <literal>String</literal> representation of the | ||||
|             <interfacename>GrantedAuthority</interfacename>. By returning a representation as a | ||||
|         <literal>String</literal>, a <interfacename>GrantedAuthority</interfacename> can be easily | ||||
|         <quote>read</quote> by most <interfacename>AccessDecisionManager</interfacename>s. If a | ||||
|             <literal>String</literal>, a <interfacename>GrantedAuthority</interfacename> can be | ||||
|             easily <quote>read</quote> by most | ||||
|             <interfacename>AccessDecisionManager</interfacename>s. If a | ||||
|             <interfacename>GrantedAuthority</interfacename> cannot be precisely represented as a | ||||
|         <literal>String</literal>, the <interfacename>GrantedAuthority</interfacename> is considered | ||||
|         <quote>complex</quote> and <literal>getAuthority()</literal> must return | ||||
|             <literal>String</literal>, the <interfacename>GrantedAuthority</interfacename> is | ||||
|             considered <quote>complex</quote> and <literal>getAuthority()</literal> must return | ||||
|             <literal>null</literal>.</para> | ||||
|     <para>An example of a <quote>complex</quote> | ||||
|       <interfacename>GrantedAuthority</interfacename> would be an implementation that stores a list | ||||
|       of operations and authority thresholds that apply to different customer account numbers. | ||||
|       Representing this complex <interfacename>GrantedAuthority</interfacename> as a | ||||
|         <literal>String</literal> would be quite difficult, and as a result the | ||||
|         <literal>getAuthority()</literal> method should return <literal>null</literal>. This will | ||||
|       indicate to any <interfacename>AccessDecisionManager</interfacename> that it will need to | ||||
|       specifically support the <interfacename>GrantedAuthority</interfacename> implementation in | ||||
|       order to understand its contents.</para> | ||||
|         <para>An example of a <quote>complex</quote> <interfacename>GrantedAuthority</interfacename> | ||||
|             would be an implementation that stores a list of operations and authority thresholds | ||||
|             that apply to different customer account numbers. Representing this complex | ||||
|             <interfacename>GrantedAuthority</interfacename> as a <literal>String</literal> would be | ||||
|             quite difficult, and as a result the <literal>getAuthority()</literal> method should | ||||
|             return <literal>null</literal>. This will indicate to any | ||||
|             <interfacename>AccessDecisionManager</interfacename> that it will need to specifically | ||||
|             support the <interfacename>GrantedAuthority</interfacename> implementation in order to | ||||
|             understand its contents.</para> | ||||
|         <para>Spring Security includes one concrete <interfacename>GrantedAuthority</interfacename> | ||||
|             implementation, <literal>GrantedAuthorityImpl</literal>. This allows any user-specified | ||||
|             <literal>String</literal> to be converted into a | ||||
|             <interfacename>GrantedAuthority</interfacename>. All | ||||
|         <classname>AuthenticationProvider</classname>s included with the security architecture use | ||||
|         <literal>GrantedAuthorityImpl</literal> to populate the | ||||
|             <classname>AuthenticationProvider</classname>s included with the security architecture | ||||
|             use <literal>GrantedAuthorityImpl</literal> to populate the | ||||
|             <interfacename>Authentication</interfacename> object.</para> | ||||
|     </section> | ||||
|     <section xml:id="authz-pre-invocation"> | ||||
|         <info> | ||||
|             <title>Pre-Invocation Handling</title> | ||||
|         </info> | ||||
|     <para> As we've also seen in the <link xlink:href="#secure-objects">Technical Overview</link> | ||||
|       chapter, Spring Security provides interceptors which control access to secure objects such as | ||||
|       method invocations or web requests. A pre-invocation decision on whether the invocation is | ||||
|       allowed to proceed is made by the <interfacename>AccessDecisionManager</interfacename>. </para> | ||||
|         <para> As we've also seen in the <link xlink:href="#secure-objects">Technical | ||||
|             Overview</link> chapter, Spring Security provides interceptors which control access to | ||||
|             secure objects such as method invocations or web requests. A pre-invocation decision on | ||||
|             whether the invocation is allowed to proceed is made by the | ||||
|             <interfacename>AccessDecisionManager</interfacename>. </para> | ||||
|         <section xml:id="authz-access-decision-manager"> | ||||
|             <title>The AccessDecisionManager</title> | ||||
|             <para>The <interfacename>AccessDecisionManager</interfacename> is called by the | ||||
|           <classname>AbstractSecurityInterceptor</classname> and is responsible for making final | ||||
|         access control decisions. The <interfacename>AccessDecisionManager</interfacename> interface | ||||
|         contains three methods: | ||||
|                 <classname>AbstractSecurityInterceptor</classname> and is responsible for making | ||||
|                 final access control decisions. The | ||||
|                 <interfacename>AccessDecisionManager</interfacename> interface contains three | ||||
|                 methods: | ||||
|                 <programlisting> | ||||
|  void decide(Authentication authentication, Object secureObject, | ||||
|      List<ConfigAttribute> config) throws AccessDeniedException; | ||||
|  boolean supports(ConfigAttribute attribute); | ||||
|  boolean supports(Class clazz); | ||||
|       </programlisting> | ||||
|         The <interfacename>AccessDecisionManager</interfacename>'s <methodname>decide</methodname> | ||||
|         method is passed all the relevant information it needs in order to make an authorization | ||||
|         decision. In particular, passing the secure <literal>Object</literal> enables those | ||||
|         arguments contained in the actual secure object invocation to be inspected. For example, | ||||
|         let's assume the secure object was a <classname>MethodInvocation</classname>. It would be | ||||
|         easy to query the <classname>MethodInvocation</classname> for any | ||||
|           <literal>Customer</literal> argument, and then implement some sort of security logic in | ||||
|         the <interfacename>AccessDecisionManager</interfacename> to ensure the principal is | ||||
|                 The <interfacename>AccessDecisionManager</interfacename>'s | ||||
|                 <methodname>decide</methodname> method is passed all the relevant information it | ||||
|                 needs in order to make an authorization decision. In particular, passing the secure | ||||
|                 <literal>Object</literal> enables those arguments contained in the actual secure | ||||
|                 object invocation to be inspected. For example, let's assume the secure object was a | ||||
|                 <classname>MethodInvocation</classname>. It would be easy to query the | ||||
|                 <classname>MethodInvocation</classname> for any <literal>Customer</literal> | ||||
|                 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 | ||||
|                 <literal>AccessDeniedException</literal> if access is denied.</para> | ||||
|             <para>The <literal>supports(ConfigAttribute)</literal> method is called by the | ||||
|           <classname>AbstractSecurityInterceptor</classname> at startup time to determine if the | ||||
|           <interfacename>AccessDecisionManager</interfacename> can process the passed | ||||
|                 <classname>AbstractSecurityInterceptor</classname> at startup time to determine if | ||||
|                 the <interfacename>AccessDecisionManager</interfacename> can process the passed | ||||
|                 <literal>ConfigAttribute</literal>. The <literal>supports(Class)</literal> method is | ||||
|                 called by a security interceptor implementation to ensure the configured | ||||
|           <interfacename>AccessDecisionManager</interfacename> supports the type of secure object | ||||
|         that the security interceptor will present.</para> | ||||
|                 <interfacename>AccessDecisionManager</interfacename> supports the type of secure | ||||
|                 object that the security interceptor will present.</para> | ||||
|         </section> | ||||
|         <section xml:id="authz-voting-based"> | ||||
|             <title>Voting-Based AccessDecisionManager Implementations</title> | ||||
|             <para>Whilst users can implement their own | ||||
|                 <interfacename>AccessDecisionManager</interfacename> to control all aspects of | ||||
|                 authorization, Spring Security includes several | ||||
|           <interfacename>AccessDecisionManager</interfacename> implementations that are based on | ||||
|         voting. <xref linkend="authz-access-voting"/> illustrates the relevant classes.</para> | ||||
|                 <interfacename>AccessDecisionManager</interfacename> implementations that are based | ||||
|                 on voting. <xref linkend="authz-access-voting"/> illustrates the relevant | ||||
|                 classes.</para> | ||||
|             <figure xml:id="authz-access-voting"> | ||||
|                 <title>Voting Decision Manager</title> | ||||
|                 <mediaobject> | ||||
|  | @ -99,87 +105,92 @@ | |||
|                     </imageobject> | ||||
|                 </mediaobject> | ||||
|             </figure> | ||||
|       <para>Using this approach, a series of <interfacename>AccessDecisionVoter</interfacename> | ||||
|         implementations are polled on an authorization decision. The | ||||
|           <interfacename>AccessDecisionManager</interfacename> then decides whether or not to throw | ||||
|         an <literal>AccessDeniedException</literal> based on its assessment of the votes.</para> | ||||
|       <para>The <interfacename>AccessDecisionVoter</interfacename> interface has three methods: | ||||
|             <para>Using this approach, a series of | ||||
|                 <interfacename>AccessDecisionVoter</interfacename> implementations are polled on an | ||||
|                 authorization decision. The <interfacename>AccessDecisionManager</interfacename> | ||||
|                 then decides whether or not to throw an <literal>AccessDeniedException</literal> | ||||
|                 based on its assessment of the votes.</para> | ||||
|             <para>The <interfacename>AccessDecisionVoter</interfacename> interface has three | ||||
|                 methods: | ||||
|                 <programlisting> | ||||
| int vote(Authentication authentication, Object object, List<ConfigAttribute> config); | ||||
| boolean supports(ConfigAttribute attribute); | ||||
| boolean supports(Class clazz); | ||||
| </programlisting> | ||||
|         Concrete implementations return an <literal>int</literal>, with possible values being | ||||
|         reflected in the <interfacename>AccessDecisionVoter</interfacename> static fields | ||||
|           <literal>ACCESS_ABSTAIN</literal>, <literal>ACCESS_DENIED</literal> and | ||||
|                 Concrete implementations return an <literal>int</literal>, with possible values | ||||
|                 being reflected in the <interfacename>AccessDecisionVoter</interfacename> static | ||||
|                 fields <literal>ACCESS_ABSTAIN</literal>, <literal>ACCESS_DENIED</literal> and | ||||
|                 <literal>ACCESS_GRANTED</literal>. A voting implementation will return | ||||
|           <literal>ACCESS_ABSTAIN</literal> if it has no opinion on an authorization decision. If it | ||||
|         does have an opinion, it must return either <literal>ACCESS_DENIED</literal> or | ||||
|           <literal>ACCESS_GRANTED</literal>.</para> | ||||
|       <para>There are three concrete <interfacename>AccessDecisionManager</interfacename>s provided | ||||
|         with Spring Security that tally the votes. The <literal>ConsensusBased</literal> | ||||
|         implementation will grant or deny access based on the consensus of non-abstain votes. | ||||
|         Properties are provided to control behavior in the event of an equality of votes or if all | ||||
|         votes are abstain. The <literal>AffirmativeBased</literal> implementation will grant access | ||||
|         if one or more <literal>ACCESS_GRANTED</literal> votes were received (i.e. a deny vote will | ||||
|         be ignored, provided there was at least one grant vote). Like the | ||||
|           <literal>ConsensusBased</literal> implementation, there is a parameter that controls the | ||||
|         behavior if all voters abstain. The <literal>UnanimousBased</literal> provider expects | ||||
|         unanimous <literal>ACCESS_GRANTED</literal> votes in order to grant access, ignoring | ||||
|         abstains. It will deny access if there is any <literal>ACCESS_DENIED</literal> vote. Like | ||||
|         the other implementations, there is a parameter that controls the behaviour if all voters | ||||
|         abstain.</para> | ||||
|                 <literal>ACCESS_ABSTAIN</literal> if it has no opinion on an authorization decision. | ||||
|                 If it does have an opinion, it must return either <literal>ACCESS_DENIED</literal> | ||||
|                 or <literal>ACCESS_GRANTED</literal>.</para> | ||||
|             <para>There are three concrete <interfacename>AccessDecisionManager</interfacename>s | ||||
|                 provided with Spring Security that tally the votes. The | ||||
|                 <literal>ConsensusBased</literal> implementation will grant or deny access based on | ||||
|                 the consensus of non-abstain votes. Properties are provided to control behavior in | ||||
|                 the event of an equality of votes or if all votes are abstain. The | ||||
|                 <literal>AffirmativeBased</literal> implementation will grant access if one or more | ||||
|                 <literal>ACCESS_GRANTED</literal> votes were received (i.e. a deny vote will be | ||||
|                 ignored, provided there was at least one grant vote). Like the | ||||
|                 <literal>ConsensusBased</literal> implementation, there is a parameter that controls | ||||
|                 the behavior if all voters abstain. The <literal>UnanimousBased</literal> provider | ||||
|                 expects unanimous <literal>ACCESS_GRANTED</literal> votes in order to grant access, | ||||
|                 ignoring abstains. It will deny access if there is any | ||||
|                 <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 | ||||
|           <interfacename>AccessDecisionManager</interfacename> that tallies votes differently. For | ||||
|         example, votes from a particular <interfacename>AccessDecisionVoter</interfacename> might | ||||
|         receive additional weighting, whilst a deny vote from a particular voter may have a veto | ||||
|         effect.</para> | ||||
|                 <interfacename>AccessDecisionManager</interfacename> that tallies votes differently. | ||||
|                 For example, votes from a particular | ||||
|                 <interfacename>AccessDecisionVoter</interfacename> might receive additional | ||||
|                 weighting, whilst a deny vote from a particular voter may have a veto effect.</para> | ||||
|             <section xml:id="authz-role-voter"> | ||||
|                 <title><classname>RoleVoter</classname></title> | ||||
|         <para> The most commonly used <interfacename>AccessDecisionVoter</interfacename> provided | ||||
|           with Spring Security is the simple <classname>RoleVoter</classname>, which treats | ||||
|           configuration attributes as simple role names and votes to grant access if the user has | ||||
|           been assigned that role.</para> | ||||
|         <para>It will vote if any <interfacename>ConfigAttribute</interfacename> begins with the | ||||
|           prefix <literal>ROLE_</literal>. It will vote to grant access if there is a | ||||
|                 <para> The most commonly used <interfacename>AccessDecisionVoter</interfacename> | ||||
|                     provided with Spring Security is the simple <classname>RoleVoter</classname>, | ||||
|                     which treats configuration attributes as simple role names and votes to grant | ||||
|                     access if the user has been assigned that role.</para> | ||||
|                 <para>It will vote if any <interfacename>ConfigAttribute</interfacename> begins with | ||||
|                     the prefix <literal>ROLE_</literal>. It will vote to grant access if there is a | ||||
|                     <interfacename>GrantedAuthority</interfacename> which returns a | ||||
|             <literal>String</literal> representation (via the <literal>getAuthority()</literal> | ||||
|           method) exactly equal to one or more <literal>ConfigAttributes</literal> starting with the | ||||
|           prefix <literal>ROLE_</literal>. If there is no exact match of any | ||||
|                     <literal>String</literal> representation (via the | ||||
|                     <literal>getAuthority()</literal> method) exactly equal to one or more | ||||
|                     <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>RoleVoter</literal> will vote to deny access. If no | ||||
|             <literal>ConfigAttribute</literal> begins with <literal>ROLE_</literal>, the voter will | ||||
|           abstain.</para> | ||||
|                     <literal>ConfigAttribute</literal> begins with <literal>ROLE_</literal>, the | ||||
|                     voter will abstain.</para> | ||||
|             </section> | ||||
|             <section xml:id="authz-authenticated-voter"> | ||||
|                 <title><classname>AuthenticatedVoter</classname></title> | ||||
|                 <para> Another voter which we've implicitly seen is the | ||||
|             <classname>AuthenticatedVoter</classname>, which can be used to differentiate between | ||||
|           anonymous, fully-authenticated and remember-me authenticated users. Many sites allow | ||||
|           certain limited access under remember-me authentication, but require 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 | ||||
|           anonymous access, this attribute was being processed by the | ||||
|             <classname>AuthenticatedVoter</classname>. See the Javadoc for this class for more | ||||
|           information. </para> | ||||
|                     <classname>AuthenticatedVoter</classname>, which can be used to differentiate | ||||
|                     between anonymous, fully-authenticated and remember-me authenticated users. Many | ||||
|                     sites allow certain limited access under remember-me authentication, but require | ||||
|                     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 anonymous access, this attribute was being processed by the | ||||
|                     <classname>AuthenticatedVoter</classname>. See the Javadoc for this class for | ||||
|                     more information. </para> | ||||
|             </section> | ||||
|             <section> | ||||
|                 <title>Custom Voters</title> | ||||
|                 <para>It is also possible to implement a custom | ||||
|             <interfacename>AccessDecisionVoter</interfacename>. Several examples are provided in | ||||
|           Spring Security unit tests, including <literal>ContactSecurityVoter</literal> and | ||||
|             <literal>DenyVoter</literal>. The <literal>ContactSecurityVoter</literal> abstains from | ||||
|           voting decisions where a <literal>CONTACT_OWNED_BY_CURRENT_USER</literal> | ||||
|                     <interfacename>AccessDecisionVoter</interfacename>. Several examples are | ||||
|                     provided in Spring Security unit tests, including | ||||
|                     <literal>ContactSecurityVoter</literal> and <literal>DenyVoter</literal>. The | ||||
|                     <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 | ||||
|                     <classname>MethodInvocation</classname> to extract the owner of the | ||||
|             <literal>Contact</literal> object that is subject of the method call. It votes to grant | ||||
|           access if the <literal>Contact</literal> owner matches the principal presented in the | ||||
|             <interfacename>Authentication</interfacename> object. It could have just as easily | ||||
|           compared the <literal>Contact</literal> owner with some | ||||
|                     <literal>Contact</literal> object that is subject of the method call. It votes | ||||
|                     to grant access if the <literal>Contact</literal> owner matches the principal | ||||
|                     presented in the <interfacename>Authentication</interfacename> object. It could | ||||
|                     have just as easily compared the <literal>Contact</literal> owner with some | ||||
|                     <interfacename>GrantedAuthority</interfacename> the | ||||
|             <interfacename>Authentication</interfacename> object presented. All of this is achieved | ||||
|           with relatively few lines of code and demonstrates the flexibility of the authorization | ||||
|           model.</para> | ||||
|                     <interfacename>Authentication</interfacename> object presented. All of this is | ||||
|                     achieved with relatively few lines of code and demonstrates the flexibility of | ||||
|                     the authorization model.</para> | ||||
|             </section> | ||||
|         </section> | ||||
|     </section> | ||||
|  | @ -188,43 +199,46 @@ boolean supports(Class clazz); | |||
|             <title>After Invocation Handling</title> | ||||
|         </info> | ||||
|         <para>Whilst the <interfacename>AccessDecisionManager</interfacename> is called by the | ||||
|         <classname>AbstractSecurityInterceptor</classname> before proceeding with the secure object | ||||
|       invocation, some applications need a way of modifying the object actually returned by the | ||||
|       secure object invocation. Whilst you could easily implement your own AOP concern to achieve | ||||
|       this, Spring Security provides a convenient hook that has several concrete implementations | ||||
|       that integrate with its ACL capabilities.</para> | ||||
|             <classname>AbstractSecurityInterceptor</classname> before proceeding with the secure | ||||
|             object invocation, some applications need a way of modifying the object actually | ||||
|             returned by the secure object invocation. Whilst you could easily implement your own AOP | ||||
|             concern to achieve this, Spring Security provides a convenient hook that has several | ||||
|             concrete implementations that integrate with its ACL capabilities.</para> | ||||
|         <para><xref linkend="authz-after-invocation"/> illustrates Spring Security's | ||||
|             <literal>AfterInvocationManager</literal> and its concrete implementations. <figure | ||||
|             xml:id="authz-after-invocation"> | ||||
|             <title>After Invocation Implementation</title> | ||||
|             <mediaobject> | ||||
|                 <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> | ||||
|             </mediaobject> | ||||
|             </figure></para> | ||||
|     <para>Like many other parts of Spring Security, <literal>AfterInvocationManager</literal> has a | ||||
|       single concrete implementation, <literal>AfterInvocationProviderManager</literal>, which polls | ||||
|       a list of <literal>AfterInvocationProvider</literal>s. Each | ||||
|         <literal>AfterInvocationProvider</literal> is allowed to modify the return object or throw | ||||
|       an <literal>AccessDeniedException</literal>. Indeed multiple providers can modify the object, | ||||
|       as the result of the previous provider is passed to the next in the list.</para> | ||||
|     <para>Please be aware that if you're using <literal>AfterInvocationManager</literal>, you will | ||||
|       still need configuration attributes that allow the | ||||
|         <para>Like many other parts of Spring Security, <literal>AfterInvocationManager</literal> | ||||
|             has a single concrete implementation, <literal>AfterInvocationProviderManager</literal>, | ||||
|             which polls a list of <literal>AfterInvocationProvider</literal>s. Each | ||||
|             <literal>AfterInvocationProvider</literal> is allowed to modify the return object or | ||||
|             throw an <literal>AccessDeniedException</literal>. Indeed multiple providers can modify | ||||
|             the object, as the result of the previous provider is passed to the next in the | ||||
|             list.</para> | ||||
|         <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 | ||||
|         <interfacename>AccessDecisionManager</interfacename> to allow an operation. If you're using | ||||
|       the typical Spring Security included <interfacename>AccessDecisionManager</interfacename> | ||||
|       implementations, having no configuration attributes defined for a particular secure method | ||||
|       invocation will cause each <interfacename>AccessDecisionVoter</interfacename> to abstain from | ||||
|       voting. In turn, if the <interfacename>AccessDecisionManager</interfacename> property | ||||
|             <interfacename>AccessDecisionManager</interfacename> to allow an operation. If you're | ||||
|             using the typical Spring Security included | ||||
|             <interfacename>AccessDecisionManager</interfacename> implementations, having no | ||||
|             configuration attributes defined for a particular secure method invocation will cause | ||||
|             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>AccessDeniedException</literal> will be thrown. You may avoid this potential issue | ||||
|       by either (i) setting "<literal>allowIfAllAbstainDecisions</literal>" to | ||||
|         <literal>true</literal> (although this is generally not recommended) or (ii) simply ensure | ||||
|       that there is at least one configuration attribute that an | ||||
|             <literal>AccessDeniedException</literal> will be thrown. You may avoid this potential | ||||
|             issue by either (i) setting "<literal>allowIfAllAbstainDecisions</literal>" to | ||||
|             <literal>true</literal> (although this is generally not recommended) or (ii) simply | ||||
|             ensure that there is at least one configuration attribute that an | ||||
|             <interfacename>AccessDecisionVoter</interfacename> will vote to grant access for. This | ||||
|       latter (recommended) approach is usually achieved through a <literal>ROLE_USER</literal> or | ||||
|         <literal>ROLE_AUTHENTICATED</literal> configuration attribute.</para> | ||||
|             latter (recommended) approach is usually achieved through a <literal>ROLE_USER</literal> | ||||
|             or <literal>ROLE_AUTHENTICATED</literal> configuration attribute.</para> | ||||
|         <!-- TODO: Move to ACL section and add reference here --> | ||||
|         <!-- | ||||
|     <section xml:id="after-invocation-acl-aware"> | ||||
|  |  | |||
|  | @ -27,11 +27,10 @@ | |||
|                 <title>Configuration</title> | ||||
|             </info> | ||||
|             <para>To implement HTTP Basic Authentication, you need to add a | ||||
|                     <literal>BasicAuthenticationFilter</literal> to your filter chain. The | ||||
|                 application context should contain <literal>BasicAuthenticationFilter</literal> and | ||||
|                 its required collaborator:</para> | ||||
|             <para> | ||||
|                 <programlisting language="xml"><![CDATA[ | ||||
|                 <literal>BasicAuthenticationFilter</literal> to your filter chain. The application | ||||
|                 context should contain <literal>BasicAuthenticationFilter</literal> and its required | ||||
|                 collaborator:</para> | ||||
|             <para> <programlisting language="xml"><![CDATA[ | ||||
| <bean id="basicAuthenticationFilter" | ||||
|   class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter"> | ||||
|   <property name="authenticationManager" ref="authenticationManager"/> | ||||
|  | @ -42,14 +41,13 @@ | |||
|   class="org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint"> | ||||
|   <property name="realmName" value="Name Of Your Realm"/> | ||||
| </bean>]]> | ||||
|                 </programlisting> | ||||
|             </para> | ||||
|                 </programlisting> </para> | ||||
|             <para>The configured <interfacename>AuthenticationManager</interfacename> processes each | ||||
|                 authentication request. If authentication fails, the configured | ||||
|                     <interfacename>AuthenticationEntryPoint</interfacename> will be used to retry | ||||
|                 the authentication process. Usually you will use the filter in combination with a | ||||
|                     <literal>BasicAuthenticationEntryPoint</literal>, which returns a 401 response | ||||
|                 with a suitable header to retry HTTP Basic authentication. If authentication is | ||||
|                 <interfacename>AuthenticationEntryPoint</interfacename> will be used to retry the | ||||
|                 authentication process. Usually you will use the filter in combination with a | ||||
|                 <literal>BasicAuthenticationEntryPoint</literal>, which returns a 401 response with | ||||
|                 a suitable header to retry HTTP Basic authentication. If authentication is | ||||
|                 successful, the resulting <interfacename>Authentication</interfacename> object will | ||||
|                 be placed into the <classname>SecurityContextHolder</classname> as usual.</para> | ||||
|             <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 | ||||
|   key:              A private key to prevent modification of the nonce token | ||||
|             </programlisting> | ||||
|         </para> | ||||
|             </programlisting> </para> | ||||
|         <para>The <classname>DigestAuthenticatonEntryPoint</classname> has a property specifying the | ||||
|             <literal>key</literal> used for generating the nonce tokens, along with a | ||||
|             <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 the server-generated nonce has merely expired (but the digest was otherwise valid), | ||||
|             the <classname>DigestAuthenticationEntryPoint</classname> will send a | ||||
|                 <literal>"stale=true"</literal> header. This tells the user agent there is no need | ||||
|             to disturb the user (as the password and username etc is correct), but simply to try | ||||
|             again using a new nonce.</para> | ||||
|             <literal>"stale=true"</literal> header. This tells the user agent there is no need to | ||||
|             disturb the user (as the password and username etc is correct), but simply to try again | ||||
|             using a new nonce.</para> | ||||
|         <para>An appropriate value for <classname>DigestAuthenticationEntryPoint</classname>'s | ||||
|             <literal>nonceValiditySeconds</literal> parameter will depend on your application. | ||||
|             Extremely secure applications should note that an intercepted authentication header can | ||||
|  | @ -120,12 +117,10 @@ | |||
|             <title>Configuration</title> | ||||
|             <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 | ||||
|                     <literal>DigestAuthenticationFilter</literal> in the filter chain. The | ||||
|                 application context will need to define the | ||||
|                     <literal>DigestAuthenticationFilter</literal> and its required | ||||
|                 collaborators:</para> | ||||
|             <para> | ||||
|                 <programlisting><![CDATA[ | ||||
|                 <literal>DigestAuthenticationFilter</literal> in the filter chain. The application | ||||
|                 context will need to define the <literal>DigestAuthenticationFilter</literal> and | ||||
|                 its required collaborators:</para> | ||||
|             <para> <programlisting><![CDATA[ | ||||
| <bean id="digestFilter" class= | ||||
|     "org.springframework.security.web.authentication.www.DigestAuthenticationFilter"> | ||||
|   <property name="userDetailsService" ref="jdbcDaoImpl"/> | ||||
|  | @ -139,11 +134,10 @@ | |||
|   <property name="key" value="acegi"/> | ||||
|   <property name="nonceValiditySeconds" value="10"/> | ||||
| </bean>]]> | ||||
|                 </programlisting> | ||||
|             </para> | ||||
|                 </programlisting> </para> | ||||
|             <para>The configured <interfacename>UserDetailsService</interfacename> is needed because | ||||
|                     <literal>DigestAuthenticationFilter</literal> must have direct access to the | ||||
|                 clear text password of a user. Digest Authentication will NOT work if you are using | ||||
|                 <literal>DigestAuthenticationFilter</literal> must have direct access to the clear | ||||
|                 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 | ||||
|                 <literal>UserCache</literal>, are typically shared directly with a | ||||
|                 <classname>DaoAuthenticationProvider</classname>. The | ||||
|  |  | |||
|  | @ -4,11 +4,11 @@ | |||
|     <section xml:id="cas-overview"> | ||||
|         <title>Overview</title> | ||||
|         <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 | ||||
|       understand, platform independent, and supports proxy capabilities. Spring Security fully | ||||
|       supports CAS, and provides an easy migration path from single-application deployments of | ||||
|       Spring Security through to multiple-application deployments secured by an enterprise-wide CAS | ||||
|       server.</para> | ||||
|             initiatives, JA-SIG's Central Authentication Service is open source, widely used, simple | ||||
|             to understand, platform independent, and supports proxy capabilities. Spring Security | ||||
|             fully supports CAS, and provides an easy migration path from single-application | ||||
|             deployments of Spring Security through to multiple-application deployments secured by an | ||||
|             enterprise-wide CAS server.</para> | ||||
|         <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> | ||||
|     </section> | ||||
|  | @ -16,28 +16,30 @@ | |||
|         <info> | ||||
|             <title>How CAS Works</title> | ||||
|         </info> | ||||
|     <para>Whilst the CAS web site contains documents that detail the architecture of CAS, we present | ||||
|       the general overview again here within the context of Spring Security. Spring Security 3.0 | ||||
|       supports CAS 3. At the time of writing, the CAS server was at version 3.3.</para> | ||||
|     <para>Somewhere in your enterprise you will need to setup a CAS server. The CAS server is simply | ||||
|       a standard WAR file, so there isn't anything difficult about setting up your server. Inside | ||||
|       the WAR file you will customise the login and other single sign on pages displayed to | ||||
|       users.</para> | ||||
|         <para>Whilst the CAS web site contains documents that detail the architecture of CAS, we | ||||
|             present the general overview again here within the context of Spring Security. Spring | ||||
|             Security 3.0 supports CAS 3. At the time of writing, the CAS server was at version | ||||
|             3.3.</para> | ||||
|         <para>Somewhere in your enterprise you will need to setup a CAS server. The CAS server is | ||||
|             simply a standard WAR file, so there isn't anything difficult about setting up your | ||||
|             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 | ||||
|             <literal>AuthenticationHandler</literal> in the | ||||
|             <filename>deployerConfigContext.xml</filename> included with CAS. The | ||||
|         <literal>AuthenticationHandler</literal> has a simple method that returns a boolean as to | ||||
|       whether a given set of Credentials is valid. Your <literal>AuthenticationHandler</literal> | ||||
|       implementation will need to link into some type of backend authentication repository, such as | ||||
|       an LDAP server or database. CAS itself includes numerous | ||||
|         <literal>AuthenticationHandler</literal>s out of the box to assist with this. When you | ||||
|       download and deploy the server war file, it is set up to successfully authenticate users who | ||||
|       enter a password matching their username, which is useful for testing.</para> | ||||
|             <literal>AuthenticationHandler</literal> has a simple method that returns a boolean as | ||||
|             to whether a given set of Credentials is valid. Your | ||||
|             <literal>AuthenticationHandler</literal> implementation will need to link into some type | ||||
|             of backend authentication repository, such as an LDAP server or database. CAS itself | ||||
|             includes numerous <literal>AuthenticationHandler</literal>s out of the box to assist | ||||
|             with this. When you download and deploy the server war file, it is set up to | ||||
|             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 | ||||
|             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 | ||||
|       service is able to request resources from other services on behalf of the user. This will be | ||||
|       explained more fully later.</para> | ||||
|             "services". There are two types of services: standard services and proxy services. A | ||||
|             proxy service is able to request resources from other services on behalf of the user. | ||||
|             This will be explained more fully later.</para> | ||||
|         <!-- | ||||
|   <section xml:id="cas-sequence"> | ||||
|     <title>Spring Security and CAS Interaction Sequence</title> | ||||
|  | @ -249,30 +251,28 @@ | |||
|             <title>Configuration of CAS Client</title> | ||||
|         </info> | ||||
|         <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 | ||||
|       assume a namespace based configuration is being used and add in the CAS beans as required. </para> | ||||
|     <para>You will need to add a <classname>ServiceProperties</classname> bean to your application | ||||
|       context. This represents your CAS service:</para> | ||||
|     <para> | ||||
|       <programlisting><![CDATA[ | ||||
|             already know the basics of using Spring Security, so these are not covered again below. | ||||
|             We'll assume a namespace based configuration is being used and add in the CAS beans as | ||||
|             required. </para> | ||||
|         <para>You will need to add a <classname>ServiceProperties</classname> bean to your | ||||
|             application context. This represents your CAS service:</para> | ||||
|         <para> <programlisting><![CDATA[ | ||||
|   <bean id="serviceProperties" | ||||
|         class="org.springframework.security.cas.ServiceProperties"> | ||||
|     <property name="service" | ||||
|         value="https://localhost:8443/cas-sample/j_spring_cas_security_check"/> | ||||
|     <property name="sendRenew" value="false"/> | ||||
|   </bean>]]> | ||||
|     </programlisting> | ||||
|     </para> | ||||
|     </programlisting> </para> | ||||
|         <para>The <literal>service</literal> must equal a URL that will be monitored by the | ||||
|             <literal>CasAuthenticationFilter</literal>. The <literal>sendRenew</literal> defaults to | ||||
|       false, but should be set to true if your application is particularly sensitive. What this | ||||
|       parameter does is tell the CAS login service that a single sign on login is unacceptable. | ||||
|       Instead, the user will need to re-enter their username and password in order to gain access to | ||||
|       the service.</para> | ||||
|             false, but should be set to true if your application is particularly sensitive. What | ||||
|             this parameter does is tell the CAS login service that a single sign on login is | ||||
|             unacceptable. Instead, the user will need to re-enter their username and password in | ||||
|             order to gain access to the service.</para> | ||||
|         <para>The following beans should be configured to commence the CAS authentication process | ||||
|             (assuming you're using a namespace configuration):</para> | ||||
|     <para> | ||||
|       <programlisting><![CDATA[ | ||||
|         <para> <programlisting><![CDATA[ | ||||
| <security:http entry-point-ref="casEntryPoint"> | ||||
|    ... | ||||
|    <custom-filter position="FORM_LOGIN_FILTER" ref="myFilter" /> | ||||
|  | @ -289,21 +289,22 @@ | |||
|   <property name="serviceProperties" ref="serviceProperties"/> | ||||
| </bean> | ||||
| ]]> | ||||
|     </programlisting> | ||||
|     </para> | ||||
|     </programlisting> </para> | ||||
|         <para> The <classname>CasAuthenticationEntryPoint</classname> should be selected to drive | ||||
|             authentication using <link xlink:href="ns-entry-point-ref" | ||||
|             ><literal>entry-point-ref</literal></link>. </para> | ||||
|         <para>The <classname>CasAuthenticationFilter</classname> has very similar properties to the | ||||
|         <classname>UsernamePasswordAuthenticationFilter</classname> (used for form-based logins). | ||||
|     </para> | ||||
|     <para>For CAS to operate, the <classname>ExceptionTranslationFilter</classname> must have its | ||||
|         <literal>authenticationEntryPoint</literal> property set to the | ||||
|             <classname>UsernamePasswordAuthenticationFilter</classname> (used for form-based | ||||
|             logins). </para> | ||||
|         <para>For CAS to operate, the <classname>ExceptionTranslationFilter</classname> must have | ||||
|             its <literal>authenticationEntryPoint</literal> property set to the | ||||
|             <classname>CasAuthenticationEntryPoint</classname> bean.</para> | ||||
|         <para>The <classname>CasAuthenticationEntryPoint</classname> must refer to the | ||||
|         <classname>ServiceProperties</classname> bean (discussed above), which provides the URL to the | ||||
|       enterprise's CAS login server. This is where the user's browser will be redirected.</para> | ||||
|     <para>Next you need to add a <literal>CasAuthenticationProvider</literal> and its collaborators: <programlisting><![CDATA[ | ||||
|             <classname>ServiceProperties</classname> bean (discussed above), which provides the URL | ||||
|             to the enterprise's CAS login server. This is where the user's browser will be | ||||
|             redirected.</para> | ||||
|         <para>Next you need to add a <literal>CasAuthenticationProvider</literal> and its | ||||
|             collaborators: <programlisting><![CDATA[ | ||||
|   <security:authentication-manager alias="authenticationManager"> | ||||
|     <security:authentication-provider ref="casAuthenticationProvider" /> | ||||
|   </security:authentication-manager> | ||||
|  | @ -327,7 +328,8 @@ | |||
|       </programlisting> The | ||||
|             <classname>CasAuthenticationProvider</classname> uses 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" | ||||
|             section.</para> | ||||
|     </section> | ||||
|  |  | |||
|  | @ -23,19 +23,18 @@ | |||
|             to HTTPS pages.</para> | ||||
|         <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 | ||||
|                 <literal>jsessionid</literal> is never sent across an insecure channel. You will | ||||
|             need to ensure your <literal>web.xml</literal>-defined | ||||
|                 <literal><welcome-file></literal> points to an HTTPS location, and the | ||||
|             application never directs the user to an HTTP location. Spring Security provides a | ||||
|             solution to assist with the latter.</para> | ||||
|             <literal>jsessionid</literal> is never sent across an insecure channel. You will need to | ||||
|             ensure your <literal>web.xml</literal>-defined <literal><welcome-file></literal> | ||||
|             points to an HTTPS location, and the application never directs the user to an HTTP | ||||
|             location. Spring Security provides a solution to assist with the latter.</para> | ||||
|     </section> | ||||
|     <section xml:id="channel-security-config"> | ||||
|         <info> | ||||
|             <title>Configuration</title> | ||||
|         </info> | ||||
|         <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 | ||||
|             the <literal><intercept-url></literal> element and this is the simplest (and | ||||
|             namespace</link> by means of the <literal>requires-channel</literal> attribute on the | ||||
|             <literal><intercept-url></literal> element and this is the simplest (and | ||||
|             recommended approach).</para> | ||||
|         <para>To configure channel security explicitly, you would define the following the filter in | ||||
|             your application context: <programlisting><![CDATA[ | ||||
|  | @ -75,13 +74,13 @@ | |||
|         <para>The <literal>ChannelProcessingFilter</literal> operates by filtering all web requests | ||||
|             and determining the configuration attributes that apply. It then delegates to the | ||||
|             <literal>ChannelDecisionManager</literal>. The default implementation, | ||||
|                 <literal>ChannelDecisionManagerImpl</literal>, should suffice in most cases. It | ||||
|             simply delegates to the list of configured <literal>ChannelProcessor</literal> | ||||
|             instances. The attribute <literal>ANY_CHANNEL</literal> can be used to override this | ||||
|             behaviour and skip a particular URL. Otherwise, a <literal>ChannelProcessor</literal> | ||||
|             will review the request, and if it is unhappy with the request (e.g. if it was received | ||||
|             across the incorrect transport protocol), it will perform a redirect, throw an exception | ||||
|             or take whatever other action is appropriate.</para> | ||||
|             <literal>ChannelDecisionManagerImpl</literal>, should suffice in most cases. It simply | ||||
|             delegates to the list of configured <literal>ChannelProcessor</literal> instances. The | ||||
|             attribute <literal>ANY_CHANNEL</literal> can be used to override this behaviour and skip | ||||
|             a particular URL. Otherwise, a <literal>ChannelProcessor</literal> will review the | ||||
|             request, and if it is unhappy with the request (e.g. if it was received across the | ||||
|             incorrect transport protocol), it will perform a redirect, throw an exception or take | ||||
|             whatever other action is appropriate.</para> | ||||
|         <para>Included with Spring Security are two concrete <literal>ChannelProcessor</literal> | ||||
|             implementations: <literal>SecureChannelProcessor</literal> ensures requests with a | ||||
|             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 | ||||
|             assigned to the <literal>ChannelProcessor</literal> implementations for the | ||||
|             configuration attribute keywords they respond to and the | ||||
|                 <interfacename>ChannelEntryPoint</interfacename> they delegate to, although you have | ||||
|             the ability to override these using the application context.</para> | ||||
|             <interfacename>ChannelEntryPoint</interfacename> they delegate to, although you have the | ||||
|             ability to override these using the application context.</para> | ||||
|         <para>Note that the redirections are absolute (eg | ||||
|             <literal>http://www.company.com:8080/app/page</literal>), not relative (eg | ||||
|                 <literal>/app/page</literal>). During testing it was discovered that Internet | ||||
|             Explorer 6 Service Pack 1 has a bug whereby it does not respond correctly to a | ||||
|             redirection instruction which also changes the port to use. Accordingly, absolute URLs | ||||
|             are used in conjunction with bug detection logic in the | ||||
|                 <classname>PortResolverImpl</classname> that is wired up by default to many Spring | ||||
|             Security beans. Please refer to the JavaDocs for <classname>PortResolverImpl</classname> | ||||
|             for further details.</para> | ||||
|             <literal>/app/page</literal>). During testing it was discovered that Internet Explorer 6 | ||||
|             Service Pack 1 has a bug whereby it does not respond correctly to a redirection | ||||
|             instruction which also changes the port to use. Accordingly, absolute URLs are used in | ||||
|             conjunction with bug detection logic in the <classname>PortResolverImpl</classname> that | ||||
|             is wired up by default to many Spring Security beans. Please refer to the JavaDocs for | ||||
|             <classname>PortResolverImpl</classname> for further details.</para> | ||||
|         <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 | ||||
|                 <classname>ChannelProcessingFilter</classname> with form-based login, please ensure | ||||
|             that your login page is set to <literal>REQUIRES_SECURE_CHANNEL</literal>, and that the | ||||
|             <classname>ChannelProcessingFilter</classname> with form-based login, please ensure that | ||||
|             your login page is set to <literal>REQUIRES_SECURE_CHANNEL</literal>, and that the | ||||
|             <literal>LoginUrlAuthenticationEntryPoint.forceHttps</literal> property is | ||||
|             <literal>true</literal>.</para> | ||||
|     </section> | ||||
|  | @ -118,13 +116,13 @@ | |||
|         <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). | ||||
|             Obviously you'll still need a way of making the initial request (probably via the | ||||
|                 <literal>web.xml</literal> | ||||
|             <literal><welcome-file></literal> or a well-known home page URL), but once this is | ||||
|             done the filter will perform redirects as defined by your application context.</para> | ||||
|             <literal>web.xml</literal> <literal><welcome-file></literal> or a well-known home | ||||
|             page URL), but once this is done the filter will perform redirects as defined by your | ||||
|             application context.</para> | ||||
|         <para>You can also add your own <literal>ChannelProcessor</literal> implementations to the | ||||
|             <literal>ChannelDecisionManagerImpl</literal>. For example, you might set a | ||||
|                 <literal>HttpSession</literal> attribute when a human user is detected via a "enter | ||||
|             the contents of this graphic" procedure. Your <literal>ChannelProcessor</literal> would | ||||
|             <literal>HttpSession</literal> attribute when a human user is detected via a "enter the | ||||
|             contents of this graphic" procedure. Your <literal>ChannelProcessor</literal> would | ||||
|             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 | ||||
|             <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 | ||||
|             authenticated requests. The latter therefore has access to the granted authorities of | ||||
|             the authenticated principal. In addition, problems detected by a | ||||
|                 <literal>ChannelProcessor</literal> will generally cause an HTTP/HTTPS redirection | ||||
|             so its requirements can be met, whilst problems detected by an | ||||
|             <literal>ChannelProcessor</literal> will generally cause an HTTP/HTTPS redirection so | ||||
|             its requirements can be met, whilst problems detected by an | ||||
|             <interfacename>AccessDecisionVoter</interfacename> will ultimately result in an | ||||
|             <literal>AccessDeniedException</literal> (depending on the governing | ||||
|             <interfacename>AccessDecisionManager</interfacename>).</para> | ||||
|  |  | |||
|  | @ -42,7 +42,7 @@ | |||
|         </info> | ||||
|         <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" | ||||
|                 >http://forum.springsource.org</uri> to discuss Spring Security with other users of | ||||
|             the framework. Remember to use JIRA for bug reports, as explained above.</para> | ||||
|             >http://forum.springsource.org</uri> to discuss Spring Security with other users of the | ||||
|             framework. Remember to use JIRA for bug reports, as explained above.</para> | ||||
|     </section> | ||||
| </chapter> | ||||
|  |  | |||
|  | @ -10,11 +10,11 @@ | |||
|         <para>We've already seen <classname>FilterSecurityInterceptor</classname> briefly when | ||||
|             discussing <link xlink:href="#tech-intro-access-control">access-control in | ||||
|             general</link>, and we've already used it with the namespace where the | ||||
|                 <literal><intercept-url></literal> elements are combined to configure it | ||||
|             internally. Now we'll see how to explicitly configure it for use with a | ||||
|             <literal><intercept-url></literal> elements are combined to configure it internally. | ||||
|             Now we'll see how to explicitly configure it for use with a | ||||
|             <classname>FilterChainProxy</classname>, along with its companion filter | ||||
|                 <classname>ExceptionTranslationFilter</classname>. A typical configuration example | ||||
|             is shown below: <programlisting language="xml"><![CDATA[ | ||||
|             <classname>ExceptionTranslationFilter</classname>. A typical configuration example is | ||||
|             shown below: <programlisting language="xml"><![CDATA[ | ||||
| <bean id="filterSecurityInterceptor" | ||||
|       class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor"> | ||||
|   <property name="authenticationManager" ref="authenticationManager"/> | ||||
|  | @ -31,33 +31,31 @@ | |||
|             <interfacename>AuthenticationManager</interfacename> and an | ||||
|             <interfacename>AccessDecisionManager</interfacename>. It is also supplied with | ||||
|             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> | ||||
|             in the technical introduction.</para> | ||||
|             xlink:href="#tech-intro-config-attributes">the original discussion on these</link> in | ||||
|             the technical introduction.</para> | ||||
|         <para>The <classname>FilterSecurityInterceptor</classname> can be configured with | ||||
|             configuration attributes in two ways. The first, which is shown above, is using the | ||||
|                 <literal><filter-security-metadata-source></literal> namespace element. This | ||||
|             is similar to the <literal><filter-chain-map></literal> used to configure a | ||||
|                 <classname>FilterChainProxy</classname> but the | ||||
|                 <literal><intercept-url></literal> child elements only use the | ||||
|                 <literal>pattern</literal> and <literal>access</literal> attributes. Commas are used | ||||
|             to delimit the different configuration attributes that apply to each HTTP URL. The | ||||
|             second option is to write your own | ||||
|             <literal><filter-security-metadata-source></literal> namespace element. This is | ||||
|             similar to the <literal><filter-chain-map></literal> used to configure a | ||||
|             <classname>FilterChainProxy</classname> but the <literal><intercept-url></literal> | ||||
|             child elements only use the <literal>pattern</literal> and <literal>access</literal> | ||||
|             attributes. Commas are used to delimit the different configuration attributes that apply | ||||
|             to each HTTP URL. The second option is to write your own | ||||
|             <interfacename>SecurityMetadataSource</interfacename>, but this is beyond the scope of | ||||
|             this document. Irrespective of the approach used, the | ||||
|             <interfacename>SecurityMetadataSource</interfacename> is responsible for returning a | ||||
|             <literal>List<ConfigAttribute></literal> containing all of the configuration | ||||
|             attributes associated with a single secure HTTP URL.</para> | ||||
|         <para>It should be noted that the | ||||
|                 <literal>FilterSecurityInterceptor.setSecurityMetadataSource()</literal> method | ||||
|             actually expects an instance of | ||||
|                 <interfacename>FilterSecurityMetadataSource</interfacename>. This is a marker | ||||
|             interface which subclasses <interfacename>SecurityMetadataSource</interfacename>. It | ||||
|             simply denotes the <interfacename>SecurityMetadataSource</interfacename> understands | ||||
|                 <classname>FilterInvocation</classname>s. In the interests of simplicity we'll | ||||
|             continue to refer to the | ||||
|                 <interfacename>FilterInvocationSecurityMetadataSource</interfacename> as a | ||||
|                 <interfacename>SecurityMetadataSource</interfacename>, as the distinction is of | ||||
|             little relevance to most users.</para> | ||||
|             <literal>FilterSecurityInterceptor.setSecurityMetadataSource()</literal> method actually | ||||
|             expects an instance of <interfacename>FilterSecurityMetadataSource</interfacename>. This | ||||
|             is a marker interface which subclasses | ||||
|             <interfacename>SecurityMetadataSource</interfacename>. It simply denotes the | ||||
|             <interfacename>SecurityMetadataSource</interfacename> understands | ||||
|             <classname>FilterInvocation</classname>s. In the interests of simplicity we'll continue | ||||
|             to refer to the <interfacename>FilterInvocationSecurityMetadataSource</interfacename> as | ||||
|             a <interfacename>SecurityMetadataSource</interfacename>, as the distinction is of little | ||||
|             relevance to most users.</para> | ||||
|         <para>The <interfacename>SecurityMetadataSource</interfacename> created by the namespace | ||||
|             syntax obtains the configuration attributes for a particular | ||||
|             <classname>FilterInvocation</classname> by matching the request URL against the | ||||
|  | @ -101,8 +99,7 @@ | |||
| --> | ||||
|     </section> | ||||
|     <section xml:id="exception-translation-filter"> | ||||
|         <title> | ||||
|             <classname>ExceptionTranslationFilter</classname></title> | ||||
|         <title> <classname>ExceptionTranslationFilter</classname></title> | ||||
|         <para>The <classname>ExceptionTranslationFilter</classname> sits above the | ||||
|             <classname>FilterSecurityInterceptor</classname> in the security filter stack. It | ||||
|             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 | ||||
|                 user requests a secure HTTP resource but they are not authenticated. An appropriate | ||||
|                 <exceptionname>AuthenticationException</exceptionname> or | ||||
|                     <exceptionname>AccessDeniedException</exceptionname> will be thrown by a | ||||
|                 security interceptor further down the call stack, triggering the | ||||
|                     <methodname>commence</methodname> method on the entry point. This does the job | ||||
|                 of presenting the appropriate response to the user so that authentication can begin. | ||||
|                 <exceptionname>AccessDeniedException</exceptionname> will be thrown by a security | ||||
|                 interceptor further down the call stack, triggering the | ||||
|                 <methodname>commence</methodname> method on the entry point. This does the job of | ||||
|                 presenting the appropriate response to the user so that authentication can begin. | ||||
|                 The one we've used here is <classname>LoginUrlAuthenticationEntryPoint</classname>, | ||||
|                 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 | ||||
|  | @ -153,32 +150,31 @@ | |||
|             <para>If an <exceptionname>AccessDeniedException</exceptionname> is thrown and a user | ||||
|                 has already been authenticated, then this means that an operation has been attempted | ||||
|                 for which they don't have enough permissions. In this case, | ||||
|                     <classname>ExceptionTranslationFilter</classname> will invoke a second strategy, | ||||
|                 the <interfacename>AccessDeniedHandler</interfacename>. By default, an | ||||
|                 <classname>ExceptionTranslationFilter</classname> will invoke a second strategy, the | ||||
|                 <interfacename>AccessDeniedHandler</interfacename>. By default, an | ||||
|                 <classname>AccessDeniedHandlerImpl</classname> is used, which just sends a 403 | ||||
|                 (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 | ||||
|                 forwards the request to <footnote> | ||||
|                     <para>We use a forward so that the SecurityContextHolder still contains details | ||||
|                         of the principal, which may be useful for displaying to the user. In old | ||||
|                         releases of Spring Security we relied upon the servlet container to handle a | ||||
|                         403 error message, which lacked this useful contextual information.</para> | ||||
|                 <para>We use a forward so that the SecurityContextHolder still contains details of | ||||
|                     the principal, which may be useful for displaying to the user. In old releases | ||||
|                     of Spring Security we relied upon the servlet container to handle a 403 error | ||||
|                     message, which lacked this useful contextual information.</para> | ||||
|                 </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 | ||||
|                 can implement the interface yourself and use your own implementation. </para> | ||||
|             <para>It's also possible to supply a custom | ||||
|                     <interfacename>AccessDeniedHandler</interfacename> when you're using the | ||||
|                 namespace to configure your application. See <link | ||||
|                     xlink:href="#nsa-access-denied-handler">the namespace appendix</link> for more | ||||
|                 details.</para> | ||||
|                 <interfacename>AccessDeniedHandler</interfacename> when you're using the namespace | ||||
|                 to configure your application. See <link xlink:href="#nsa-access-denied-handler">the | ||||
|                 namespace appendix</link> for more details.</para> | ||||
|         </section> | ||||
|     </section> | ||||
|     <section xml:id="security-context-persistence-filter"> | ||||
|         <title><classname>SecurityContextPersistenceFilter</classname></title> | ||||
|         <para> We covered the purpose of this all-important filter in the <link | ||||
|                 xlink:href="#tech-intro-sec-context-persistence">Technical Overview</link> chapter | ||||
|             so you might want to re-read that section at this point. Let's first take a look at how | ||||
|             you would configure it for use with a <classname>FilterChainProxy</classname>. A basic | ||||
|             xlink:href="#tech-intro-sec-context-persistence">Technical Overview</link> chapter so | ||||
|             you might want to re-read that section at this point. Let's first take a look at how you | ||||
|             would configure it for use with a <classname>FilterChainProxy</classname>. A basic | ||||
|             configuration only requires the bean itself <programlisting><![CDATA[ | ||||
| <bean id="securityContextPersistenceFilter" | ||||
|   class="org.springframework.security.web.context.SecurityContextPersistenceFilter"/> | ||||
|  | @ -208,16 +204,16 @@ public interface SecurityContextRepository { | |||
|                 <classname>HttpSessionSecurityContextRepository</classname>, which stores the | ||||
|                 security context as an <interfacename>HttpSession</interfacename> attribute <footnote> | ||||
|                 <para>In Spring Security 2.0 and earlier, this filter was called | ||||
|                             <classname>HttpSessionContextIntegrationFilter</classname> and performed | ||||
|                         all the work of storing the context was performed by the filter itself. If | ||||
|                         you were familiar with this class, then most of the configuration options | ||||
|                         which were available can now be found on | ||||
|                     <classname>HttpSessionContextIntegrationFilter</classname> and performed all the | ||||
|                     work of storing the context was performed by the filter itself. If you were | ||||
|                     familiar with this class, then most of the configuration options which were | ||||
|                     available can now be found on | ||||
|                     <classname>HttpSessionSecurityContextRepository</classname>. </para> | ||||
|                 </footnote>. The most important configuration parameter for this implementation is | ||||
|                 the <literal>allowSessionCreation</literal> property, which defaults to | ||||
|                     <literal>true</literal>, thus allowing the class to create a session if it needs | ||||
|                 one to store the security context for an authenticated user (it won't create one | ||||
|                 unless authentication has taken place and the contents of the security context have | ||||
|                 <literal>true</literal>, thus allowing the class to create a session if it needs one | ||||
|                 to store the security context for an authenticated user (it won't create one unless | ||||
|                 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 | ||||
|                 to <literal>false</literal>: <programlisting language="xml"><![CDATA[ | ||||
| <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 | ||||
|             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 | ||||
|                         <classname>AuthenticationProcessingFilter</classname> and the entry point | ||||
|                     was called <classname>AuthenticationProcessingFilterEntryPoint</classname>. | ||||
|                     Since the framework now supports many different forms of authentication, they | ||||
|                     have both been given more specific names in 3.0.</para> | ||||
|                 <classname>AuthenticationProcessingFilter</classname> and the entry point was called | ||||
|                 <classname>AuthenticationProcessingFilterEntryPoint</classname>. Since the framework | ||||
|                 now supports many different forms of authentication, they have both been given more | ||||
|                 specific names in 3.0.</para> | ||||
|             </footnote>. It also provides the implementation used by the | ||||
|                 <literal><form-login></literal> element from the namespace. There are three | ||||
|             stages required to configure it. <orderedlist> | ||||
|             <literal><form-login></literal> element from the namespace. There are three stages | ||||
|             required to configure it. <orderedlist> | ||||
|             <listitem> | ||||
|                     <para>Configure a <classname>LoginUrlAuthenticationEntryPoint</classname> with | ||||
|                         the URL of the login page, just as we did above, and set it on the | ||||
|                 <para>Configure a <classname>LoginUrlAuthenticationEntryPoint</classname> with the | ||||
|                     URL of the login page, just as we did above, and set it on the | ||||
|                     <classname>ExceptionTranslationFilter</classname>. </para> | ||||
|             </listitem> | ||||
|             <listitem> | ||||
|  | @ -260,17 +256,17 @@ class="org.springframework.security.web.context.SecurityContextPersistenceFilter | |||
|             </listitem> | ||||
|             <listitem> | ||||
|                 <para>Configure an instance of | ||||
|                             <classname>UsernamePasswordAuthenticationFilter</classname> in the | ||||
|                         application context</para> | ||||
|                     <classname>UsernamePasswordAuthenticationFilter</classname> in the application | ||||
|                     context</para> | ||||
|             </listitem> | ||||
|             <listitem> | ||||
|                     <para>Add the filter bean to your filter chain proxy (making sure you pay | ||||
|                         attention to the order). <!-- TODO: link --></para> | ||||
|                 <para>Add the filter bean to your filter chain proxy (making sure you pay attention | ||||
|                     to the order). <!-- TODO: link --></para> | ||||
|             </listitem> | ||||
|             </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 | ||||
|             by the filter (by default this is <literal>/j_spring_security_check</literal>). The | ||||
|             basic filter configuration looks something like this: <programlisting><![CDATA[ | ||||
|             <literal>j_password</literal> input fields, and posts to the URL that is monitored by | ||||
|             the filter (by default this is <literal>/j_spring_security_check</literal>). The basic | ||||
|             filter configuration looks something like this: <programlisting><![CDATA[ | ||||
| <bean id="authenticationFilter" class= | ||||
| "org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"> | ||||
|   <property name="authenticationManager" ref="authenticationManager"/> | ||||
|  | @ -280,38 +276,37 @@ class="org.springframework.security.web.context.SecurityContextPersistenceFilter | |||
|         <section xml:id="form-login-flow-handling"> | ||||
|             <title>Application Flow on Authentication Success and Failure</title> | ||||
|             <para> The filter calls the configured | ||||
|                     <interfacename>AuthenticationManager</interfacename> to process each | ||||
|                 authentication request. The destination following a successful authentication or an | ||||
|                 authentication failure is controlled by the | ||||
|                 <interfacename>AuthenticationManager</interfacename> to process each authentication | ||||
|                 request. The destination following a successful authentication or an authentication | ||||
|                 failure is controlled by the | ||||
|                 <interfacename>AuthenticationSuccessHandler</interfacename> and | ||||
|                 <interfacename>AuthenticationFailureHandler</interfacename> strategy interfaces, | ||||
|                 respectively. The filter has properties which allow you to set these so you can | ||||
|                 customize the behaviour completely <footnote> | ||||
|                     <para>In versions prior to 3.0, the application flow at this point had evolved | ||||
|                         to a 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. </para> | ||||
|                 <para>In versions prior to 3.0, the application flow at this point had evolved to a | ||||
|                     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. </para> | ||||
|                 </footnote>. Some standard implementations are supplied such as | ||||
|                 <classname>SimpleUrlAuthenticationSuccessHandler</classname>, | ||||
|                 <classname>SavedRequestAwareAuthenticationSuccessHandler</classname>, | ||||
|                 <classname>SimpleUrlAuthenticationFailureHandler</classname> and | ||||
|                     <classname>ExceptionMappingAuthenticationFailureHandler</classname>. Have a look | ||||
|                 at the Javadoc for these classes to see how they work. </para> | ||||
|                 <classname>ExceptionMappingAuthenticationFailureHandler</classname>. Have a look at | ||||
|                 the Javadoc for these classes to see how they work. </para> | ||||
|             <para>If authentication is successful, the resulting | ||||
|                 <interfacename>Authentication</interfacename> object will be placed into the | ||||
|                 <classname>SecurityContextHolder</classname>. The configured | ||||
|                     <interfacename>AuthenticationSuccessHandler</interfacename> will then be called | ||||
|                 to either redirect or forward the user to the appropriate destination. By default a | ||||
|                     <classname>SavedRequestAwareAuthenticationSuccessHandler</classname> is used, | ||||
|                 which means that the user will be redirected to the original destination they | ||||
|                 requested before they were asked to login. <note> | ||||
|                 <interfacename>AuthenticationSuccessHandler</interfacename> will then be called to | ||||
|                 either redirect or forward the user to the appropriate destination. By default a | ||||
|                 <classname>SavedRequestAwareAuthenticationSuccessHandler</classname> is used, which | ||||
|                 means that the user will be redirected to the original destination they requested | ||||
|                 before they were asked to login. <note> | ||||
|                 <para> The <classname>ExceptionTranslationFilter</classname> caches the original | ||||
|                         request a user makes. When the user authenticates, the request handler makes | ||||
|                         use of this cached request to obtain the original URL and redirect to it. | ||||
|                         The original request is then rebuilt and used as an alternative. </para> | ||||
|                     request a user makes. When the user authenticates, the request handler makes use | ||||
|                     of this cached request to obtain the original URL and redirect to it. The | ||||
|                     original request is then rebuilt and used as an alternative. </para> | ||||
|                 </note> If authentication fails, the configured | ||||
|                     <interfacename>AuthenticationFailureHandler</interfacename> will be invoked. | ||||
|             </para> | ||||
|                 <interfacename>AuthenticationFailureHandler</interfacename> will be invoked. </para> | ||||
|         </section> | ||||
|     </section> | ||||
| </chapter> | ||||
|  |  | |||
|  | @ -5,9 +5,9 @@ | |||
|         classes, let's take a closer look at one or two of the core interfaces and their | ||||
|         implementations, in particular the <interfacename>AuthenticationManager</interfacename>, | ||||
|         <interfacename>UserDetailsService</interfacename> and the | ||||
|             <interfacename>AccessDecisionManager</interfacename>. These crop up regularly throughout | ||||
|         the remainder of this document so it's important you know how they are configured and how | ||||
|         they operate. </para> | ||||
|         <interfacename>AccessDecisionManager</interfacename>. These crop up regularly throughout the | ||||
|         remainder of this document so it's important you know how they are configured and how they | ||||
|         operate. </para> | ||||
|     <section xml:id="core-services-authentication-manager"> | ||||
|         <title>The <interfacename>AuthenticationManager</interfacename>, | ||||
|             <classname>ProviderManager</classname> and | ||||
|  | @ -19,27 +19,25 @@ | |||
|         <para>The default implementation in Spring Security is called | ||||
|             <classname>ProviderManager</classname> and rather than handling the authentication | ||||
|             request itself, it delegates to a list of configured | ||||
|                 <classname>AuthenticationProvider</classname>s, each of which is queried in turn to | ||||
|             see if it can perform the authentication. Each provider will either throw an exception | ||||
|             or return a fully populated <interfacename>Authentication</interfacename> object. | ||||
|             Remember our good friends, <interfacename>UserDetails</interfacename> and | ||||
|             <classname>AuthenticationProvider</classname>s, each of which is queried in turn to see | ||||
|             if it can perform the authentication. Each provider will either throw an exception or | ||||
|             return a fully populated <interfacename>Authentication</interfacename> object. Remember | ||||
|             our good friends, <interfacename>UserDetails</interfacename> and | ||||
|             <interfacename>UserDetailsService</interfacename>? If not, head back to the previous | ||||
|             chapter and refresh your memory. The most common approach to verifying an authentication | ||||
|             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 | ||||
|             approach used by the <classname>DaoAuthenticationProvider</classname> (see below). The | ||||
|             loaded <interfacename>UserDetails</interfacename> object - and particularly the | ||||
|                 <literal>GrantedAuthority</literal>s it contains - will be used when building the | ||||
|             fully populated <interfacename>Authentication</interfacename> object which is returned | ||||
|             from a successful authentication and stored in the | ||||
|                 <classname>SecurityContext</classname>. </para> | ||||
|         <para> If you are using the namespace, an instance of | ||||
|                 <classname>ProviderManager</classname> is created and maintained internally, and | ||||
|             you add providers to it by using the namespace authentication provider elements | ||||
|             (see <link xlink:href="#ns-auth-manager">the namespace chapter</link>). In this | ||||
|             case, you should not declare a <classname>ProviderManager</classname> bean in your | ||||
|             application context. However, if you are not using the namespace then you would declare | ||||
|             it like so: <programlisting language="xml"><![CDATA[ | ||||
|             <literal>GrantedAuthority</literal>s it contains - will be used when building the fully | ||||
|             populated <interfacename>Authentication</interfacename> object which is returned from a | ||||
|             successful authentication and stored in the <classname>SecurityContext</classname>. </para> | ||||
|         <para> If you are using the namespace, an instance of <classname>ProviderManager</classname> | ||||
|             is created and maintained internally, and you add providers to it by using the namespace | ||||
|             authentication provider elements (see <link xlink:href="#ns-auth-manager">the namespace | ||||
|             chapter</link>). In this case, you should not declare a | ||||
|             <classname>ProviderManager</classname> bean in your application context. However, if you | ||||
|             are not using the namespace then you would declare it like so: <programlisting language="xml"><![CDATA[ | ||||
| <bean id="authenticationManager" | ||||
|      class="org.springframework.security.authentication.ProviderManager"> | ||||
|   <property name="providers"> | ||||
|  | @ -78,12 +76,12 @@ | |||
|             <para>The simplest <interfacename>AuthenticationProvider</interfacename> implemented by | ||||
|                 Spring Security is <literal>DaoAuthenticationProvider</literal>, which is also one | ||||
|                 of the earliest supported by the framework. It leverages a | ||||
|                     <interfacename>UserDetailsService</interfacename> (as a DAO) in order to lookup | ||||
|                 the username, password and <interfacename>GrantedAuthority</interfacename>s. It | ||||
|                 <interfacename>UserDetailsService</interfacename> (as a DAO) in order to lookup the | ||||
|                 username, password and <interfacename>GrantedAuthority</interfacename>s. It | ||||
|                 authenticates the user simply by comparing the password submitted in a | ||||
|                     <classname>UsernamePasswordAuthenticationToken</classname> against the one | ||||
|                 loaded by the <interfacename>UserDetailsService</interfacename>. Configuring the | ||||
|                 provider is quite simple: <programlisting language="xml"><![CDATA[ | ||||
|                 <classname>UsernamePasswordAuthenticationToken</classname> against the one loaded by | ||||
|                 the <interfacename>UserDetailsService</interfacename>. Configuring the provider is | ||||
|                 quite simple: <programlisting language="xml"><![CDATA[ | ||||
| <bean id="daoAuthenticationProvider" | ||||
|     class="org.springframework.security.authentication.dao.DaoAuthenticationProvider"> | ||||
|   <property name="userDetailsService" ref="inMemoryDaoImpl"/> | ||||
|  | @ -94,8 +92,8 @@ | |||
|                 <interfacename>PasswordEncoder</interfacename> provides encoding and decoding of | ||||
|                 passwords presented in the <interfacename>UserDetails</interfacename> object that is | ||||
|                 returned from the configured <interfacename>UserDetailsService</interfacename>. A | ||||
|                     <interfacename>SaltSource</interfacename> enables the passwords to be populated | ||||
|                 with a "salt", which enhances the security of the passwords in the authentication | ||||
|                 <interfacename>SaltSource</interfacename> enables the passwords to be populated with | ||||
|                 a "salt", which enhances the security of the passwords in the authentication | ||||
|                 repository. These will be discussed in more detail <link | ||||
|                 xlink:href="core-services-password-encodin">below</link>. </para> | ||||
|         </section> | ||||
|  | @ -104,23 +102,21 @@ | |||
|         <title><interfacename>UserDetailsService</interfacename> Implementations</title> | ||||
|         <para>As mentioned in the earlier in this reference guide, most authentication providers | ||||
|             take advantage of the <interfacename>UserDetails</interfacename> and | ||||
|                 <interfacename>UserDetailsService</interfacename> interfaces. Recall that the | ||||
|             contract for <interfacename>UserDetailsService</interfacename> is a single | ||||
|             method:</para> | ||||
|             <interfacename>UserDetailsService</interfacename> interfaces. Recall that the contract | ||||
|             for <interfacename>UserDetailsService</interfacename> is a single method:</para> | ||||
|         <para> | ||||
|             <programlisting> | ||||
|   UserDetails loadUserByUsername(String username) throws UsernameNotFoundException; | ||||
|             </programlisting> | ||||
|         </para> | ||||
|             </programlisting> </para> | ||||
|         <para>The returned <interfacename>UserDetails</interfacename> is an interface that provides | ||||
|             getters that guarantee non-null provision of authentication information such as the | ||||
|             username, password, granted authorities and whether the user account is enabled or | ||||
|             disabled. Most authentication providers will use a | ||||
|                 <interfacename>UserDetailsService</interfacename>, even if the username and password | ||||
|             are not actually used as part of the authentication decision. They may use the returned | ||||
|             <interfacename>UserDetailsService</interfacename>, even if the username and password are | ||||
|             not actually used as part of the authentication decision. They may use the returned | ||||
|             <interfacename>UserDetails</interfacename> object just for its | ||||
|                 <literal>GrantedAuthority</literal> information, because some other system (like | ||||
|             LDAP or X.509 or CAS etc) has undertaken the responsibility of actually validating the | ||||
|             <literal>GrantedAuthority</literal> information, because some other system (like LDAP or | ||||
|             X.509 or CAS etc) has undertaken the responsibility of actually validating the | ||||
|             credentials.</para> | ||||
|         <para>Given <interfacename>UserDetailsService</interfacename> is so simple to implement, it | ||||
|             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 | ||||
|                 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 | ||||
|                     <interfacename>UserDetailsService</interfacename> implementations. For this sort | ||||
|                 of situation, a simple option is to use the <literal>user-service</literal> element | ||||
|                 <interfacename>UserDetailsService</interfacename> implementations. For this sort of | ||||
|                 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[ | ||||
|   <user-service id="userDetailsService"> | ||||
|     <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 | ||||
|                 relational mapper (ORM) just to store user details. If your application does use an | ||||
|                 ORM tool, you might prefer to write a custom | ||||
|                     <interfacename>UserDetailsService</interfacename> to reuse the mapping files | ||||
|                 you've probably already created. Returning to <literal>JdbcDaoImpl</literal>, an | ||||
|                 example configuration is shown below:</para> | ||||
|             <para> | ||||
|                 <programlisting language="xml"><![CDATA[ | ||||
|                 <interfacename>UserDetailsService</interfacename> to reuse the mapping files you've | ||||
|                 probably already created. Returning to <literal>JdbcDaoImpl</literal>, an example | ||||
|                 configuration is shown below:</para> | ||||
|             <para> <programlisting language="xml"><![CDATA[ | ||||
| <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> | ||||
|   <property name="driverClassName" value="org.hsqldb.jdbcDriver"/> | ||||
|   <property name="url" value="jdbc:hsqldb:hsql://localhost:9001"/> | ||||
|  | @ -173,19 +168,17 @@ | |||
| <bean id="userDetailsService" | ||||
|       class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl"> | ||||
|   <property name="dataSource" ref="dataSource"/> | ||||
| </bean> ]]>       </programlisting> | ||||
|             </para> | ||||
| </bean> ]]>       </programlisting> </para> | ||||
|             <para>You can use different relational database management systems by modifying the | ||||
|                     <literal>DriverManagerDataSource</literal> shown above. You can also use a | ||||
|                 global data source obtained from JNDI, as with any other Spring | ||||
|                 configuration.</para> | ||||
|                 <literal>DriverManagerDataSource</literal> shown above. You can also use a global | ||||
|                 data source obtained from JNDI, as with any other Spring configuration.</para> | ||||
|             <section> | ||||
|                 <title>Authority Groups</title> | ||||
|                 <para>By default, <classname>JdbcDaoImpl</classname> loads the authorities for a | ||||
|                     single user with the assumption that the authorities are mapped directly to | ||||
|                     users (see the <link xlink:href="#appendix-schema">database schema | ||||
|                         appendix</link>). An alternative approach is to partition the authorities | ||||
|                     into groups and assign groups to the user. Some people prefer this approach as a | ||||
|                     appendix</link>). An alternative approach is to partition the authorities into | ||||
|                     groups and assign groups to the user. Some people prefer this approach as a | ||||
|                     means of administering user rights. See the <classname>JdbcDaoImpl</classname> | ||||
|                     Javadoc for more information on how to enable the use of group authorities. The | ||||
|                     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 | ||||
|                 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 | ||||
|                     <literal>5f4dcc3b5aa765d61d8327deb882cf99</literal> using google, you will | ||||
|                 quickly find the original word <quote>password</quote>. In a similar way, an | ||||
|                 attacker can build a dictionary of hashes from a standard word list and use this to | ||||
|                 lookup the original password. One way to help prevent this is to have a suitably | ||||
|                 strong password policy to try to prevent common words from being used. Another is to | ||||
|                 use a <quote>salt</quote> when calculating the hashes. This is an additional string | ||||
|                 of known data for each user which is combined with the password before calculating | ||||
|                 the hash. Ideally the data should be as random as possible, but in practice any salt | ||||
|                 <literal>5f4dcc3b5aa765d61d8327deb882cf99</literal> using google, you will quickly | ||||
|                 find the original word <quote>password</quote>. In a similar way, an attacker can | ||||
|                 build a dictionary of hashes from a standard word list and use this to lookup the | ||||
|                 original password. One way to help prevent this is to have a suitably strong | ||||
|                 password policy to try to prevent common words from being used. Another is to use a | ||||
|                 <quote>salt</quote> when calculating the hashes. This is an additional string of | ||||
|                 known data for each user which is combined with the password before calculating the | ||||
|                 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 | ||||
|                 <interfacename>SaltSource</interfacename> interface which can be used by an | ||||
|                 authentication provider to generate a salt value for a particular user. Using a salt | ||||
|  | @ -248,31 +241,31 @@ | |||
|         <section> | ||||
|             <title> Hashing and Authentication</title> | ||||
|             <para>When an authentication provider (such as Spring Security's | ||||
|                     <classname>DaoAuthenticationProvider</classname> needs to check the password in | ||||
|                 a submitted authentication request against the known value for a user, and the | ||||
|                 stored password is encoded in some way, then the submitted value must be encoded | ||||
|                 using exactly the same algorithm. It's up to you to check that these are compatible | ||||
|                 as Spring Security has no control over the persistent values. If you add password | ||||
|                 <classname>DaoAuthenticationProvider</classname> needs to check the password in a | ||||
|                 submitted authentication request against the known value for a user, and the stored | ||||
|                 password is encoded in some way, then the submitted value must be encoded using | ||||
|                 exactly the same algorithm. It's up to you to check that these are compatible as | ||||
|                 Spring Security has no control over the persistent values. If you add password | ||||
|                 hashing to your authentication configuration in Spring Security, and your database | ||||
|                 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 | ||||
|                 example, and your application is configured to use Spring Security's | ||||
|                     <classname>Md5PasswordEncoder</classname>, there are still things that can go | ||||
|                 wrong. 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 | ||||
|                         the encoder to use Base 64 instead of hex by setting the | ||||
|                             <literal>encodeHashAsBase64</literal> property to | ||||
|                             <literal>true</literal>. Check the Javadoc for | ||||
|                             <classname>MessageDigestPasswordEncoder</classname> and its parent | ||||
|                         classes for more information.</para></footnote>. Alternatively your database | ||||
|                 may be using upper-case while the output from the encoder is lower-case. Make sure | ||||
|                 you write a test to check the output from your configured password encoder with a | ||||
|                 known password and salt combination and check that it matches the database value | ||||
|                 before going further and attempting to authenticate through your application. For | ||||
|                 more information on the default method for merging salt and password, see the | ||||
|                 Javadoc for <classname>BasePasswordEncoder</classname>. If you want to generate | ||||
|                 encoded passwords directly in Java for storage in your user database, then you can | ||||
|                 use the <methodname>encodePassword</methodname> method on the | ||||
|                 <classname>Md5PasswordEncoder</classname>, there are still things that can go wrong. | ||||
|                 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 the encoder to use Base 64 instead of hex by setting the | ||||
|                     <literal>encodeHashAsBase64</literal> property to <literal>true</literal>. Check | ||||
|                     the Javadoc for <classname>MessageDigestPasswordEncoder</classname> and its | ||||
|                     parent classes for more information.</para> | ||||
|                 </footnote>. Alternatively your database may be using upper-case while the output | ||||
|                 from the encoder is lower-case. Make sure you write a test to check the output from | ||||
|                 your configured password encoder with a known password and salt combination and | ||||
|                 check that it matches the database value before going further and attempting to | ||||
|                 authenticate through your application. For more information on the default method | ||||
|                 for merging salt and password, see the Javadoc for | ||||
|                 <classname>BasePasswordEncoder</classname>. If you want to generate encoded | ||||
|                 passwords directly in Java for storage in your user database, then you can use the | ||||
|                 <methodname>encodePassword</methodname> method on the | ||||
|                 <interfacename>PasswordEncoder</interfacename>.</para> | ||||
|         </section> | ||||
|     </section> | ||||
|  |  | |||
|  | @ -8,8 +8,8 @@ | |||
|         </info> | ||||
|         <para>Spring Security includes a production-quality | ||||
|             <classname>AuthenticationProvider</classname> implementation called | ||||
|                 <literal>DaoAuthenticationProvider</literal>. This authentication provider is | ||||
|             compatible with all of the authentication mechanisms that generate a | ||||
|             <literal>DaoAuthenticationProvider</literal>. This authentication provider is compatible | ||||
|             with all of the authentication mechanisms that generate a | ||||
|             <literal>UsernamePasswordAuthenticationToken</literal>, and is probably the most | ||||
|             commonly used provider in the framework. Like most of the other authentication | ||||
|             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 | ||||
|             authentication mechanism is configured to present a UsernamePasswordAuthenticationToken, | ||||
|             the configuration of the provider itself is rather simple:</para> | ||||
|         <para> | ||||
|             <programlisting> | ||||
|         <para> <programlisting> | ||||
|         <![CDATA[ | ||||
| <bean id="daoAuthenticationProvider" | ||||
|     class="org.springframework.security.authentication.dao.DaoAuthenticationProvider"> | ||||
|  | @ -36,14 +35,13 @@ | |||
|   <property name="saltSource" ref bean="saltSource"/> | ||||
|   <property name="passwordEncoder" ref="passwordEncoder"/> | ||||
| </bean>  ]]> | ||||
|     </programlisting> | ||||
|         </para> | ||||
|     </programlisting> </para> | ||||
|         <para>The <literal>PasswordEncoder</literal> and <literal>SaltSource</literal> are optional. | ||||
|             A <literal>PasswordEncoder</literal> provides encoding and decoding of passwords | ||||
|             presented in the <interfacename>UserDetails</interfacename> object that is returned from | ||||
|             the configured <interfacename>UserDetailsService</interfacename>. A | ||||
|                 <literal>SaltSource</literal> enables the passwords to be populated with a "salt", | ||||
|             which enhances the security of the passwords in the authentication repository. | ||||
|             <literal>SaltSource</literal> enables the passwords to be populated with a "salt", which | ||||
|             enhances the security of the passwords in the authentication repository. | ||||
|             <literal>PasswordEncoder</literal> implementations are provided with Spring Security | ||||
|             covering MD5, SHA and cleartext encodings. Two <literal>SaltSource</literal> | ||||
|             implementations are also provided: <literal>SystemWideSaltSource</literal> which encodes | ||||
|  | @ -55,14 +53,12 @@ | |||
|             supports optional caching of <interfacename>UserDetails</interfacename> objects. The | ||||
|             <literal>UserCache</literal> interface enables the | ||||
|             <literal>DaoAuthenticationProvider</literal> to place a | ||||
|                 <interfacename>UserDetails</interfacename> object into the cache, and retrieve it | ||||
|             from the cache upon subsequent authentication attempts for the same username. By default | ||||
|             the <literal>DaoAuthenticationProvider</literal> uses the | ||||
|                 <literal>NullUserCache</literal>, which performs no caching. A usable caching | ||||
|             implementation is also provided, <literal>EhCacheBasedUserCache</literal>, which is | ||||
|             configured as follows:</para> | ||||
|         <para> | ||||
|             <programlisting><![CDATA[ | ||||
|             <interfacename>UserDetails</interfacename> object into the cache, and retrieve it from | ||||
|             the cache upon subsequent authentication attempts for the same username. By default the | ||||
|             <literal>DaoAuthenticationProvider</literal> uses the <literal>NullUserCache</literal>, | ||||
|             which performs no caching. A usable caching implementation is also provided, | ||||
|             <literal>EhCacheBasedUserCache</literal>, which is configured as follows:</para> | ||||
|         <para> <programlisting><![CDATA[ | ||||
| <bean id="daoAuthenticationProvider" | ||||
|     class="org.springframework.security.authentication.dao.DaoAuthenticationProvider"> | ||||
|   <property name="userDetailsService" ref="userDetailsService"/> | ||||
|  | @ -82,15 +78,14 @@ | |||
|     class="org.springframework.security.core.userdetails.cache.EhCacheBasedUserCache"> | ||||
|   <property name="cache" ref="userCacheBackend"/> | ||||
| </bean>]]> | ||||
|     </programlisting> | ||||
|         </para> | ||||
|     </programlisting> </para> | ||||
|         <para>All Spring Security EH-CACHE implementations (including | ||||
|                 <literal>EhCacheBasedUserCache</literal>) require an EH-CACHE | ||||
|                 <literal>Cache</literal> object. The <literal>Cache</literal> object can be obtained | ||||
|             from wherever you like, although we recommend you use Spring's factory classes as shown | ||||
|             in the above configuration. If using Spring's factory classes, please refer to the | ||||
|             Spring documentation for further details on how to optimise the cache storage location, | ||||
|             memory usage, eviction policies, timeouts etc.</para> | ||||
|             <literal>EhCacheBasedUserCache</literal>) require an EH-CACHE <literal>Cache</literal> | ||||
|             object. The <literal>Cache</literal> object can be obtained from wherever you like, | ||||
|             although we recommend you use Spring's factory classes as shown in the above | ||||
|             configuration. If using Spring's factory classes, please refer to the Spring | ||||
|             documentation for further details on how to optimise the cache storage location, memory | ||||
|             usage, eviction policies, timeouts etc.</para> | ||||
|         <note> | ||||
|             <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 | ||||
|  |  | |||
|  | @ -9,9 +9,9 @@ | |||
|         <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 | ||||
|             comprise both who (<interfacename>Authentication</interfacename>), where | ||||
|             (<classname>MethodInvocation</classname>) and what (<literal>SomeDomainObject</literal>). In | ||||
|             other words, authorization decisions also need to consider the actual domain object | ||||
|             instance subject of a method invocation.</para> | ||||
|             (<classname>MethodInvocation</classname>) and what | ||||
|             (<literal>SomeDomainObject</literal>). In other words, authorization decisions also need | ||||
|             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 | ||||
|             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 | ||||
|  | @ -29,42 +29,42 @@ | |||
|                     object.</para> | ||||
|             </listitem> | ||||
|             <listitem> | ||||
|                     <para>Write an <interfacename>AccessDecisionVoter</interfacename> to enforce the security | ||||
|                         from the <literal>GrantedAuthority[]</literal>s stored in the | ||||
|                 <para>Write an <interfacename>AccessDecisionVoter</interfacename> to enforce the | ||||
|                     security from the <literal>GrantedAuthority[]</literal>s stored in the | ||||
|                     <interfacename>Authentication</interfacename> object. This would mean your | ||||
|                     <interfacename>AuthenticationManager</interfacename> would need to populate the | ||||
|                     <interfacename>Authentication</interfacename> with custom | ||||
|                     <interfacename>GrantedAuthority</interfacename>[]s representing each of the | ||||
|                             <literal>Customer</literal> domain object instances the principal has | ||||
|                         access to.</para> | ||||
|                     <literal>Customer</literal> domain object instances the principal has access | ||||
|                     to.</para> | ||||
|             </listitem> | ||||
|             <listitem> | ||||
|                     <para>Write an <interfacename>AccessDecisionVoter</interfacename> to enforce the security | ||||
|                         and open the target <literal>Customer</literal> domain object directly. This | ||||
|                         would mean your voter needs access to a DAO that allows it to retrieve the | ||||
|                 <para>Write an <interfacename>AccessDecisionVoter</interfacename> to enforce the | ||||
|                     security and open the target <literal>Customer</literal> domain object directly. | ||||
|                     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's collection of approved users and | ||||
|                         make the appropriate decision.</para> | ||||
|                     <literal>Customer</literal> object's collection of approved users and make the | ||||
|                     appropriate decision.</para> | ||||
|             </listitem> | ||||
|             </orderedlist></para> | ||||
|         <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 | ||||
|             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>GrantedAuthority[]</literal>s from the <interfacename>Authentication</interfacename> | ||||
|             object is also fine, but will not scale to large numbers of | ||||
|             <literal>Customer</literal>s. If a user might be able to access 5,000 | ||||
|             <literal>GrantedAuthority[]</literal>s from the | ||||
|             <interfacename>Authentication</interfacename> object is also fine, but will not scale to | ||||
|             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 | ||||
|             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, | ||||
|             opening the <literal>Customer</literal> directly from external code, is probably the | ||||
|             best of the three. It achieves separation of concerns, and doesn't misuse memory or CPU | ||||
|             cycles, but it is still inefficient in that both the | ||||
|             <interfacename>AccessDecisionVoter</interfacename> and the eventual business method itself will | ||||
|             perform a call to the DAO responsible for retrieving the <literal>Customer</literal> | ||||
|             object. Two accesses per method invocation is clearly undesirable. In addition, with | ||||
|             every approach listed you'll need to write your own access control list (ACL) | ||||
|             persistence and business logic from scratch.</para> | ||||
|             the <interfacename>Authentication</interfacename> object would be undesirable. The final | ||||
|             method, opening the <literal>Customer</literal> directly from external code, is probably | ||||
|             the best of the three. It achieves separation of concerns, and doesn't misuse memory or | ||||
|             CPU cycles, but it is still inefficient in that both the | ||||
|             <interfacename>AccessDecisionVoter</interfacename> and the eventual business method | ||||
|             itself will perform a call to the DAO responsible for retrieving the | ||||
|             <literal>Customer</literal> object. Two accesses per method invocation is clearly | ||||
|             undesirable. In addition, with every approach listed you'll need to write your own | ||||
|             access control list (ACL) persistence and business logic from scratch.</para> | ||||
|         <para>Fortunately, there is another alternative, which we'll talk about below.</para> | ||||
|     </section> | ||||
|     <section xml:id="domain-acls-key-concepts"> | ||||
|  | @ -83,12 +83,12 @@ | |||
|                     (and modifying those ACLs)</para> | ||||
|             </listitem> | ||||
|             <listitem> | ||||
|                     <para>A way of ensuring a given principal is permitted to work with your | ||||
|                         objects, before methods are called</para> | ||||
|                 <para>A way of ensuring a given principal is permitted to work with your objects, | ||||
|                     before methods are called</para> | ||||
|             </listitem> | ||||
|             <listitem> | ||||
|                     <para>A way of ensuring a given principal is permitted to work with your objects | ||||
|                         (or something they return), after methods are called</para> | ||||
|                 <para>A way of ensuring a given principal is permitted to work with your objects (or | ||||
|                     something they return), after methods are called</para> | ||||
|             </listitem> | ||||
|             </itemizedlist></para> | ||||
|         <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 | ||||
|             order of size in a typical Spring Security ACL deployment, with the table with the most | ||||
|             rows listed last:</para> | ||||
|         <para> | ||||
|             <itemizedlist> | ||||
|         <para> <itemizedlist> | ||||
|             <listitem> | ||||
|                 <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, | ||||
|                         a textual representation of the SID, and a flag to indicate whether the | ||||
|                         textual representation refers to a principal name or a | ||||
|                     system ("SID" stands for "security identity"). The only columns are the ID, a | ||||
|                     textual representation of the SID, and a flag to indicate whether the textual | ||||
|                     representation refers to a principal name or a | ||||
|                     <interfacename>GrantedAuthority</interfacename>. Thus, there is a single row for | ||||
|                         each unique principal or <interfacename>GrantedAuthority</interfacename>. When used in | ||||
|                         the context of receiving a permission, a SID is generally called a | ||||
|                     each unique principal or <interfacename>GrantedAuthority</interfacename>. When | ||||
|                     used in the context of receiving a permission, a SID is generally called a | ||||
|                     "recipient".</para> | ||||
|             </listitem> | ||||
|             <listitem> | ||||
|                 <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 | ||||
|                         a single row for each unique Class we wish to store ACL permissions | ||||
|                     for.</para> | ||||
|                     system. The only columns are the ID and the Java class name. Thus, there is a | ||||
|                     single row for each unique Class we wish to store ACL permissions for.</para> | ||||
|             </listitem> | ||||
|             <listitem> | ||||
|                     <para>ACL_OBJECT_IDENTITY stores information for each unique domain object | ||||
|                         instance in the system. Columns include the ID, a foreign key to the | ||||
|                         ACL_CLASS table, a unique identifier so we know which ACL_CLASS instance | ||||
|                         we're providing information for, the parent, a foreign key to the ACL_SID | ||||
|                         table to represent the owner of the domain object instance, and whether we | ||||
|                         allow ACL entries to inherit from any parent ACL. We have a single row for | ||||
|                         every domain object instance we're storing ACL permissions for.</para> | ||||
|                 <para>ACL_OBJECT_IDENTITY stores information for each unique domain object instance | ||||
|                     in the system. Columns include the ID, a foreign key to the ACL_CLASS table, a | ||||
|                     unique identifier so we know which ACL_CLASS instance we're providing | ||||
|                     information for, the parent, a foreign key to the ACL_SID table to represent the | ||||
|                     owner of the domain object instance, and whether we allow ACL entries to inherit | ||||
|                     from any parent ACL. We have a single row for every domain object instance we're | ||||
|                     storing ACL permissions for.</para> | ||||
|             </listitem> | ||||
|             <listitem> | ||||
|                 <para>Finally, ACL_ENTRY stores the individual permissions assigned to each | ||||
|                     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, | ||||
|                         and the integer bit mask that represents the actual permission being granted | ||||
|                         or denied. We have a single row for every recipient that receives a | ||||
|                         permission to work with a domain object.</para> | ||||
|                     recipient (ie a foreign key to ACL_SID), whether we'll be auditing or not, and | ||||
|                     the integer bit mask that represents the actual permission being granted or | ||||
|                     denied. We have a single row for every recipient that receives a permission to | ||||
|                     work with a domain object.</para> | ||||
|             </listitem> | ||||
|             </itemizedlist> | ||||
|         </para> | ||||
|             </itemizedlist> </para> | ||||
|         <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, | ||||
|             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 | ||||
|                     <literal>Acl</literal> object, which internally holds 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, | ||||
|                     but instead to an <literal>ObjectIdentity</literal>. The <literal>Acl</literal> | ||||
|                     is stored in the ACL_OBJECT_IDENTITY table.</para> | ||||
|                     <literal>Acl</literal>. An Acl does not refer directly to the domain object, but | ||||
|                     instead to an <literal>ObjectIdentity</literal>. The <literal>Acl</literal> is | ||||
|                     stored in the ACL_OBJECT_IDENTITY table.</para> | ||||
|             </listitem> | ||||
|             <listitem> | ||||
|                 <para><literal>AccessControlEntry</literal>: An <literal>Acl</literal> holds | ||||
|  | @ -183,11 +180,11 @@ | |||
|             </listitem> | ||||
|             <listitem> | ||||
|                 <para><literal>Sid</literal>: The ACL module needs to refer to principals and | ||||
|                         <literal>GrantedAuthority[]</literal>s. A level of indirection is provided | ||||
|                     by the <literal>Sid</literal> interface, which is an abbreviation of "security | ||||
|                     <literal>GrantedAuthority[]</literal>s. A level of indirection is provided by | ||||
|                     the <literal>Sid</literal> interface, which is an abbreviation of "security | ||||
|                     identity". Common classes include <literal>PrincipalSid</literal> (to represent | ||||
|                     the principal inside an <interfacename>Authentication</interfacename> object) and | ||||
|                         <literal>GrantedAuthoritySid</literal>. The security identity information is | ||||
|                     the principal inside an <interfacename>Authentication</interfacename> object) | ||||
|                     and <literal>GrantedAuthoritySid</literal>. The security identity information is | ||||
|                     stored in the ACL_SID table.</para> | ||||
|             </listitem> | ||||
|             <listitem> | ||||
|  | @ -227,15 +224,14 @@ | |||
|             ACL information somewhere. This necessitates the instantiation of a | ||||
|             <literal>DataSource</literal> using Spring. The <literal>DataSource</literal> is then | ||||
|             injected into a <literal>JdbcMutableAclService</literal> and | ||||
|                 <literal>BasicLookupStrategy</literal> instance. The latter provides | ||||
|             high-performance ACL retrieval capabilities, and the former provides mutator | ||||
|             capabilities. Refer to one of the samples that ship with Spring Security for an example | ||||
|             configuration. You'll also need to populate the database with the four ACL-specific | ||||
|             tables listed in the last section (refer to the ACL samples for the appropriate SQL | ||||
|             statements).</para> | ||||
|             <literal>BasicLookupStrategy</literal> instance. The latter provides high-performance | ||||
|             ACL retrieval capabilities, and the former provides mutator capabilities. Refer to one | ||||
|             of the samples that ship with Spring Security for an example configuration. You'll also | ||||
|             need to populate the database with the four ACL-specific tables listed in the last | ||||
|             section (refer to the ACL samples for the appropriate SQL statements).</para> | ||||
|         <para>Once you've created the required schema and instantiated | ||||
|                 <literal>JdbcMutableAclService</literal>, you'll next need to ensure your domain | ||||
|             model supports interoperability with the Spring Security ACL package. Hopefully | ||||
|             <literal>JdbcMutableAclService</literal>, you'll next need to ensure your domain model | ||||
|             supports interoperability with the Spring Security ACL package. Hopefully | ||||
|             <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 | ||||
|             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 | ||||
|             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 | ||||
|             (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, | ||||
|             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 | ||||
|  | @ -282,15 +279,15 @@ aclService.updateAcl(acl); | |||
|         <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 | ||||
|             logic. You have a number of choices here. You could write your own | ||||
|                 <interfacename>AccessDecisionVoter</interfacename> or <literal>AfterInvocationProvider</literal> | ||||
|             that respectively fires before or after a method invocation. Such classes would use | ||||
|                 <literal>AclService</literal> to retrieve the relevant ACL and then call | ||||
|                 <literal>Acl.isGranted(Permission[] permission, Sid[] sids, boolean | ||||
|                 administrativeMode)</literal> to decide whether permission is granted or denied. | ||||
|             <interfacename>AccessDecisionVoter</interfacename> or | ||||
|             <literal>AfterInvocationProvider</literal> that respectively fires before or after a | ||||
|             method invocation. Such classes would use <literal>AclService</literal> to retrieve the | ||||
|             relevant ACL and then call <literal>Acl.isGranted(Permission[] permission, Sid[] sids, | ||||
|             boolean administrativeMode)</literal> to decide whether permission is granted or denied. | ||||
|             Alternately, you could use our <literal>AclEntryVoter</literal>, | ||||
|             <literal>AclEntryAfterInvocationProvider</literal> or | ||||
|                 <literal>AclEntryAfterInvocationCollectionFilteringProvider</literal> classes. All | ||||
|             of these classes provide a declarative-based approach to evaluating ACL information at | ||||
|             <literal>AclEntryAfterInvocationCollectionFilteringProvider</literal> classes. All of | ||||
|             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 | ||||
|             applications to learn how to use these classes.</para> | ||||
|     </section> | ||||
|  |  | |||
|  | @ -18,8 +18,8 @@ | |||
|         <section xml:id="el-common-built-in"> | ||||
|             <title>Common Built-In Expressions</title> | ||||
|             <para>The base class for expression root objects is | ||||
|                     <classname>SecurityExpressionRoot</classname>. This provides some common | ||||
|                 expressions which are available in both web and method security.</para> | ||||
|                 <classname>SecurityExpressionRoot</classname>. This provides some common expressions | ||||
|                 which are available in both web and method security.</para> | ||||
|             <table frame="none"> | ||||
|                 <title>Common built-in expressions</title> | ||||
|                 <tgroup cols="2"> | ||||
|  | @ -51,8 +51,8 @@ | |||
|                         <row> | ||||
|                             <entry><literal>authentication</literal></entry> | ||||
|                             <entry>Allows direct access to the current | ||||
|                                     <interfacename>Authentication</interfacename> object obtained | ||||
|                                 from the <interfacename>SecurityContext</interfacename></entry> | ||||
|                                 <interfacename>Authentication</interfacename> object obtained from | ||||
|                                 the <interfacename>SecurityContext</interfacename></entry> | ||||
|                         </row> | ||||
|                         <row> | ||||
|                             <entry><literal>permitAll</literal></entry> | ||||
|  | @ -90,8 +90,8 @@ | |||
|     <section xml:id="el-access-web"> | ||||
|         <title>Web Security Expressions</title> | ||||
|         <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> | ||||
|             element to <literal>true</literal>. Spring Security will then expect the | ||||
|             <literal>use-expressions</literal> attribute in the <literal><http></literal> element | ||||
|             to <literal>true</literal>. Spring Security will then expect the | ||||
|             <literal>access</literal> attributes of the <literal><intercept-url></literal> | ||||
|             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[ | ||||
|  | @ -106,8 +106,8 @@ | |||
|             already seen the built-in <literal>hasRole</literal> expression in the previous section. | ||||
|             The expression <literal>hasIpAddress</literal> is an additional built-in expression | ||||
|             which is specific to web security. It is defined by the | ||||
|                 <classname>WebSecurityExpressionRoot</classname> class, an instance of which is used | ||||
|             as the expression root object when evaluation web-access expressions. This object also | ||||
|             <classname>WebSecurityExpressionRoot</classname> class, an instance of which is used as | ||||
|             the expression root object when evaluation web-access expressions. This object also | ||||
|             directly exposed the <interfacename>HttpServletRequest</interfacename> object under the | ||||
|             name <literal>request</literal> so you can invoke the request directly in an | ||||
|             expression.</para> | ||||
|  | @ -150,25 +150,25 @@ | |||
|                     whether the current user has the <quote>admin</quote>permission for the given | ||||
|                     contact. The built-in <literal>hasPermission()</literal> expression is linked | ||||
|                     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 | ||||
|                     any of the method arguments by name as expression variables, provided your code | ||||
|                     has debug information compiled in. Any Spring-EL functionality is available | ||||
|                     within the expression, so you can also access properties on the arguments. For | ||||
|                     example, if you wanted a particular method to only allow access to a user whose | ||||
|                     username matched that of the contact, you could write</para> | ||||
|                     <link xlink:href="#el-permission-evaluator">see below</link>. You can access any | ||||
|                     of the method arguments by name as expression variables, provided your code has | ||||
|                     debug information compiled in. Any Spring-EL functionality is available within | ||||
|                     the expression, so you can also access properties on the arguments. For example, | ||||
|                     if you wanted a particular method to only allow access to a user whose username | ||||
|                     matched that of the contact, you could write</para> | ||||
|                 <programlisting> | ||||
|  @PreAuthorize("#contact.name == principal.name)") | ||||
|  public void doSomething(Contact contact);</programlisting> | ||||
|                 <para>Here we are accessing another built–in expression, which is the | ||||
|                     <literal>principal</literal> of the current Spring Security | ||||
|                         <interfacename>Authentication</interfacename> object obtained from the | ||||
|                     security context. You can also access the | ||||
|                         <interfacename>Authentication</interfacename> object itself directly using | ||||
|                     the expression name <literal>authentication</literal>.</para> | ||||
|                     <interfacename>Authentication</interfacename> object obtained from the security | ||||
|                     context. You can also access the <interfacename>Authentication</interfacename> | ||||
|                     object itself directly using the expression name | ||||
|                     <literal>authentication</literal>.</para> | ||||
|                 <para>Less commonly, you may wish to perform an access-control check after the | ||||
|                     method has been invoked. This can be achieved using the | ||||
|                         <literal>@PostAuthorize</literal> annotation. To access the return value | ||||
|                     from a method, use the built–in name <literal>returnObject</literal> in the | ||||
|                     <literal>@PostAuthorize</literal> annotation. To access the return value from a | ||||
|                     method, use the built–in name <literal>returnObject</literal> in the | ||||
|                     expression.</para> | ||||
|             </section> | ||||
|             <section> | ||||
|  | @ -227,8 +227,7 @@ | |||
|                     long as it is consistent with how the permissions are loaded.</para> | ||||
|                 <para>To use <literal>hasPermission()</literal> expressions, you have to explicitly | ||||
|                     configure a <interfacename>PermissionEvaluator</interfacename> in your | ||||
|                     application context. This would look something like this: | ||||
| <programlisting language="xml"> <![CDATA[ | ||||
|                     application context. This would look something like this: <programlisting language="xml"> <![CDATA[ | ||||
| <security:global-method-security pre-post-annotations="enabled"> | ||||
|   <security:expression-handler ref="expressionHandler"/> | ||||
| </security:global-method-security> | ||||
|  | @ -239,9 +238,8 @@ | |||
| </bean>]]></programlisting>Where <literal>myPermissionEvaluator</literal> is the bean which | ||||
|                     implements <interfacename>PermissionEvaluator</interfacename>. Usually this will | ||||
|                     be the implementation from the ACL module which is called | ||||
|                         <classname>AclPermissionEvaluator</classname>. See the | ||||
|                         <quote>Contacts</quote> sample application configuration for more | ||||
|                     details.</para> | ||||
|                     <classname>AclPermissionEvaluator</classname>. See the <quote>Contacts</quote> | ||||
|                     sample application configuration for more details.</para> | ||||
|             </section> | ||||
|         </section> | ||||
|     </section> | ||||
|  |  | |||
|  | @ -1,67 +1,68 @@ | |||
| <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"> | ||||
|         <info><title>Overview</title></info> | ||||
|         <info> | ||||
|             <title>Overview</title> | ||||
|         </info> | ||||
| 
 | ||||
|         <para>HTTP Form Authentication involves using the | ||||
|             <literal>UsernamePasswordAuthenticationFilter</literal> to process a login | ||||
|             form. This is the most common way for an application to authenticate end | ||||
|             users. Form-based authentication is entirely compatible with the DAO, LDAP | ||||
|             and JAAS authentication providers.</para> | ||||
|             <literal>UsernamePasswordAuthenticationFilter</literal> to process a login form. This is | ||||
|             the most common way for an application to authenticate end users. Form-based | ||||
|             authentication is entirely compatible with the DAO, LDAP and JAAS authentication | ||||
|             providers.</para> | ||||
|         <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. | ||||
|         </para> | ||||
|             and it's recommended that you use that unless you have specific customization | ||||
|             requirements. </para> | ||||
|     </section> | ||||
| 
 | ||||
|     <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 | ||||
|             <literal>j_password</literal> input fields, and posts to a URL that is | ||||
|             monitored by the filter (by default | ||||
|             <literal>/j_spring_security_check</literal>). You should add an | ||||
|             <literal>UsernamePasswordAuthenticationFilter</literal> to your application context: | ||||
|             <programlisting><![CDATA[ | ||||
|             <literal>j_password</literal> input fields, and posts to a URL that is monitored by the | ||||
|             filter (by default <literal>/j_spring_security_check</literal>). You should add an | ||||
|             <literal>UsernamePasswordAuthenticationFilter</literal> to your application context: <programlisting><![CDATA[ | ||||
| <bean id="authenticationProcessingFilter" class= | ||||
| "org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"> | ||||
|   <property name="authenticationManager" ref="authenticationManager"/> | ||||
|   <property name="filterProcessesUrl" value="/j_spring_security_check"/> | ||||
| </bean> ]]> | ||||
|             </programlisting></para> | ||||
|         <para> | ||||
|             The configured <interfacename>AuthenticationManager</interfacename> | ||||
|             processes each authentication request. The destination following a successful authentication | ||||
|             or an authentication failure is controlled by the <interfacename>AuthenticationSuccessHandler</interfacename> | ||||
|             and <interfacename>AuthenticationFailureHandler</interfacename> interfaces, respectively. | ||||
|             The filter has properties which allow you to set these | ||||
|             <footnote><para>In versions prior to 3.0, the application flow at this point had evolved to a 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. | ||||
|             </para></footnote>. | ||||
|             Some standard implementations are supplied for these such as | ||||
|         <para> The configured <interfacename>AuthenticationManager</interfacename> processes each | ||||
|             authentication request. The destination following a successful authentication or an | ||||
|             authentication failure is controlled by the | ||||
|             <interfacename>AuthenticationSuccessHandler</interfacename> and | ||||
|             <interfacename>AuthenticationFailureHandler</interfacename> interfaces, respectively. | ||||
|             The filter has properties which allow you to set these <footnote> | ||||
|             <para>In versions prior to 3.0, the application flow at this point had evolved to a | ||||
|                 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. </para> | ||||
|             </footnote>. Some standard implementations are supplied for these such as | ||||
|             <classname>SimpleUrlAuthenticationSuccessHandler</classname>, | ||||
|             <classname>SavedRequestAwareAuthenticationSuccessHandler</classname>, | ||||
|             <classname>SimpleUrlAuthenticationFailureHandler</classname> and | ||||
|             <classname>ExceptionMappingAuthenticationFailureHandler</classname>. Have a look at the Javadoc | ||||
|             for these classes to see how they work. | ||||
|             </para> | ||||
|             <classname>ExceptionMappingAuthenticationFailureHandler</classname>. Have a look at the | ||||
|             Javadoc for these classes to see how they work. </para> | ||||
| 
 | ||||
|         <para>If authentication is successful, the resulting | ||||
|             <interfacename>Authentication</interfacename> object will be placed into the | ||||
|             <classname>SecurityContextHolder</classname>. | ||||
|             The configured AuthenticationSuccessHandler will then be called to either redirect or forward | ||||
|             the user to the appropriate destination. By default a <classname>SavedRequestAwareAuthenticationSuccessHandler</classname> | ||||
|             is used, which means that the user will be redirected to the original destination they requested before they were asked to | ||||
|             login. | ||||
|             <note> | ||||
|                 <para> | ||||
|                     The <classname>ExceptionTranslationFilter</classname> caches the original request a user makes. | ||||
|                     When the user authenticates, the request handler makes use of this cached request to obtain the original | ||||
|                     URL and redirect to it. The original request is then rebuilt and used as an alternative. | ||||
|                 </para> | ||||
|             </note> | ||||
|             If authentication fails, the configured <interfacename>AuthenticationFailureHandler</interfacename> will be invoked. | ||||
|         </para> | ||||
|             <classname>SecurityContextHolder</classname>. The configured | ||||
|             AuthenticationSuccessHandler will then be called to either redirect or forward the user | ||||
|             to the appropriate destination. By default a | ||||
|             <classname>SavedRequestAwareAuthenticationSuccessHandler</classname> is used, which | ||||
|             means that the user will be redirected to the original destination they requested before | ||||
|             they were asked to login. <note> | ||||
|             <para> The <classname>ExceptionTranslationFilter</classname> caches the original request | ||||
|                 a user makes. When the user authenticates, the request handler makes use of this | ||||
|                 cached request to obtain the original URL and redirect to it. The original request | ||||
|                 is then rebuilt and used as an alternative. </para> | ||||
|             </note> If authentication fails, the configured | ||||
|             <interfacename>AuthenticationFailureHandler</interfacename> will be invoked. </para> | ||||
|     </section> | ||||
| </chapter> | ||||
|  | @ -25,8 +25,8 @@ | |||
|             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 | ||||
|             other system which can perform an action in your application). | ||||
|                 <quote>Authorization</quote> refers to the process of deciding whether a principal | ||||
|             is allowed to perform an action within your application. To arrive at the point where an | ||||
|             <quote>Authorization</quote> refers to the process of deciding whether a principal is | ||||
|             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 | ||||
|             established by the authentication process. These concepts are common, and not at all | ||||
|             specific to Spring Security. </para> | ||||
|  | @ -134,8 +134,8 @@ | |||
|             </listitem> | ||||
|         </itemizedlist> | ||||
|         <para>(* Denotes provided by a third party; check our <link | ||||
|                 xlink:href="http://acegisecurity.org/powering.html">integration page</link> for | ||||
|             links to the latest details)</para> | ||||
|             xlink:href="http://acegisecurity.org/powering.html">integration page</link> for links to | ||||
|             the latest details)</para> | ||||
|         <para>Many independent software vendors (ISVs) adopt Spring Security because of this | ||||
|             significant choice of flexible authentication models. Doing so allows them to quickly | ||||
|             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 | ||||
|             contained on that page for your convenience:</para> | ||||
|         <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 API. MINOR versions retain source and binary compatibility with older minor | ||||
|                 versions, and changes in the PATCH level are perfectly compatible, forwards and | ||||
|             The basic intent is that MAJOR versions are incompatible, large-scale upgrades of the | ||||
|             API. MINOR versions retain source and binary compatibility with older minor versions, | ||||
|             and changes in the PATCH level are perfectly compatible, forwards and | ||||
|             backwards.</quote></para> | ||||
|     </section> | ||||
|     <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 | ||||
|             distribution from the main Spring <link | ||||
|             xlink:href="http://www.springsource.com/download/community?project=Spring%20Security" | ||||
|                 >download page</link>, download individual jars (and sample WAR files) from the | ||||
|             Maven Central repository (or a SpringSource Maven repository for snapshot and milestone | ||||
|             >download page</link>, download individual jars (and sample WAR files) from the Maven | ||||
|             Central repository (or a SpringSource Maven repository for snapshot and milestone | ||||
|             releases) or, alternatively, you can build the project from source yourself. See the | ||||
|             project web site for more details. </para> | ||||
|         <section xml:id="modules"> | ||||
|  | @ -233,8 +233,23 @@ | |||
|                 <para>Contains core authentication and access-contol classes and interfaces, | ||||
|                     remoting support and basic provisioning APIs. Required by any application which | ||||
|                     uses Spring Security. Supports standalone applications, remote clients, method | ||||
|                     (service layer) security and JDBC user provisioning. Contains the top-level | ||||
|                                     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> | ||||
|                     (service layer) security and JDBC user provisioning. Contains the top-level 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> | ||||
|             </section> | ||||
|             <section xml:id="spring-security-web"> | ||||
|                 <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"> | ||||
|     <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"> | ||||
|         <info><title>Overview</title></info> | ||||
|         <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> | ||||
|         <info> | ||||
|             <title>Overview</title> | ||||
|         </info> | ||||
|         <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 | ||||
|             learn more about JAAS login configuration files, consult the JAAS | ||||
|             reference documentation available from Sun Microsystems. We expect you | ||||
|             to have a basic understanding of JAAS and its login configuration file | ||||
|             syntax in order to understand this section.</para> | ||||
|         <para>Central to JAAS operation are login configuration files. To learn more about JAAS | ||||
|             login configuration files, consult the JAAS reference documentation available from Sun | ||||
|             Microsystems. We expect you to have a basic understanding of JAAS and its login | ||||
|             configuration file syntax in order to understand this section.</para> | ||||
|     </section> | ||||
| 
 | ||||
|     <section xml:id="jaas-config"> | ||||
|         <info><title>Configuration</title></info> | ||||
|         <para>The <literal>JaasAuthenticationProvider</literal> attempts to | ||||
|             authenticate a user’s principal and credentials through JAAS.</para> | ||||
|         <info> | ||||
|             <title>Configuration</title> | ||||
|         </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, | ||||
|             <literal>/WEB-INF/login.conf</literal>, with the following | ||||
|             contents: | ||||
| <programlisting> | ||||
|             <literal>/WEB-INF/login.conf</literal>, with the following contents: | ||||
|             <programlisting> | ||||
| JAASTest { | ||||
|     sample.SampleLoginModule required; | ||||
| };</programlisting></para> | ||||
|         <para>Like all Spring Security beans, the | ||||
|             <classname>JaasAuthenticationProvider</classname> is configured via the | ||||
|             application context. The following definitions would correspond to the | ||||
|             above JAAS login configuration file: | ||||
| <programlisting><![CDATA[ | ||||
|         <para>Like all Spring Security beans, the <classname>JaasAuthenticationProvider</classname> | ||||
|             is configured via the application context. The following definitions would correspond to | ||||
|             the above JAAS login configuration file: <programlisting><![CDATA[ | ||||
| <bean id="jaasAuthenticationProvider" | ||||
|    class="org.springframework.security.authentication.jaas.JaasAuthenticationProvider"> | ||||
|  <property name="loginConfig" value="/WEB-INF/login.conf"/> | ||||
|  | @ -55,82 +57,76 @@ JAASTest { | |||
|             <interfacename>AuthorityGranter</interfacename>s are discussed below.</para> | ||||
| 
 | ||||
|         <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 | ||||
|                 of some sort. These callbacks are usually used to obtain the | ||||
|                 username and password from the user.</para> | ||||
|             <para>Most JAAS <literal>LoginModule</literal>s require a callback of some sort. These | ||||
|                 callbacks are usually used to obtain the username and password from the user.</para> | ||||
| 
 | ||||
|             <para>In a Spring Security deployment, Spring Security is | ||||
|                 responsible for this user interaction (via the authentication | ||||
|                 mechanism). Thus, by the time the authentication request is | ||||
|                 delegated through to JAAS, Spring Security's authentication | ||||
|                 mechanism will already have fully-populated an | ||||
|                 <interfacename>Authentication</interfacename> object containing all the | ||||
|                 information required by the JAAS | ||||
|             <para>In a Spring Security deployment, Spring Security is responsible for this user | ||||
|                 interaction (via the authentication mechanism). Thus, by the time the authentication | ||||
|                 request is delegated through to JAAS, Spring Security's authentication mechanism | ||||
|                 will already have fully-populated an <interfacename>Authentication</interfacename> | ||||
|                 object containing all the information required by the JAAS | ||||
|                 <literal>LoginModule</literal>.</para> | ||||
| 
 | ||||
|             <para>Therefore, the JAAS package for Spring Security provides two | ||||
|                 default callback handlers, | ||||
|                 <literal>JaasNameCallbackHandler</literal> and | ||||
|                 <literal>JaasPasswordCallbackHandler</literal>. Each of these | ||||
|                 callback handlers implement | ||||
|                 <literal>JaasAuthenticationCallbackHandler</literal>. In most cases | ||||
|                 these callback handlers can simply be used without understanding the | ||||
|                 internal mechanics.</para> | ||||
|             <para>Therefore, the JAAS package for Spring Security provides two default callback | ||||
|                 handlers, <literal>JaasNameCallbackHandler</literal> and | ||||
|                 <literal>JaasPasswordCallbackHandler</literal>. Each of these callback handlers | ||||
|                 implement <literal>JaasAuthenticationCallbackHandler</literal>. In most cases these | ||||
|                 callback handlers can simply be used without understanding the internal | ||||
|                 mechanics.</para> | ||||
| 
 | ||||
|             <para>For those needing full control over the callback behavior, | ||||
|                 internally <literal>JaasAuthenticationProvider</literal> wraps these | ||||
|             <para>For those needing full control over the callback behavior, internally | ||||
|                 <literal>JaasAuthenticationProvider</literal> wraps these | ||||
|                 <literal>JaasAuthenticationCallbackHandler</literal>s with an | ||||
|                 <literal>InternalCallbackHandler</literal>. The | ||||
|                 <literal>InternalCallbackHandler</literal> is the class that | ||||
|                 actually implements JAAS’ normal <literal>CallbackHandler</literal> | ||||
|                 interface. Any time that the JAAS <literal>LoginModule</literal> is | ||||
|                 used, it is passed a list of application context configured | ||||
|                 <literal>InternalCallbackHandler</literal>s. If the | ||||
|                 <literal>InternalCallbackHandler</literal> is the class that actually implements | ||||
|                 JAAS’ normal <literal>CallbackHandler</literal> interface. Any time that the JAAS | ||||
|                 <literal>LoginModule</literal> is used, it is passed a list of application context | ||||
|                 configured <literal>InternalCallbackHandler</literal>s. If the | ||||
|                 <literal>LoginModule</literal> requests a callback against the | ||||
|                 <literal>InternalCallbackHandler</literal>s, the callback is in-turn | ||||
|                 passed to the <literal>JaasAuthenticationCallbackHandler</literal>s | ||||
|                 being wrapped.</para> | ||||
|                 <literal>InternalCallbackHandler</literal>s, the callback is in-turn passed to the | ||||
|                 <literal>JaasAuthenticationCallbackHandler</literal>s being wrapped.</para> | ||||
|         </section> | ||||
| 
 | ||||
|         <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 | ||||
|                 principals in JAAS. Spring Security, on the other hand, works with | ||||
|             <para>JAAS works with principals. Even "roles" are represented as principals in JAAS. | ||||
|                 Spring Security, on the other hand, works with | ||||
|                 <interfacename>Authentication</interfacename> objects. Each | ||||
|                 <interfacename>Authentication</interfacename> object contains a single | ||||
|                 principal, and multiple <interfacename>GrantedAuthority</interfacename>[]s. To | ||||
|                 facilitate mapping between these different concepts, Spring | ||||
|                 Security's JAAS package includes an | ||||
|                 <interfacename>Authentication</interfacename> object contains a single principal, | ||||
|                 and multiple <interfacename>GrantedAuthority</interfacename>[]s. To facilitate | ||||
|                 mapping between these different concepts, Spring Security's JAAS package includes an | ||||
|                 <literal>AuthorityGranter</literal> interface.</para> | ||||
| 
 | ||||
|             <para>An <literal>AuthorityGranter</literal> is responsible for | ||||
|                 inspecting a JAAS principal and returning a set of | ||||
|                 <literal>String</literal>s, representing the authorities assigned to the principal. | ||||
|                 For each returned authority string, the | ||||
|             <para>An <literal>AuthorityGranter</literal> is responsible for inspecting a JAAS | ||||
|                 principal and returning a set of <literal>String</literal>s, representing the | ||||
|                 authorities assigned to the principal. For each returned authority string, the | ||||
|                 <classname>JaasAuthenticationProvider</classname> creates a | ||||
|                 <classname>JaasGrantedAuthority</classname> (which implements Spring | ||||
|                 Security’s <interfacename>GrantedAuthority</interfacename> interface) containing | ||||
|                 the authority string and the JAAS principal that the | ||||
|                 <classname>JaasGrantedAuthority</classname> (which implements Spring Security’s | ||||
|                 <interfacename>GrantedAuthority</interfacename> interface) containing the authority | ||||
|                 string and the JAAS principal that the | ||||
|                 <interfacename>AuthorityGranter</interfacename> was passed. The | ||||
|                 <classname>JaasAuthenticationProvider</classname> obtains the JAAS | ||||
|                 principals by firstly successfully authenticating the user’s | ||||
|                 credentials using the JAAS <literal>LoginModule</literal>, and then | ||||
|                 accessing the <literal>LoginContext</literal> it returns. A call to | ||||
|                 <literal>LoginContext.getSubject().getPrincipals()</literal> is | ||||
|                 made, with each resulting principal passed to each | ||||
|                 <interfacename>AuthorityGranter</interfacename> defined against the | ||||
|                 <classname>JaasAuthenticationProvider</classname> obtains the JAAS principals by | ||||
|                 firstly successfully authenticating the user’s credentials using the JAAS | ||||
|                 <literal>LoginModule</literal>, and then accessing the | ||||
|                 <literal>LoginContext</literal> it returns. A call to | ||||
|                 <literal>LoginContext.getSubject().getPrincipals()</literal> is made, with each | ||||
|                 resulting principal passed to each <interfacename>AuthorityGranter</interfacename> | ||||
|                 defined against the | ||||
|                 <literal>JaasAuthenticationProvider.setAuthorityGranters(List)</literal> | ||||
|                 property.</para> | ||||
| 
 | ||||
|             <para>Spring Security does not include any production | ||||
|                 <interfacename>AuthorityGranter</interfacename>s given that every JAAS principal | ||||
|                 has an implementation-specific meaning. However, there is a | ||||
|                 <literal>TestAuthorityGranter</literal> in the unit tests that | ||||
|                 demonstrates a simple <literal>AuthorityGranter</literal> | ||||
|                 implementation.</para> | ||||
|                 <interfacename>AuthorityGranter</interfacename>s given that every JAAS principal has | ||||
|                 an implementation-specific meaning. However, there is a | ||||
|                 <literal>TestAuthorityGranter</literal> in the unit tests that demonstrates a simple | ||||
|                 <literal>AuthorityGranter</literal> implementation.</para> | ||||
|         </section> | ||||
|     </section> | ||||
| </chapter> | ||||
|  | @ -17,12 +17,11 @@ | |||
|             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 | ||||
|             xmlns:xlink="http://www.w3.org/1999/xlink" | ||||
|                 xlink:href="http://www.zytrax.com/books/ldap/" | ||||
|                 >http://www.zytrax.com/books/ldap/</uri>. Some familiarity with the JNDI APIs used | ||||
|             to access LDAP from Java may also be useful. We don't use any third-party LDAP libraries | ||||
|             (Mozilla, JLDAP etc.) in the LDAP provider, but extensive use is made of Spring LDAP, so | ||||
|             some familiarity with that project may be useful if you plan on adding your own | ||||
|             customizations.</para> | ||||
|             xlink:href="http://www.zytrax.com/books/ldap/">http://www.zytrax.com/books/ldap/</uri>. | ||||
|             Some familiarity with the JNDI APIs used to access LDAP from Java may also be useful. We | ||||
|             don't use any third-party LDAP libraries (Mozilla, JLDAP etc.) in the LDAP provider, but | ||||
|             extensive use is made of Spring LDAP, so some familiarity with that project may be | ||||
|             useful if you plan on adding your own customizations.</para> | ||||
|     </section> | ||||
|     <section> | ||||
|         <info> | ||||
|  | @ -31,9 +30,9 @@ | |||
|         <para> LDAP authentication in Spring Security can be roughly divided into the following | ||||
|             stages. <orderedlist inheritnum="ignore" continuation="restarts"> | ||||
|             <listitem> | ||||
|                     <para>Obtaining the unique LDAP <quote>Distinguished Name</quote>, or DN, from | ||||
|                         the login name. This will often mean performing a search in the directory, | ||||
|                         unless the exact mapping of usernames to DNs is known in advance.</para> | ||||
|                 <para>Obtaining the unique LDAP <quote>Distinguished Name</quote>, or DN, from the | ||||
|                     login name. This will often mean performing a search in the directory, unless | ||||
|                     the exact mapping of usernames to DNs is known in advance.</para> | ||||
|             </listitem> | ||||
|             <listitem> | ||||
|                 <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"/> | ||||
|  ]]> | ||||
|     </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, | ||||
|                 the namespace parser will create an embedded Apache Directory server and scan the | ||||
|                 <quote>dc=springframework,dc=org</quote>, which is the default. Used this way, 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 | ||||
|                 customize this behaviour using the <literal>ldif</literal> attribute, which defines | ||||
|                 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 | ||||
|                 following attributes. <itemizedlist> | ||||
|                 <listitem> | ||||
|                         <para> | ||||
|                             <literal>group-search-base</literal>. Defines the part of the directory | ||||
|                     <para> <literal>group-search-base</literal>. Defines the part of the directory | ||||
|                         tree under which group searches should be performed.</para> | ||||
|                 </listitem> | ||||
|                 <listitem> | ||||
|                         <para> | ||||
|                             <literal>group-role-attribute</literal>. The attribute which contains | ||||
|                             the name of the authority defined by the group entry. Defaults to | ||||
|                                 <literal>cn</literal> | ||||
|                         </para> | ||||
|                     <para> <literal>group-role-attribute</literal>. The attribute which contains the | ||||
|                         name of the authority defined by the group entry. Defaults to | ||||
|                         <literal>cn</literal> </para> | ||||
|                 </listitem> | ||||
|                 <listitem> | ||||
|                         <para> | ||||
|                             <literal>group-search-filter</literal>. The filter which is used to | ||||
|                     <para> <literal>group-search-filter</literal>. The filter which is used to | ||||
|                         search for group membership. The default is | ||||
|                         <literal>uniqueMember={0}</literal>, corresponding to the | ||||
|                                 <literal>groupOfUniqueMembers</literal> LDAP class. In this case, | ||||
|                             the substituted parameter is the full distinguished name of the user. | ||||
|                             The parameter <literal>{1}</literal> can be used if you want to filter | ||||
|                             on the login name.</para> | ||||
|                         <literal>groupOfUniqueMembers</literal> LDAP class. In this case, the | ||||
|                         substituted parameter is the full distinguished name of the user. The | ||||
|                         parameter <literal>{1}</literal> can be used if you want to filter on the | ||||
|                         login name.</para> | ||||
|                 </listitem> | ||||
|                 </itemizedlist> So if we used the following configuration <programlisting><![CDATA[ | ||||
|   <ldap-authentication-provider user-dn-pattern="uid={0},ou=people" | ||||
|           group-search-base="ou=groups" /> | ||||
|     ]]></programlisting> and authenticated successfully as user <quote>ben</quote>, the subsequent | ||||
|                 loading of authorities would perform a search under the directory entry | ||||
|                     <literal>ou=groups,dc=springframework,dc=org</literal>, looking for entries | ||||
|                 which contain the attribute <literal>uniqueMember</literal> with value | ||||
|                 <literal>ou=groups,dc=springframework,dc=org</literal>, looking for entries which | ||||
|                 contain the attribute <literal>uniqueMember</literal> with value | ||||
|                 <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 | ||||
|                 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> | ||||
|             <para>There are currently two authentication strategies supplied with Spring Security: <itemizedlist> | ||||
|                 <listitem> | ||||
|                         <para>Authentication directly to the LDAP server ("bind" | ||||
|                             authentication).</para> | ||||
|                     <para>Authentication directly to the LDAP server ("bind" authentication).</para> | ||||
|                 </listitem> | ||||
|                 <listitem> | ||||
|                         <para>Password comparison, where the password supplied by the user is | ||||
|                             compared with the one stored in the repository. This can either be done | ||||
|                             by retrieving the value of the password attribute and checking it | ||||
|                             locally or by performing an LDAP "compare" operation, where the supplied | ||||
|                             password is passed to the server for comparison and the real password | ||||
|                             value is never retrieved.</para> | ||||
|                     <para>Password comparison, where the password supplied by the user is compared | ||||
|                         with the one stored in the repository. This can either be done by retrieving | ||||
|                         the value of the password attribute and checking it locally or by performing | ||||
|                         an LDAP "compare" operation, where the supplied password is passed to the | ||||
|                         server for comparison and the real password value is never retrieved.</para> | ||||
|                 </listitem> | ||||
|                 </itemizedlist></para> | ||||
|             <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 | ||||
|                     application. This can be done either by simple pattern-matching (by setting the | ||||
|                     <property>setUserDnPatterns</property> array property) or by setting the | ||||
|                         <property>userSearch</property> property. For the DN pattern-matching | ||||
|                     approach, a standard Java pattern format is used, and the login name will be | ||||
|                     substituted for the parameter <parameter>{0}</parameter>. The pattern should be | ||||
|                     relative to the DN that the configured | ||||
|                         <interfacename>SpringSecurityContextSource</interfacename> will bind to (see | ||||
|                     the section on <link linkend="ldap-context-source">connecting to the LDAP | ||||
|                         server</link> for more information on this). For example, if you are using | ||||
|                     an LDAP server with the URL | ||||
|                     <property>userSearch</property> property. For the DN pattern-matching approach, | ||||
|                     a standard Java pattern format is used, and the login name will be substituted | ||||
|                     for the parameter <parameter>{0}</parameter>. The pattern should be relative to | ||||
|                     the DN that the configured | ||||
|                     <interfacename>SpringSecurityContextSource</interfacename> will bind to (see the | ||||
|                     section on <link linkend="ldap-context-source">connecting to the LDAP | ||||
|                     server</link> for more information on this). For example, if you are using an | ||||
|                     LDAP server with the URL | ||||
|                     <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 | ||||
|                     "gorilla" will map to a DN | ||||
|                     <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 | ||||
|                     information on using a search, see the section on <link | ||||
|                         linkend="ldap-searchobjects">search objects</link> below. A combination of | ||||
|                     the two approaches can also be used - the patterns will be checked first and if | ||||
|                     no matching DN is found, the search will be used.</para> | ||||
|                     linkend="ldap-searchobjects">search objects</link> below. A combination of the | ||||
|                     two approaches can also be used - the patterns will be checked first and if no | ||||
|                     matching DN is found, the search will be used.</para> | ||||
|             </section> | ||||
|             <section xml:id="ldap-ldap-authenticators-bind"> | ||||
|                 <info> | ||||
|                     <title>BindAuthenticator</title> | ||||
|                 </info> | ||||
|                 <para>The class <classname>BindAuthenticator</classname> in the package | ||||
|                         <filename>org.springframework.security.ldap.authentication</filename> | ||||
|                     implements the bind authentication strategy. It simply attempts to bind as the | ||||
|                     user.</para> | ||||
|                     <filename>org.springframework.security.ldap.authentication</filename> implements | ||||
|                     the bind authentication strategy. It simply attempts to bind as the user.</para> | ||||
|             </section> | ||||
|             <section xml:id="ldap-ldap-authenticators-password"> | ||||
|                 <info> | ||||
|  | @ -254,16 +246,15 @@ | |||
|             <info> | ||||
|                 <title>LDAP Search Objects</title> | ||||
|             </info> | ||||
|             <para>Often a more complicated strategy than simple DN-matching is required to | ||||
|                 locate a user entry in the directory. This can be encapsulated in an | ||||
|                     <interfacename>LdapUserSearch</interfacename> instance which can be supplied to | ||||
|                 the authenticator implementations, for example, to allow them to locate a user. The | ||||
|             <para>Often a more complicated strategy than simple DN-matching is required to locate a | ||||
|                 user entry in the directory. This can be encapsulated in an | ||||
|                 <interfacename>LdapUserSearch</interfacename> instance which can be supplied to the | ||||
|                 authenticator implementations, for example, to allow them to locate a user. The | ||||
|                 supplied implementation is <classname>FilterBasedLdapUserSearch</classname>.</para> | ||||
|             <section xml:id="ldap-searchobjects-filter"> | ||||
|                 <info> | ||||
|                     <title xml:id="ldap-searchobjects-filter-based"> | ||||
|                         <classname>FilterBasedLdapUserSearch</classname> | ||||
|                     </title> | ||||
|                         <classname>FilterBasedLdapUserSearch</classname> </title> | ||||
|                 </info> | ||||
|                 <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 | ||||
|  | @ -281,11 +272,11 @@ | |||
|                 <classname>LdapAuthenticationProvider</classname> will attempt to load a set of | ||||
|                 authorities for the user by calling the configured | ||||
|                 <interfacename>LdapAuthoritiesPopulator</interfacename> bean. The | ||||
|                     <classname>DefaultLdapAuthoritiesPopulator</classname> is an implementation | ||||
|                 which will load the authorities by searching the directory for groups of which the | ||||
|                 user is a member (typically these will be <literal>groupOfNames</literal> or | ||||
|                     <literal>groupOfUniqueNames</literal> entries in the directory). Consult the | ||||
|                 Javadoc for this class for more details on how it works. </para> | ||||
|                 <classname>DefaultLdapAuthoritiesPopulator</classname> is an implementation which | ||||
|                 will load the authorities by searching the directory for groups of which the user is | ||||
|                 a member (typically these will be <literal>groupOfNames</literal> or | ||||
|                 <literal>groupOfUniqueNames</literal> entries in the directory). Consult the Javadoc | ||||
|                 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 | ||||
|                 difference source (such as a database) then you can provide your own implementation | ||||
|                 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 | ||||
|                 from the <quote>ou</quote> attribute of each match.</para> | ||||
|             <para>To configure a user search object, which uses the filter | ||||
|                     <literal>(uid=<user-login-name>)</literal> for use instead of the | ||||
|                 DN-pattern (or in addition to it), you would configure the following bean <programlisting><![CDATA[ | ||||
|                 <literal>(uid=<user-login-name>)</literal> for use instead of the DN-pattern | ||||
|                 (or in addition to it), you would configure the following bean <programlisting><![CDATA[ | ||||
| <bean id="userSearch" | ||||
|     class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch"> | ||||
|   <constructor-arg index="0" value=""/> | ||||
|  | @ -355,25 +346,25 @@ | |||
|                 <interfacename>UserDetailsService</interfacename>, a common requirement is to be | ||||
|                 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 | ||||
|                     <interfacename>UserDetails</interfacename> object is controlled by the | ||||
|                 provider's <interfacename>UserDetailsContextMapper</interfacename> strategy, which | ||||
|                 is responsible for mapping user objects to and from LDAP context data: <programlisting><![CDATA[ | ||||
|                 <interfacename>UserDetails</interfacename> object is controlled by the provider's | ||||
|                 <interfacename>UserDetailsContextMapper</interfacename> strategy, which is | ||||
|                 responsible for mapping user objects to and from LDAP context data: <programlisting><![CDATA[ | ||||
| public interface UserDetailsContextMapper { | ||||
|   UserDetails mapUserFromContext(DirContextOperations ctx, String username, | ||||
|           Collection<GrantedAuthority> authorities); | ||||
| 
 | ||||
|   void mapUserToContext(UserDetails user, DirContextAdapter ctx); | ||||
| }]]> | ||||
|                 </programlisting> Only the first method is relevant for | ||||
|                 authentication. If you provide an implementation of this interface, you can control | ||||
|                 exactly how the UserDetails object is created. The first parameter is an instance of | ||||
|                 Spring LDAP's <interfacename>DirContextOperations</interfacename> which gives you | ||||
|                 access to the LDAP attributes which were loaded. The <literal>username</literal> | ||||
|                 parameter is the name used to authenticate and the final parameter is the collection | ||||
|                 of authorities loaded for the user. </para> | ||||
|                 </programlisting> Only the first method is relevant for authentication. If you | ||||
|                 provide an implementation of this interface, you can control exactly how the | ||||
|                 UserDetails object is created. The first parameter is an instance of Spring LDAP's | ||||
|                 <interfacename>DirContextOperations</interfacename> which gives you access to the | ||||
|                 LDAP attributes which were loaded. The <literal>username</literal> parameter is the | ||||
|                 name used to authenticate and the final parameter is the collection of authorities | ||||
|                 loaded for the user. </para> | ||||
|             <para> The way the context data is loaded varies slightly depending on the type of | ||||
|                 authentication you are using. With the <classname>BindAuthenticator</classname>, | ||||
|                 the context returned from the bind operation will be used to read the attributes, | ||||
|                 authentication you are using. With the <classname>BindAuthenticator</classname>, the | ||||
|                 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 | ||||
|                 configured <interfacename>ContextSource</interfacename> (when a search is configured | ||||
|                 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> | ||||
|         <title>Pre-Authentication Scenarios</title> | ||||
|     </info> | ||||
|   <para> There are situations where you want to use Spring Security for authorization, but the user | ||||
|     has already been reliably authenticated by some external system prior to accessing the | ||||
|     <para> There are situations where you want to use Spring Security for authorization, but 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. | ||||
|         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 | ||||
|           <orderedlist><listitem><para>Identify the user making the request. | ||||
|           </para></listitem><listitem><para>Obtain the authorities for the | ||||
|       user.</para></listitem></orderedlist>The details will depend on the external authentication | ||||
|     mechanism. A user might be identified by their certificate information in the case of X.509, or | ||||
|     by an HTTP request 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> | ||||
|         application is running. When using pre-authentication, Spring Security has to <orderedlist> | ||||
|         <listitem> | ||||
|             <para>Identify the user making the request. </para> | ||||
|         </listitem> | ||||
|         <listitem> | ||||
|             <para>Obtain the authorities for the user.</para> | ||||
|         </listitem> | ||||
|         </orderedlist>The details will depend on the external authentication mechanism. A user might | ||||
|         be identified by their certificate information in the case of X.509, or by an HTTP request | ||||
|         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> | ||||
|         <title>Pre-Authentication Framework Classes</title> | ||||
|     <para> Because most pre-authentication mechanisms follow the same pattern, Spring Security has a | ||||
|       set of classes which provide an internal framework for implementing pre-authenticated | ||||
|       authentication providers. This removes duplication and allows new implementations to be added | ||||
|       in a structured fashion, without having to write everything from scratch. You don't need to | ||||
|       know about these classes if you want to use something like <link xlink:href="#x509">X.509 | ||||
|         authentication</link>, as it already has a namespace configuration option which is simpler | ||||
|       to use and get started with. If you need to use explicit bean configuration or are planning on | ||||
|       writing your own implementation then an understanding of how the provided implementations work | ||||
|       will be useful. You will find classes under the | ||||
|         <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> | ||||
|         <para> Because most pre-authentication mechanisms follow the same pattern, Spring Security | ||||
|             has a set of classes which provide an internal framework for implementing | ||||
|             pre-authenticated authentication providers. This removes duplication and allows new | ||||
|             implementations to be added in a structured fashion, without having to write everything | ||||
|             from scratch. You don't need to know about these classes if you want to use something | ||||
|             like <link xlink:href="#x509">X.509 authentication</link>, as it already has a namespace | ||||
|             configuration option which is simpler to use and get started with. If you need to use | ||||
|             explicit bean configuration or are planning on writing your own implementation then an | ||||
|             understanding of how the provided implementations work will be useful. You will find | ||||
|             classes under the | ||||
|             <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> | ||||
|             <title>AbstractPreAuthenticatedProcessingFilter</title> | ||||
|       <para> This class will check the current contents of the security context and, if empty, it | ||||
|         will attempt to extract user information from the HTTP request and submit it to the | ||||
|           <interfacename>AuthenticationManager</interfacename>. Subclasses override the following | ||||
|         methods to obtain this information: | ||||
|             <para> This class will check the current contents of the security context and, if empty, | ||||
|                 it will attempt to extract user information from the HTTP request and submit it to | ||||
|                 the <interfacename>AuthenticationManager</interfacename>. Subclasses override the | ||||
|                 following methods to obtain this information: | ||||
|                 <programlisting language="java"> | ||||
|   protected abstract Object getPreAuthenticatedPrincipal(HttpServletRequest request); | ||||
| 
 | ||||
|   protected abstract Object getPreAuthenticatedCredentials(HttpServletRequest request); | ||||
| </programlisting> | ||||
|                 After calling these, the filter will create a | ||||
|           <classname>PreAuthenticatedAuthenticationToken</classname> containing the returned data | ||||
|         and submit it for authentication. By <quote>authentication</quote> here, we really just mean | ||||
|         further processing to perhaps load the user's authorities, but the standard Spring Security | ||||
|         authentication architecture is followed. </para> | ||||
|                 <classname>PreAuthenticatedAuthenticationToken</classname> containing the returned | ||||
|                 data and submit it for authentication. By <quote>authentication</quote> here, we | ||||
|                 really just mean further processing to perhaps load the user's authorities, but the | ||||
|                 standard Spring Security authentication architecture is followed. </para> | ||||
|         </section> | ||||
|         <section> | ||||
|             <title>AbstractPreAuthenticatedAuthenticationDetailsSource</title> | ||||
|       <para> Like other Spring Security authentication filters, the pre-authentication filter has an | ||||
|           <literal>authenticationDetailsSource</literal> property which by default will create a | ||||
|           <classname>WebAuthenticationDetails</classname> object to store additional information | ||||
|         such as the session-identifier and originating IP address in the <literal>details</literal> | ||||
|         property of the <interfacename>Authentication</interfacename> object. In cases where user | ||||
|         role information can be obtained from the pre-authentication mechanism, the data is also | ||||
|             <para> Like other Spring Security authentication filters, the pre-authentication filter | ||||
|                 has an <literal>authenticationDetailsSource</literal> property which by default will | ||||
|                 create a <classname>WebAuthenticationDetails</classname> object to store additional | ||||
|                 information such as the session-identifier and originating IP address in the | ||||
|                 <literal>details</literal> property of the | ||||
|                 <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 | ||||
|           <classname>AbstractPreAuthenticatedAuthenticationDetailsSource</classname> use an extended | ||||
|         details object which implements the | ||||
|           <interfacename>GrantedAuthoritiesContainer</interfacename> interface, thus enabling the | ||||
|         authentication provider to read the authorities which were externally allocated to the user. | ||||
|         We'll look at a concrete example next. </para> | ||||
|                 <classname>AbstractPreAuthenticatedAuthenticationDetailsSource</classname> use an | ||||
|                 extended details object which implements the | ||||
|                 <interfacename>GrantedAuthoritiesContainer</interfacename> interface, thus enabling | ||||
|                 the authentication provider to read the authorities which were externally allocated | ||||
|                 to the user. We'll look at a concrete example next. </para> | ||||
|             <section xml:id="j2ee-preauth-details"> | ||||
|                 <title>J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource</title> | ||||
|         <para> If the filter is configured with an <literal>authenticationDetailsSource</literal> | ||||
|           which is an instance of this class, the authority information is obtained by calling the | ||||
|             <methodname>isUserInRole(String role)</methodname> method for each of a pre-determined | ||||
|           set of <quote>mappable roles</quote>. The class gets these from a configured | ||||
|             <interfacename>MappableAttributesRetriever</interfacename>. Possible implementations | ||||
|           include hard-coding a list in the application context and reading the role information | ||||
|           from the <literal><security-role></literal> information in a | ||||
|             <filename>web.xml</filename> file. The pre-authentication sample application uses the | ||||
|           latter approach. </para> | ||||
|         <para>There is an additional stage where the roles (or attributes) are mapped to Spring | ||||
|           Security <interfacename>GrantedAuthority</interfacename> objects using a configured | ||||
|             <interfacename>Attributes2GrantedAuthoritiesMapper</interfacename>. The default will | ||||
|           just add the usual <literal>ROLE_</literal> prefix to the names, but it gives you full | ||||
|           control over the behaviour. </para> | ||||
|                 <para> If the filter is configured with an | ||||
|                     <literal>authenticationDetailsSource</literal> which is an instance of this | ||||
|                     class, the authority information is obtained by calling the | ||||
|                     <methodname>isUserInRole(String role)</methodname> method for each of a | ||||
|                     pre-determined set of <quote>mappable roles</quote>. The class gets these from a | ||||
|                     configured <interfacename>MappableAttributesRetriever</interfacename>. Possible | ||||
|                     implementations include hard-coding a list in the application context and | ||||
|                     reading the role information from the <literal><security-role></literal> | ||||
|                     information in a <filename>web.xml</filename> file. The pre-authentication | ||||
|                     sample application uses the latter approach. </para> | ||||
|                 <para>There is an additional stage where the roles (or attributes) are mapped to | ||||
|                     Spring Security <interfacename>GrantedAuthority</interfacename> objects using a | ||||
|                     configured <interfacename>Attributes2GrantedAuthoritiesMapper</interfacename>. | ||||
|                     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> | ||||
|             <title>PreAuthenticatedAuthenticationProvider</title> | ||||
|             <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 | ||||
|         to a <interfacename>AuthenticationUserDetailsService</interfacename>. The latter is similar | ||||
|         to the standard <interfacename>UserDetailsService</interfacename> but takes an | ||||
|           <interfacename>Authentication</interfacename> object rather than just user name: | ||||
|                 <interfacename>UserDetails</interfacename> object for the user. It does this by | ||||
|                 delegating to a <interfacename>AuthenticationUserDetailsService</interfacename>. The | ||||
|                 latter is similar to the standard <interfacename>UserDetailsService</interfacename> | ||||
|                 but takes an <interfacename>Authentication</interfacename> object rather than just | ||||
|                 user name: | ||||
|                 <programlisting language="java"> | ||||
|   public interface AuthenticationUserDetailsService { | ||||
|     UserDetails loadUserDetails(Authentication token) throws UsernameNotFoundException; | ||||
|   } | ||||
| </programlisting> | ||||
|         This interface may have also other uses but with pre-authentication it allows access to the | ||||
|         authorities which were packaged in the <interfacename>Authentication</interfacename> object, | ||||
|         as we saw in the previous section. The | ||||
|           <classname>PreAuthenticatedGrantedAuthoritiesUserDetailsService</classname> class does | ||||
|         this. Alternatively, it may delegate to a standard | ||||
|                 This interface may have also other uses but with pre-authentication it allows access | ||||
|                 to the authorities which were packaged in the | ||||
|                 <interfacename>Authentication</interfacename> object, as we saw in the previous | ||||
|                 section. The | ||||
|                 <classname>PreAuthenticatedGrantedAuthoritiesUserDetailsService</classname> class | ||||
|                 does this. Alternatively, it may delegate to a standard | ||||
|                 <interfacename>UserDetailsService</interfacename> via the | ||||
|                 <classname>UserDetailsByNameServiceWrapper</classname> implementation. </para> | ||||
|         </section> | ||||
|         <section> | ||||
|             <title>Http403ForbiddenEntryPoint</title> | ||||
|       <para> The <interfacename>AuthenticationEntryPoint</interfacename> was discussed in the <link | ||||
|           xlink:href="#tech-intro-auth-entry-point">technical overview</link> chapter. Normally it | ||||
|         is responsible for kick-starting the authentication process for an unauthenticated user | ||||
|         (when they try to access a protected resource), but in the pre-authenticated case this | ||||
|         doesn't apply. You would only configure the | ||||
|           <classname>ExceptionTranslationFilter</classname> with an instance of this class if you | ||||
|         aren't using pre-authentication in combination with other authentication mechanisms. It will | ||||
|         be called if the user is rejected by the | ||||
|             <para> The <interfacename>AuthenticationEntryPoint</interfacename> was discussed in the | ||||
|                 <link xlink:href="#tech-intro-auth-entry-point">technical overview</link> chapter. | ||||
|                 Normally it is responsible for kick-starting the authentication process for an | ||||
|                 unauthenticated user (when they try to access a protected resource), but in the | ||||
|                 pre-authenticated case this doesn't apply. You would only configure the | ||||
|                 <classname>ExceptionTranslationFilter</classname> with an instance of this class if | ||||
|                 you aren't using pre-authentication in combination with other authentication | ||||
|                 mechanisms. It will be called if the user is rejected by the | ||||
|                 <classname>AbstractPreAuthenticatedProcessingFilter</classname> resulting in a null | ||||
|         authentication. It always returns a <literal>403</literal>-forbidden response code if | ||||
|         called. </para> | ||||
|                 authentication. It always returns a <literal>403</literal>-forbidden response code | ||||
|                 if called. </para> | ||||
|         </section> | ||||
|     </section> | ||||
|     <section> | ||||
|         <title>Concrete Implementations</title> | ||||
|     <para> X.509 authentication is covered in its <link xlink:href="#x509">own chapter</link>. Here | ||||
|       we'll look at some classes which provide support for other pre-authenticated scenarios. </para> | ||||
|         <para> X.509 authentication is covered in its <link xlink:href="#x509">own chapter</link>. | ||||
|             Here we'll look at some classes which provide support for other pre-authenticated | ||||
|             scenarios. </para> | ||||
|         <section> | ||||
|             <title>Request-Header Authentication (Siteminder)</title> | ||||
|       <para> An external authentication system may supply information to the application by setting | ||||
|         specific headers on the HTTP request. A well known example of this is Siteminder, which | ||||
|         passes the username in a header called <literal>SM_USER</literal>. This mechanism is | ||||
|         supported by the class <classname>RequestHeaderAuthenticationFilter</classname> which simply | ||||
|         extracts the 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> | ||||
|             <para> An external authentication system may supply information to the application by | ||||
|                 setting specific headers on the HTTP request. A well known example of this is | ||||
|                 Siteminder, which passes the username in a header called <literal>SM_USER</literal>. | ||||
|                 This mechanism is supported by the class | ||||
|                 <classname>RequestHeaderAuthenticationFilter</classname> which simply extracts the | ||||
|                 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> | ||||
|         <para>Note that when using a system like this, the framework performs no authentication | ||||
|           checks at all and it is <emphasis>extremely</emphasis> important that the external system | ||||
|           is configured properly and protects all access to the application. If an attacker is able | ||||
|           to forge the headers in their original request without this being detected then they could | ||||
|           potentially choose any username they wished. </para> | ||||
|                 <para>Note that when using a system like this, the framework performs no | ||||
|                     authentication checks at all and it is <emphasis>extremely</emphasis> important | ||||
|                     that the external system is configured properly and protects all access to the | ||||
|                     application. If an attacker is able to forge the headers in their original | ||||
|                     request without this being detected then they could potentially choose any | ||||
|                     username they wished. </para> | ||||
|             </tip> | ||||
|             <section> | ||||
|                 <title>Siteminder Example Configuration</title> | ||||
|  | @ -162,27 +174,28 @@ class="org.springframework.security.web.authentication.preauth.PreAuthenticatedA | |||
|       <security:authentication-provider ref="preauthAuthProvider" /> | ||||
|     </security-authentication-manager> | ||||
| ]]> | ||||
| </programlisting> We've assumed here that the security namespace is being used for | ||||
|           configuration (hence the user of the <literal>custom-filter</literal>, | ||||
| </programlisting> We've assumed here that the security namespace is being used for configuration | ||||
|                     (hence the user of the <literal>custom-filter</literal>, | ||||
|                     <literal>authentication-manager</literal> and | ||||
|             <literal>custom-authentication-provider</literal> elements (you can read more about them | ||||
|           in the <link xlink:href="ns-config">namespace chapter</link>). You would leave these out | ||||
|           of a traditional bean configuration. It's also assumed that you have added a | ||||
|             <interfacename>UserDetailsService</interfacename> (called | ||||
|             <quote>userDetailsService</quote>) to your configuration to load the user's roles. | ||||
|         </para> | ||||
|                     <literal>custom-authentication-provider</literal> elements (you can read more | ||||
|                     about them in the <link xlink:href="ns-config">namespace chapter</link>). You | ||||
|                     would leave these out of a traditional bean configuration. It's also assumed | ||||
|                     that you have added a <interfacename>UserDetailsService</interfacename> (called | ||||
|                     <quote>userDetailsService</quote>) to your configuration to load the user's | ||||
|                     roles. </para> | ||||
|             </section> | ||||
|         </section> | ||||
|         <section> | ||||
|             <title>J2EE Container Authentication</title> | ||||
|       <para> The class <classname>J2eePreAuthenticatedProcessingFilter</classname> will extract the | ||||
|         username from the <literal>userPrincipal</literal> property of the | ||||
|           <interfacename>HttpServletRequest</interfacename>. Use of this filter would usually be | ||||
|         combined with the use of J2EE roles as described above in <xref | ||||
|             <para> The class <classname>J2eePreAuthenticatedProcessingFilter</classname> will | ||||
|                 extract the username from the <literal>userPrincipal</literal> property of the | ||||
|                 <interfacename>HttpServletRequest</interfacename>. Use of this filter would usually | ||||
|                 be combined with the use of J2EE roles as described above in <xref | ||||
|                 linkend="j2ee-preauth-details"/>. </para> | ||||
|       <para> There is a sample application in the codebase which uses this approach, so get hold of | ||||
|         the code from subversion and have a look at the application context file if you are | ||||
|         interested. The code is in the <filename>samples/preauth</filename> directory. </para> | ||||
|             <para> There is a sample application in the codebase which uses this approach, so get | ||||
|                 hold of the code from subversion and have a look at the application context file if | ||||
|                 you are interested. The code is in the <filename>samples/preauth</filename> | ||||
|                 directory. </para> | ||||
|         </section> | ||||
|     </section> | ||||
| </chapter> | ||||
|  |  | |||
|  | @ -15,10 +15,9 @@ | |||
|             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> | ||||
|         <para> Note that both implemementations require a | ||||
|                 <interfacename>UserDetailsService</interfacename>. If you are using an | ||||
|             authentication provider which doesn't use a | ||||
|                 <interfacename>UserDetailsService</interfacename> (for example, the LDAP provider) | ||||
|             then it won't work unless you also have a | ||||
|             <interfacename>UserDetailsService</interfacename>. If you are using an authentication | ||||
|             provider which doesn't use a <interfacename>UserDetailsService</interfacename> (for | ||||
|             example, the LDAP provider) then it won't work unless you also have a | ||||
|             <interfacename>UserDetailsService</interfacename> bean in your application context. | ||||
|         </para> | ||||
|     </section> | ||||
|  | @ -63,12 +62,13 @@ | |||
|         <title>Persistent Token Approach</title> | ||||
|         <para>This approach is based on the article <link | ||||
|             xlink:href="http://jaspan.com/improved_persistent_login_cookie_best_practice" | ||||
|                 >http://jaspan.com/improved_persistent_login_cookie_best_practice</link> with some | ||||
|             minor modifications <footnote><para>Essentially, the username is not included in the | ||||
|                     cookie, to prevent exposing a valid login name unecessarily. There is a | ||||
|                     discussion on this in the comments section of this article.</para></footnote>. | ||||
|             To use the this approach with namespace configuration, you would supply a datasource | ||||
|             reference: <programlisting><![CDATA[ | ||||
|             >http://jaspan.com/improved_persistent_login_cookie_best_practice</link> with some minor | ||||
|             modifications <footnote> | ||||
|             <para>Essentially, the username is not included in the cookie, to prevent exposing a | ||||
|                 valid login name unecessarily. There is a discussion on this in the comments section | ||||
|                 of this article.</para> | ||||
|             </footnote>. To use the this approach with namespace configuration, you would supply a | ||||
|             datasource reference: <programlisting><![CDATA[ | ||||
|   <http> | ||||
|     ... | ||||
|     <remember-me data-source-ref="someDataSource"/> | ||||
|  | @ -91,10 +91,10 @@ | |||
|         </info> | ||||
|         <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 | ||||
|                 <literal>UsernamePasswordAuthenticationFilter</literal>, and is implemented via | ||||
|             hooks in the <literal>AbstractAuthenticationProcessingFilter</literal> superclass. The | ||||
|             hooks will invoke a concrete <interfacename>RememberMeServices</interfacename> at the | ||||
|             appropriate times. The interface looks like this: | ||||
|             <literal>UsernamePasswordAuthenticationFilter</literal>, and is implemented via hooks in | ||||
|             the <literal>AbstractAuthenticationProcessingFilter</literal> superclass. The hooks will | ||||
|             invoke a concrete <interfacename>RememberMeServices</interfacename> at the appropriate | ||||
|             times. The interface looks like this: | ||||
|             <programlisting language="java"> | ||||
|   Authentication autoLogin(HttpServletRequest request, HttpServletResponse response); | ||||
|   void loginFail(HttpServletRequest request, HttpServletResponse response); | ||||
|  | @ -122,12 +122,12 @@ | |||
|                 <literal>RememberMeAuthenticationProvider</literal>. A <literal>key</literal> is | ||||
|                 shared between this authentication provider and the | ||||
|                 <literal>TokenBasedRememberMeServices</literal>. In addition, | ||||
|                     <literal>TokenBasedRememberMeServices</literal> requires A UserDetailsService | ||||
|                 from which it can retrieve the username and password for signature comparison | ||||
|                 purposes, and generate the <literal>RememberMeAuthenticationToken</literal> to | ||||
|                 contain the correct <interfacename>GrantedAuthority</interfacename>[]s. Some sort of | ||||
|                 logout command should be provided by the application that invalidates the cookie if | ||||
|                 the user requests this. <classname>TokenBasedRememberMeServices</classname> also | ||||
|                 <literal>TokenBasedRememberMeServices</literal> requires A UserDetailsService from | ||||
|                 which it can retrieve the username and password for signature comparison purposes, | ||||
|                 and generate the <literal>RememberMeAuthenticationToken</literal> to contain the | ||||
|                 correct <interfacename>GrantedAuthority</interfacename>[]s. Some sort of logout | ||||
|                 command should be provided by the application that invalidates the cookie if the | ||||
|                 user requests this. <classname>TokenBasedRememberMeServices</classname> also | ||||
|                 implements Spring Security's <interfacename>LogoutHandler</interfacename> interface | ||||
|                 so can be used with <classname>LogoutFilter</classname> to have the cookie cleared | ||||
|                 automatically. </para> | ||||
|  | @ -162,14 +162,18 @@ | |||
|         <section> | ||||
|             <title>PersistentTokenBasedRememberMeServices</title> | ||||
|             <para> This class can be used in the same way as | ||||
|                     <classname>TokenBasedRememberMeServices</classname>, but it additionally needs | ||||
|                 to be configured with a <interfacename>PersistentTokenRepository</interfacename> to | ||||
|                 store the tokens. There are two standard implementations. | ||||
|                                 <itemizedlist><listitem><para><classname>InMemoryTokenRepositoryImpl</classname> | ||||
|                             which is intended for testing | ||||
|                                 only.</para></listitem><listitem><para><classname>JdbcTokenRepositoryImpl</classname> | ||||
|                             which stores the tokens in a database. </para></listitem></itemizedlist> | ||||
|                 The database schema is described above in <xref | ||||
|                 <classname>TokenBasedRememberMeServices</classname>, but it additionally needs to be | ||||
|                 configured with a <interfacename>PersistentTokenRepository</interfacename> to store | ||||
|                 the tokens. There are two standard implementations. <itemizedlist> | ||||
|                 <listitem> | ||||
|                     <para><classname>InMemoryTokenRepositoryImpl</classname> which is intended for | ||||
|                         testing only.</para> | ||||
|                 </listitem> | ||||
|                 <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> | ||||
|         </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"> | ||||
|         <info><title>Overview</title></info> | ||||
|         <info> | ||||
|             <title>Overview</title> | ||||
|         </info> | ||||
| 
 | ||||
|         <para>The <classname>AbstractSecurityInterceptor</classname> is able to | ||||
|             temporarily replace the <interfacename>Authentication</interfacename> object in | ||||
|             the <interfacename>SecurityContext</interfacename> and | ||||
|             <classname>SecurityContextHolder</classname> during the secure object | ||||
|             callback phase. This only occurs if the original | ||||
|             <interfacename>Authentication</interfacename> object was successfully processed by | ||||
|             the <interfacename>AuthenticationManager</interfacename> and | ||||
|             <interfacename>AccessDecisionManager</interfacename>. The | ||||
|         <para>The <classname>AbstractSecurityInterceptor</classname> is able to temporarily replace | ||||
|             the <interfacename>Authentication</interfacename> object in the | ||||
|             <interfacename>SecurityContext</interfacename> and | ||||
|             <classname>SecurityContextHolder</classname> during the secure object callback phase. | ||||
|             This only occurs if the original <interfacename>Authentication</interfacename> object | ||||
|             was successfully processed by the <interfacename>AuthenticationManager</interfacename> | ||||
|             and <interfacename>AccessDecisionManager</interfacename>. The | ||||
|             <literal>RunAsManager</literal> will indicate the replacement | ||||
|             <interfacename>Authentication</interfacename> object, if any, that should be used | ||||
|             during the <literal>SecurityInterceptorCallback</literal>.</para> | ||||
|             <interfacename>Authentication</interfacename> object, if any, that should be used during | ||||
|             the <literal>SecurityInterceptorCallback</literal>.</para> | ||||
| 
 | ||||
|         <para>By temporarily replacing the <interfacename>Authentication</interfacename> | ||||
|             object during the secure object callback phase, the secured invocation | ||||
|             will be able to call other objects which require different | ||||
|             authentication and authorization credentials. It will also be able to | ||||
|             perform any internal security checks for specific | ||||
|         <para>By temporarily replacing the <interfacename>Authentication</interfacename> object | ||||
|             during the secure object callback phase, the secured invocation will be able to call | ||||
|             other objects which require different authentication and authorization credentials. It | ||||
|             will also be able to perform any internal security checks for specific | ||||
|             <interfacename>GrantedAuthority</interfacename> objects. Because Spring Security | ||||
|             provides a number of helper classes that automatically configure | ||||
|             remoting protocols based on the contents of the | ||||
|             <classname>SecurityContextHolder</classname>, these run-as replacements | ||||
|             are particularly useful when calling remote web services</para> | ||||
|             provides a number of helper classes that automatically configure remoting protocols | ||||
|             based on the contents of the <classname>SecurityContextHolder</classname>, these run-as | ||||
|             replacements are particularly useful when calling remote web services</para> | ||||
|     </section> | ||||
| 
 | ||||
|     <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: | ||||
|             <programlisting> | ||||
|   Authentication buildRunAs(Authentication authentication, Object object, | ||||
|       List<ConfigAttribute> config); | ||||
|   boolean supports(ConfigAttribute attribute); | ||||
|   boolean supports(Class clazz); | ||||
|             </programlisting> | ||||
|         </para> | ||||
|             </programlisting> </para> | ||||
| 
 | ||||
|         <para>The first method returns the <interfacename>Authentication</interfacename> | ||||
|             object that should replace the existing | ||||
|             <interfacename>Authentication</interfacename> object for the duration of the | ||||
|             method invocation. If the method returns <literal>null</literal>, it | ||||
|             indicates no replacement should be made. The second method is used by | ||||
|             the <classname>AbstractSecurityInterceptor</classname> as part of its | ||||
|             startup validation of configuration attributes. The | ||||
|             <literal>supports(Class)</literal> method is called by a security | ||||
|             interceptor implementation to ensure the configured | ||||
|             <literal>RunAsManager</literal> supports the type of secure object | ||||
|             that the security interceptor will present.</para> | ||||
|         <para>The first method returns the <interfacename>Authentication</interfacename> object that | ||||
|             should replace the existing <interfacename>Authentication</interfacename> object for the | ||||
|             duration of the method invocation. If the method returns <literal>null</literal>, it | ||||
|             indicates no replacement should be made. The second method is used by the | ||||
|             <classname>AbstractSecurityInterceptor</classname> as part of its startup validation of | ||||
|             configuration attributes. The <literal>supports(Class)</literal> method is called by a | ||||
|             security interceptor implementation to ensure the configured | ||||
|             <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> | ||||
|             is provided with Spring Security. The | ||||
|             <literal>RunAsManagerImpl</literal> class returns a replacement | ||||
|             <literal>RunAsUserToken</literal> if any | ||||
|             <literal>ConfigAttribute</literal> starts with | ||||
|             <literal>RUN_AS_</literal>. If any such | ||||
|             <literal>ConfigAttribute</literal> is found, the replacement | ||||
|             <literal>RunAsUserToken</literal> will contain the same principal, | ||||
|         <para>One concrete implementation of a <literal>RunAsManager</literal> is provided with | ||||
|             Spring Security. The <literal>RunAsManagerImpl</literal> class returns a replacement | ||||
|             <literal>RunAsUserToken</literal> if any <literal>ConfigAttribute</literal> starts with | ||||
|             <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 | ||||
|             <interfacename>Authentication</interfacename> object, along with a new | ||||
|             <literal>GrantedAuthorityImpl</literal> for each | ||||
|             <literal>RUN_AS_</literal> <literal>ConfigAttribute</literal>. Each | ||||
|             new <literal>GrantedAuthorityImpl</literal> will be prefixed with | ||||
|             <literal>ROLE_</literal>, followed by the <literal>RUN_AS</literal> | ||||
|             <literal>ConfigAttribute</literal>. For example, a | ||||
|             <literal>GrantedAuthorityImpl</literal> for each <literal>RUN_AS_</literal> | ||||
|             <literal>ConfigAttribute</literal>. Each new <literal>GrantedAuthorityImpl</literal> | ||||
|             will be prefixed with <literal>ROLE_</literal>, followed by the | ||||
|             <literal>RUN_AS</literal> <literal>ConfigAttribute</literal>. For example, a | ||||
|             <literal>RUN_AS_SERVER</literal> will result in the replacement | ||||
|             <literal>RunAsUserToken</literal> containing a | ||||
|             <literal>ROLE_RUN_AS_SERVER</literal> granted authority.</para> | ||||
|             <literal>RunAsUserToken</literal> containing a <literal>ROLE_RUN_AS_SERVER</literal> | ||||
|             granted authority.</para> | ||||
| 
 | ||||
|         <para>The replacement <literal>RunAsUserToken</literal> is just like | ||||
|             any other <interfacename>Authentication</interfacename> object. It needs to be | ||||
|             authenticated by the <interfacename>AuthenticationManager</interfacename>, | ||||
|             probably via delegation to a suitable | ||||
|             <classname>AuthenticationProvider</classname>. The | ||||
|             <literal>RunAsImplAuthenticationProvider</literal> performs such | ||||
|             authentication. It simply accepts as valid any | ||||
|             <literal>RunAsUserToken</literal> presented.</para> | ||||
|         <para>The replacement <literal>RunAsUserToken</literal> is just like any other | ||||
|             <interfacename>Authentication</interfacename> object. It needs to be authenticated by | ||||
|             the <interfacename>AuthenticationManager</interfacename>, probably via delegation to a | ||||
|             suitable <classname>AuthenticationProvider</classname>. The | ||||
|             <literal>RunAsImplAuthenticationProvider</literal> performs such authentication. It | ||||
|             simply accepts as valid any <literal>RunAsUserToken</literal> presented.</para> | ||||
| 
 | ||||
|         <para>To ensure malicious code does not create a | ||||
|             <literal>RunAsUserToken</literal> and present it for guaranteed | ||||
|             acceptance by the <literal>RunAsImplAuthenticationProvider</literal>, | ||||
|             the hash of a key is stored in all generated tokens. The | ||||
|             <literal>RunAsManagerImpl</literal> and | ||||
|             <literal>RunAsImplAuthenticationProvider</literal> is created in the | ||||
|             bean context with the same key: | ||||
|             <programlisting> | ||||
|         <para>To ensure malicious code does not create a <literal>RunAsUserToken</literal> and | ||||
|             present it for guaranteed acceptance by the | ||||
|             <literal>RunAsImplAuthenticationProvider</literal>, the hash of a key is stored in all | ||||
|             generated tokens. The <literal>RunAsManagerImpl</literal> and | ||||
|             <literal>RunAsImplAuthenticationProvider</literal> is created in the bean context with | ||||
|             the same key: <programlisting> | ||||
| <![CDATA[ | ||||
| <bean id="runAsManager" | ||||
|     class="org.springframework.security.access.intercept.RunAsManagerImpl"> | ||||
|  | @ -97,10 +89,9 @@ | |||
|     class="org.springframework.security.access.intercept.RunAsImplAuthenticationProvider"> | ||||
|   <property name="key" value="my_run_as_password"/> | ||||
| </bean>]]></programlisting></para> | ||||
|         <para>By using the same key, each <literal>RunAsUserToken</literal> | ||||
|             can be validated it was created by an approved | ||||
|             <literal>RunAsManagerImpl</literal>. The | ||||
|             <literal>RunAsUserToken</literal> is immutable after creation for | ||||
|             security reasons</para> | ||||
|         <para>By using the same key, each <literal>RunAsUserToken</literal> can be validated it was | ||||
|             created by an approved <literal>RunAsManagerImpl</literal>. The | ||||
|             <literal>RunAsUserToken</literal> is immutable after creation for security | ||||
|             reasons</para> | ||||
|     </section> | ||||
| </chapter> | ||||
|  |  | |||
|  | @ -10,22 +10,22 @@ | |||
|         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 | ||||
|         <link xlink:href="http://www.springsource.org/security/"> | ||||
|             http://www.springsource.org/security/ </link> if you need it. All paths referred to in | ||||
|         this chapter are relative to the project source directory. </para> | ||||
|         http://www.springsource.org/security/ </link> if you need it. All paths referred to in this | ||||
|         chapter are relative to the project source directory. </para> | ||||
|     <section xml:id="tutorial-sample"> | ||||
|         <title>Tutorial Sample</title> | ||||
|         <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 | ||||
|             distribution zip file, ready to be deployed into your web container | ||||
|             (<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 | ||||
|             in combination with the commonly-used <link xlink:href="#remember-me">remember-me</link> | ||||
|             xlink:href="#ns-form-and-basic">form-based</link> authentication mechanism is used in | ||||
|             combination with the commonly-used <link xlink:href="#remember-me">remember-me</link> | ||||
|             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 | ||||
|             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 | ||||
|             basic integration is achieved do we suggest you attempt adding in method authorization | ||||
|             or domain object security.</para> | ||||
|             <literal>web.xml</literal> entries) to your existing application. Only when this basic | ||||
|             integration is achieved do we suggest you attempt adding in method authorization or | ||||
|             domain object security.</para> | ||||
|     </section> | ||||
|     <section xml:id="contacts-sample"> | ||||
|         <title>Contacts</title> | ||||
|  | @ -35,11 +35,11 @@ | |||
|             administer a simple database of contacts (the domain objects).</para> | ||||
|         <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 | ||||
|                 <filename>spring-security-samples-contacts-3.0.x.war</filename> (the appended | ||||
|             version number will vary depending on what release you are using). </para> | ||||
|             <filename>spring-security-samples-contacts-3.0.x.war</filename> (the appended version | ||||
|             number will vary depending on what release you are using). </para> | ||||
|         <para>After starting your container, check the application can load. Visit | ||||
|                 <literal>http://localhost:8080/contacts</literal> (or whichever URL is appropriate | ||||
|             for your web container and the WAR you deployed). </para> | ||||
|             <literal>http://localhost:8080/contacts</literal> (or whichever URL is appropriate for | ||||
|             your web container and the WAR you deployed). </para> | ||||
|         <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 | ||||
|             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 | ||||
|             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 | ||||
|                 <literal>ROLE_SUPERVISOR</literal> are granted access to delete their contacts. | ||||
|             Behind the scenes, the <classname>MethodSecurityInterceptor</classname> is securing the | ||||
|             <literal>ROLE_SUPERVISOR</literal> are granted access to delete their contacts. Behind | ||||
|             the scenes, the <classname>MethodSecurityInterceptor</classname> is securing the | ||||
|             business objects. </para> | ||||
|         <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 | ||||
|  | @ -103,12 +103,12 @@ Success! Your web filters appear to be properly configured! | |||
|         <title>CAS Sample</title> | ||||
|         <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 | ||||
|                 <link xlink:href="get-source">the introduction</link>. You'll find the relevant | ||||
|             files 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 | ||||
|             server and the client directly from the source tree, complete with SSL support. You have | ||||
|             to download the CAS Server web application (a war file) from the CAS site and drop it | ||||
|             into the <filename>samples/cas/server</filename> directory. </para> | ||||
|             <link xlink:href="get-source">the introduction</link>. You'll find the relevant files | ||||
|             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 server | ||||
|             and the client directly from the source tree, complete with SSL support. You have to | ||||
|             download the CAS Server web application (a war file) from the CAS site and drop it into | ||||
|             the <filename>samples/cas/server</filename> directory. </para> | ||||
|     </section> | ||||
|     <section xml:id="preauth-sample"> | ||||
|         <title>Pre-Authentication Sample</title> | ||||
|  |  | |||
|  | @ -7,26 +7,28 @@ | |||
|         <info> | ||||
|             <title>AOP Alliance (MethodInvocation) Security Interceptor</title> | ||||
|         </info> | ||||
|     <para> Prior to Spring Security 2.0, securing <classname>MethodInvocation</classname>s needed | ||||
|       quite a lot of boiler plate configuration. Now the recommended approach for method security is | ||||
|       to use <link xlink:href="#ns-method-security">namespace configuration</link>. This way the | ||||
|       method security infrastructure beans are configured automatically for you so you don't really | ||||
|       need to know about the implementation classes. We'll just provide a quick overview of the | ||||
|       classes that are involved here. </para> | ||||
|         <para> Prior to Spring Security 2.0, securing <classname>MethodInvocation</classname>s | ||||
|             needed quite a lot of boiler plate configuration. Now the recommended approach for | ||||
|             method security is to use <link xlink:href="#ns-method-security">namespace | ||||
|             configuration</link>. This way the method security infrastructure beans are configured | ||||
|             automatically for you so you don't really need to know about the implementation classes. | ||||
|             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>, | ||||
|             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. | ||||
|       The interceptor uses a <interfacename>MethodSecurityMetadataSource</interfacename> instance to | ||||
|       obtain the configuration attributes that apply to a particular method invocation. | ||||
|         <classname>MapBasedMethodSecurityMetadataSource</classname> is used to store 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 | ||||
|             approach, an interceptor may be specific to a single bean or shared between multiple | ||||
|             beans. The interceptor uses a | ||||
|             <interfacename>MethodSecurityMetadataSource</interfacename> instance to obtain the | ||||
|             configuration attributes that apply to a particular method invocation. | ||||
|             <classname>MapBasedMethodSecurityMetadataSource</classname> is used to store | ||||
|             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> | ||||
|             elements. Other implementations will be used to handle annotation-based configuration. </para> | ||||
|         <section> | ||||
|             <title>Explicit MethodSecurityInterceptor Configuration</title> | ||||
|       <para> You can of course configure a <classname>MethodSecurityIterceptor</classname> directly | ||||
|         in your application context for use with one of Spring AOP's proxying mechanisms: <programlisting><![CDATA[ | ||||
|             <para> You can of course configure a <classname>MethodSecurityIterceptor</classname> | ||||
|                 directly in your application context for use with one of Spring AOP's proxying | ||||
|                 mechanisms: <programlisting><![CDATA[ | ||||
| <bean id="bankManagerSecurity" class= | ||||
|     "org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor"> | ||||
|   <property name="authenticationManager" ref="authenticationManager"/> | ||||
|  | @ -46,19 +48,20 @@ | |||
|         <info> | ||||
|             <title>AspectJ (JoinPoint) Security Interceptor</title> | ||||
|         </info> | ||||
|     <para>The AspectJ security interceptor is very similar to the AOP Alliance security interceptor | ||||
|       discussed in the previous section. Indeed we will only discuss the differences in this | ||||
|       section.</para> | ||||
|     <para>The AspectJ interceptor is named <literal>AspectJSecurityInterceptor</literal>. Unlike the | ||||
|       AOP Alliance security interceptor, which relies on the Spring application context to weave in | ||||
|       the security interceptor via proxying, the <literal>AspectJSecurityInterceptor</literal> is | ||||
|       weaved in via the AspectJ compiler. It would not be uncommon to use both types of security | ||||
|       interceptors in the same application, with <literal>AspectJSecurityInterceptor</literal> being | ||||
|       used for domain object instance security and the AOP Alliance | ||||
|         <para>The AspectJ security interceptor is very similar to the AOP Alliance security | ||||
|             interceptor discussed in the previous section. Indeed we will only discuss the | ||||
|             differences in this section.</para> | ||||
|         <para>The AspectJ interceptor is named <literal>AspectJSecurityInterceptor</literal>. Unlike | ||||
|             the AOP Alliance security interceptor, which relies on the Spring application context to | ||||
|             weave in the security interceptor via proxying, the | ||||
|             <literal>AspectJSecurityInterceptor</literal> is weaved in via the AspectJ compiler. It | ||||
|             would not be uncommon to use both types of security interceptors in the same | ||||
|             application, with <literal>AspectJSecurityInterceptor</literal> being used for domain | ||||
|             object instance security and the AOP Alliance | ||||
|             <classname>MethodSecurityInterceptor</classname> being used for services layer | ||||
|             security.</para> | ||||
|     <para>Let's first consider how the <literal>AspectJSecurityInterceptor</literal> is configured | ||||
|       in the Spring application context:</para> | ||||
|         <para>Let's first consider how the <literal>AspectJSecurityInterceptor</literal> is | ||||
|             configured in the Spring application context:</para> | ||||
|         <programlisting><![CDATA[ | ||||
| <bean id="bankManagerSecurity" class= | ||||
|     "org.springframework.security.access.intercept.aspectj.AspectJSecurityInterceptor"> | ||||
|  | @ -77,11 +80,11 @@ | |||
|             security interceptor. Indeed the two interceptors can share the same | ||||
|             <literal>securityMetadataSource</literal>, as the | ||||
|             <interfacename>SecurityMetadataSource</interfacename> works with | ||||
|         <literal>java.lang.reflect.Method</literal>s rather than an AOP library-specific class. Of | ||||
|       course, your access decisions have access to the relevant AOP library-specific invocation (ie | ||||
|         <classname>MethodInvocation</classname> or <literal>JoinPoint</literal>) and as such can | ||||
|       consider a range of addition criteria when making access decisions (such as method | ||||
|       arguments).</para> | ||||
|             <literal>java.lang.reflect.Method</literal>s rather than an AOP library-specific class. | ||||
|             Of course, your access decisions have access to the relevant AOP library-specific | ||||
|             invocation (ie <classname>MethodInvocation</classname> or <literal>JoinPoint</literal>) | ||||
|             and as such can consider a range of addition criteria when making access decisions (such | ||||
|             as method arguments).</para> | ||||
|         <para>Next you'll need to define an AspectJ <literal>aspect</literal>. For example:</para> | ||||
|         <programlisting language="java"> | ||||
| package org.springframework.security.samples.aspectj; | ||||
|  | @ -127,12 +130,13 @@ public aspect DomainObjectInstanceSecurityAspect implements InitializingBean { | |||
| } | ||||
| </programlisting> | ||||
|         <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 | ||||
|       other class or <literal>pointcut</literal> expression you like). For those curious, | ||||
|             <literal>PersistableEntity</literal>, which is an abstract class not shown (you can use | ||||
|             any other class or <literal>pointcut</literal> expression you like). For those curious, | ||||
|             <literal>AspectJCallback</literal> is needed because the <literal>proceed();</literal> | ||||
|             statement has special meaning only within an <literal>around()</literal> body. The | ||||
|             <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 | ||||
|             <literal>AspectJSecurityInterceptor</literal>. A bean declaration which achieves this is | ||||
|             shown below:</para> | ||||
|  | @ -144,7 +148,7 @@ public aspect DomainObjectInstanceSecurityAspect implements InitializingBean { | |||
| </bean>]]> | ||||
|     </programlisting> | ||||
|         <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 | ||||
|       security interceptor applied.</para> | ||||
|             whatever means you think fit (eg <literal>new Person();</literal>) and they will have | ||||
|             the security interceptor applied.</para> | ||||
|     </section> | ||||
| </chapter> | ||||
|  |  | |||
|  | @ -4,29 +4,29 @@ | |||
|         <title>The Security Filter Chain</title> | ||||
|     </info> | ||||
|     <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 | ||||
|     it has no strong links to any particular web technology. It deals in | ||||
|       <classname>HttpServletRequest</classname>s and <classname>HttpServletResponse</classname>s and | ||||
|     doesn't care whether the requests come from a browser, a web service client, an | ||||
|         doesn't use servlets or any other servlet-based frameworks (such as Spring MVC) internally, | ||||
|         so it has no strong links to any particular web technology. It deals in | ||||
|         <classname>HttpServletRequest</classname>s and <classname>HttpServletResponse</classname>s | ||||
|         and doesn't care whether the requests come 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 | ||||
|     particular responsibility and filters are added or removed from the configuration depending on | ||||
|     which services are required. The ordering of the filters is important as there are 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 | ||||
|     to define any Spring beans explicitly but here may be times when you want full control over the | ||||
|     security filter 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> | ||||
|         particular responsibility and filters are added or removed from the configuration depending | ||||
|         on which services are required. The ordering of the filters is important as there are | ||||
|         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 to define any Spring beans explicitly but here may be times when you want full control | ||||
|         over the security filter 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"> | ||||
|         <title><classname>DelegatingFilterProxy</classname></title> | ||||
|         <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 | ||||
|       Security, the filter classes are also Spring beans defined in the application context and thus | ||||
|       able to take advantage of Spring's rich dependency-injection facilities and lifecycle | ||||
|       interfaces. Spring's <classname>DelegatingFilterProxy</classname> provides the link between | ||||
|         <filename>web.xml</filename> and the application context. </para> | ||||
|     <para>When using <classname>DelegatingFilterProxy</classname>, you will see something like this | ||||
|       in the <filename>web.xml</filename> file: <programlisting><![CDATA[ | ||||
|             <filename>web.xml</filename>, or they will be ignored by the servlet container. In | ||||
|             Spring Security, the filter classes are also Spring beans defined in the application | ||||
|             context and thus able to take advantage of Spring's rich dependency-injection facilities | ||||
|             and lifecycle interfaces. Spring's <classname>DelegatingFilterProxy</classname> provides | ||||
|             the link between <filename>web.xml</filename> and the application context. </para> | ||||
|         <para>When using <classname>DelegatingFilterProxy</classname>, you will see something like | ||||
|             this in the <filename>web.xml</filename> file: <programlisting><![CDATA[ | ||||
|   <filter> | ||||
|     <filter-name>myFilter</filter-name> | ||||
|     <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> | ||||
|  | @ -37,29 +37,29 @@ | |||
|     <url-pattern>/*</url-pattern> | ||||
|   </filter-mapping>]]> | ||||
|       </programlisting> Notice that the filter is actually a | ||||
|         <literal>DelegatingFilterProxy</literal>, and not the class that will actually implement the | ||||
|       logic of the filter. What <classname>DelegatingFilterProxy</classname> does is delegate the | ||||
|         <interfacename>Filter</interfacename>'s methods through to a bean which is obtained from the | ||||
|       Spring application context. This enables the bean to benefit from the Spring web application | ||||
|       context lifecycle support and configuration flexibility. The bean must implement | ||||
|         <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 | ||||
|             <literal>DelegatingFilterProxy</literal>, and not the class that will actually implement | ||||
|             the logic of the filter. What <classname>DelegatingFilterProxy</classname> does is | ||||
|             delegate the <interfacename>Filter</interfacename>'s methods through to a bean which is | ||||
|             obtained from the Spring application context. This enables the bean to benefit from the | ||||
|             Spring web application context lifecycle support and configuration flexibility. The bean | ||||
|             must implement <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> | ||||
|     </section> | ||||
|     <section xml:id="filter-chain-proxy"> | ||||
|         <title><classname>FilterChainProxy</classname></title> | ||||
|         <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 | ||||
|         <classname>DelegatingFilterProxy</classname> entry to <filename>web.xml</filename> for each | ||||
|       filter, making sure that they are ordered correctly. This is a cumbersome approach and | ||||
|       clutters up the <filename>web.xml</filename> file quickly if we have a lot of filters. We | ||||
|       would prefer to just add a single entry to <filename>web.xml</filename> and deal entirely with | ||||
|       the application context file for managing our web security beans. This is where Spring | ||||
|       Secuiryt's <classname>FilterChainProxy</classname> comes in. It is wired using a | ||||
|         <literal>DelegatingFilterProxy</literal>, just like in the example above, but with the | ||||
|         <literal>filter-name</literal> set to the bean name <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[ | ||||
|             <classname>DelegatingFilterProxy</classname> entry to <filename>web.xml</filename> for | ||||
|             each filter, making sure that they are ordered correctly. This is a cumbersome approach | ||||
|             and clutters up the <filename>web.xml</filename> file quickly if we have a lot of | ||||
|             filters. We would prefer to just add a single entry to <filename>web.xml</filename> and | ||||
|             deal entirely with the application context file for managing our web security beans. | ||||
|             This is where Spring Secuirity's <classname>FilterChainProxy</classname> comes in. It is | ||||
|             wired using a <literal>DelegatingFilterProxy</literal>, just like in the example above, | ||||
|             but with the <literal>filter-name</literal> set to the bean name | ||||
|             <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"> | ||||
|   <sec:filter-chain-map path-type="ant"> | ||||
|      <sec:filter-chain pattern="/webServices/**" filters=" | ||||
|  | @ -75,104 +75,114 @@ | |||
|   </sec:filter-chain-map> | ||||
| </bean> | ||||
| ]]> | ||||
|     </programlisting> The namespace element <literal>filter-chain-map</literal> is used | ||||
|       to set 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 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 names specified in the | ||||
|         <literal>filters</literal> element. Both regular expressions 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 | ||||
|       current web request and the list of filter beans specified by the <literal>filters</literal> | ||||
|       attribute will be applied to that request. The filters will be invoked in the order they are | ||||
|       defined, so you have complete control over the filter chain which is applied to a particular | ||||
|       URL.</para> | ||||
|     </programlisting> The namespace element <literal>filter-chain-map</literal> is used to set | ||||
|             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 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 names specified in the <literal>filters</literal> element. Both regular expressions | ||||
|             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 current web request and the list of filter beans specified by the | ||||
|             <literal>filters</literal> attribute will be applied to that request. The filters will | ||||
|             be invoked in the order they are defined, so you have complete control over the filter | ||||
|             chain which is applied to a particular URL.</para> | ||||
|         <para>You may have noticed we have declared two | ||||
|             <classname>SecurityContextPersistenceFilter</classname>s in the filter chain | ||||
|         (<literal>ASC</literal> is short for <literal>allowSessionCreation</literal>, a property of | ||||
|         <classname>SecurityContextPersistenceFilter</classname>). As web services will never present | ||||
|       a <literal>jsessionid</literal> on future requests, creating <literal>HttpSession</literal>s | ||||
|       for such user agents would be wasteful. If you had a high-volume application which required | ||||
|       maximum scalability, we recommend you use the approach shown above. For smaller applications, | ||||
|       using a single <classname>SecurityContextPersistenceFilter</classname> (with its default | ||||
|             (<literal>ASC</literal> is short for <literal>allowSessionCreation</literal>, a property | ||||
|             of <classname>SecurityContextPersistenceFilter</classname>). As web services will never | ||||
|             present a <literal>jsessionid</literal> on future requests, creating | ||||
|             <literal>HttpSession</literal>s for such user agents would be wasteful. If you had a | ||||
|             high-volume application which required maximum scalability, we recommend you use the | ||||
|             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 | ||||
|             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" | ||||
|         >namespace configuration</link>, we used a <literal>DelegatingFilterProxy</literal> with the | ||||
|       name <quote>springSecurityFilterChain</quote>. You should now be able to see that this is the | ||||
|       name of the <classname>FilterChainProxy</classname> which is created by the namespace. </para> | ||||
|             >namespace configuration</link>, we used a <literal>DelegatingFilterProxy</literal> with | ||||
|             the name <quote>springSecurityFilterChain</quote>. You should now be able to see that | ||||
|             this is the name of the <classname>FilterChainProxy</classname> which is created by the | ||||
|             namespace. </para> | ||||
|         <section> | ||||
|             <title>Bypassing the Filter Chain</title> | ||||
|       <para> As with the namespace, you can use the attribute <literal>filters = "none"</literal> as | ||||
|         an alternative to supplying a filter bean list. This will omit the request pattern from the | ||||
|         security filter chain entirely. Note that anything matching this path will then have no | ||||
|         authentication or authorization services applied and will be freely accessible. If you want | ||||
|         to make use of the contents of the <classname>SecurityContext</classname> contents during a | ||||
|         request, then it must have passed through the security filter chain. Otherwise the | ||||
|           <classname>SecurityContextHolder</classname> will not have been populated and the contents | ||||
|         will be null.</para> | ||||
|             <para> As with the namespace, you can use the attribute <literal>filters = | ||||
|                 "none"</literal> as an alternative to supplying a filter bean list. This will omit | ||||
|                 the request pattern from the security filter chain entirely. Note that anything | ||||
|                 matching this path will then have no authentication or authorization services | ||||
|                 applied and will be freely accessible. If you want to make use of the contents of | ||||
|                 the <classname>SecurityContext</classname> contents during a request, then it must | ||||
|                 have passed through the security filter chain. Otherwise the | ||||
|                 <classname>SecurityContextHolder</classname> will not have been populated and the | ||||
|                 contents will be null.</para> | ||||
|         </section> | ||||
|     </section> | ||||
|     <section> | ||||
|         <title>Filter Ordering</title> | ||||
|     <para>The order that filters are defined in the chain is very important. Irrespective of which | ||||
|       filters you are actually using, the order should be as follows: | ||||
|               <orderedlist><listitem><para><classname>ChannelProcessingFilter</classname>, because | ||||
|             it might need to redirect to a different | ||||
|               protocol</para></listitem><listitem><para><classname>ConcurrentSessionFilter</classname>, | ||||
|             because it doesn't use any <classname>SecurityContextHolder</classname> functionality | ||||
|             but needs to update the <interfacename>SessionRegistry</interfacename> to reflect | ||||
|             ongoing requests from the | ||||
|               principal</para></listitem><listitem><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 - | ||||
|         <para>The order that filters are defined in the chain is very important. Irrespective of | ||||
|             which filters you are actually using, the order should be as follows: <orderedlist> | ||||
|             <listitem> | ||||
|                 <para><classname>ChannelProcessingFilter</classname>, because it might need to | ||||
|                     redirect to a different protocol</para> | ||||
|             </listitem> | ||||
|             <listitem> | ||||
|                 <para><classname>ConcurrentSessionFilter</classname>, because it doesn't use any | ||||
|                     <classname>SecurityContextHolder</classname> functionality but needs to update | ||||
|                     the <interfacename>SessionRegistry</interfacename> to reflect ongoing requests | ||||
|                     from the principal</para> | ||||
|             </listitem> | ||||
|             <listitem> | ||||
|                 <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>CasAuthenticationFilter</classname>, | ||||
|                     <classname>BasicAuthenticationFilter</classname> etc - so that the | ||||
|                     <classname>SecurityContextHolder</classname> can be modified to contain a valid | ||||
|               <interfacename>Authentication</interfacename> request | ||||
|             token</para></listitem><listitem><para>The | ||||
|               <literal>SecurityContextHolderAwareRequestFilter</literal>, if you are using it to | ||||
|             install a Spring Security aware <literal>HttpServletRequestWrapper</literal> into your | ||||
|             servlet | ||||
|               container</para></listitem><listitem><para><classname>RememberMeAuthenticationFilter</classname>, | ||||
|             so that if no earlier authentication processing mechanism updated the | ||||
|               <classname>SecurityContextHolder</classname>, and the request presents a cookie 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 | ||||
|                     <interfacename>Authentication</interfacename> request token</para> | ||||
|             </listitem> | ||||
|             <listitem> | ||||
|                 <para>The <literal>SecurityContextHolderAwareRequestFilter</literal>, if you are | ||||
|                     using it to install a Spring Security aware | ||||
|                     <literal>HttpServletRequestWrapper</literal> into your servlet container</para> | ||||
|             </listitem> | ||||
|             <listitem> | ||||
|                 <para><classname>RememberMeAuthenticationFilter</classname>, so that if no earlier | ||||
|                     authentication processing mechanism updated the | ||||
|                     <classname>SecurityContextHolder</classname>, and the request presents a cookie | ||||
|                     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 | ||||
|               <interfacename>Authentication</interfacename> object will be put | ||||
|           there</para></listitem><listitem><para><classname>ExceptionTranslationFilter</classname>, | ||||
|             to catch any Spring Security exceptions so that either an HTTP error response can be | ||||
|             returned or an appropriate <interfacename>AuthenticationEntryPoint</interfacename> can | ||||
|             be | ||||
|               launched</para></listitem><listitem><para><classname>FilterSecurityInterceptor</classname>, | ||||
|             to protect web URIs and raise exceptions when access is | ||||
|         denied</para></listitem></orderedlist></para> | ||||
|                     <interfacename>Authentication</interfacename> object will be put there</para> | ||||
|             </listitem> | ||||
|             <listitem> | ||||
|                 <para><classname>ExceptionTranslationFilter</classname>, to catch any Spring | ||||
|                     Security exceptions so that either an HTTP error response can be returned or an | ||||
|                     appropriate <interfacename>AuthenticationEntryPoint</interfacename> can be | ||||
|                     launched</para> | ||||
|             </listitem> | ||||
|             <listitem> | ||||
|                 <para><classname>FilterSecurityInterceptor</classname>, to protect web URIs and | ||||
|                     raise exceptions when access is denied</para> | ||||
|             </listitem> | ||||
|             </orderedlist></para> | ||||
|     </section> | ||||
|     <section> | ||||
|         <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 | ||||
|       that the Spring Security filters come first. This enables the | ||||
|         <classname>SecurityContextHolder</classname> to be populated in time for use by the other | ||||
|       filters. Examples are the use of SiteMesh to decorate your web pages or a web framework like | ||||
|       Wicket which uses a filter to handle its requests. </para> | ||||
|         <para>If you're using some other framework that is also filter-based, then you need to 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 filters. Examples are the use of SiteMesh to decorate your web pages or a web | ||||
|             framework like Wicket which uses a filter to handle its requests. </para> | ||||
|     </section> | ||||
|     <!-- | ||||
|   <section xml:id="taglib"> | ||||
|  |  | |||
|  | @ -6,38 +6,41 @@ | |||
|     <para>HTTP session related functonality is handled by a combination of the | ||||
|         <classname>SessionManagementFilter</classname> and the | ||||
|         <interfacename>SessionAuthenticationStrategy</interfacename> interface, which the filter | ||||
|     delegates to. Typical usage includes session-fixation protection attack prevention, detection of | ||||
|     session timeouts and restrictions on how many sessions an authenticated user may have open | ||||
|     concurrently.</para> | ||||
|         delegates to. Typical usage includes session-fixation protection attack prevention, | ||||
|         detection of session timeouts and restrictions on how many sessions an authenticated user | ||||
|         may have open concurrently.</para> | ||||
|     <section> | ||||
|         <title>SessionManagementFilter</title> | ||||
|         <para>The <classname>SessionManagementFilter</classname> checks the contents of the | ||||
|         <interfacename>SecurityContextRepository</interfacename> against the current contents of the | ||||
|         <classname>SecurityContextHolder</classname> to determine whether a user has been | ||||
|             <interfacename>SecurityContextRepository</interfacename> against the current contents of | ||||
|             the <classname>SecurityContextHolder</classname> to determine whether a user has been | ||||
|             authenticated during the current request, typically by a non-interactive authentication | ||||
|       mechanism, such as pre-authentication or remember-me <footnote><para>Authentication by | ||||
|           mechanisms which perform a redirect after authenticating (such as form-login) will not be | ||||
|           detected by <classname>SessionManagementFilter</classname>, as the filter will not be | ||||
|           invoked during the authenticating request. Session-management functionality has to be | ||||
|           handled separately in these cases. </para></footnote>. If the repository contains a | ||||
|       security context, the filter does nothing. If it doesn't, and the thread-local | ||||
|         <interfacename>SecurityContext</interfacename> contains 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 | ||||
|             mechanism, such as pre-authentication or remember-me <footnote> | ||||
|             <para>Authentication by mechanisms which perform a redirect after authenticating (such | ||||
|                 as form-login) will not be detected by | ||||
|                 <classname>SessionManagementFilter</classname>, as the filter will not be invoked | ||||
|                 during the authenticating request. Session-management functionality has to be | ||||
|                 handled separately in these cases. </para> | ||||
|             </footnote>. If the repository contains a security context, the filter does nothing. If | ||||
|             it doesn't, and the thread-local <interfacename>SecurityContext</interfacename> contains | ||||
|             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> | ||||
|         <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 | ||||
|       configured <literal>invalidSessionUrl</literal> if set. The easiest way to configure this is | ||||
|       through the namespace, <link xlink:href="#ns-session-mgmt">as described earlier</link>.</para> | ||||
|             session ID has been requested (because of a timeout, for example) and will redirect to | ||||
|             the configured <literal>invalidSessionUrl</literal> if set. The easiest way to configure | ||||
|             this is through the namespace, <link xlink:href="#ns-session-mgmt">as described | ||||
|             earlier</link>.</para> | ||||
|     </section> | ||||
|     <section> | ||||
|         <title><interfacename>SessionAuthenticationStrategy</interfacename></title> | ||||
|     <para> | ||||
|       <interfacename>SessionAuthenticationStrategy</interfacename> is used by both | ||||
|         <para> <interfacename>SessionAuthenticationStrategy</interfacename> is used by both | ||||
|             <classname>SessionManagementFilter</classname> and | ||||
|             <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 | ||||
|       this case, a typical configuration, combining the namespace and custom beans might look like this:<programlisting><![CDATA[ | ||||
|             customized form-login class, for example, you will need to inject it into both of these. | ||||
|             In this case, a typical configuration, combining the namespace and custom beans might | ||||
|             look like this:<programlisting><![CDATA[ | ||||
| <http> | ||||
|   <custom-filter position="FORM_LOGIN_FILTER" ref="myAuthFilter" /> | ||||
|   <session-management session-authentication-strategy-ref="sas"/> | ||||
|  | @ -60,27 +63,31 @@ | |||
|     <section xml:id="concurrent-sessions"> | ||||
|         <title>Concurrency Control</title> | ||||
|         <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 | ||||
|       enforce licensing, whilst network administrators like this feature because it helps prevent | ||||
|       people from sharing login names. You can, for example, stop user <quote>Batman</quote> from | ||||
|       logging onto the web application from two different sessions. You can either expire their | ||||
|       previous login or you can report an error when they try to log in again, preventing the second | ||||
|       login. Note that if you are using the second approach, a user who has not explicitly logged | ||||
|       out (but who has just closed their browser, for example) will not be able to log in again | ||||
|       until their original session expires.</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> | ||||
|             same application more than a specified number of times. Many ISVs take advantage of this | ||||
|             to enforce licensing, whilst network administrators like this feature because it helps | ||||
|             prevent people from sharing login names. You can, for example, stop user | ||||
|             <quote>Batman</quote> from logging onto the web application from two different sessions. | ||||
|             You can either expire their previous login or you can report an error when they try to | ||||
|             log in again, preventing the second login. Note that if you are using the second | ||||
|             approach, a user who has not explicitly logged out (but who has just closed their | ||||
|             browser, for example) will not be able to log in again until their original session | ||||
|             expires.</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 | ||||
|             <interfacename>SessionAuthenticationStrategy</interfacename>, called | ||||
|         <classname>ConcurrentSessionControlStrategy</classname>. <note><para>Previously the | ||||
|           concurrent authentication check was made by the <classname>ProviderManager</classname>, | ||||
|           which could be injected with a <literal>ConcurrentSessionController</literal>. The latter | ||||
|           would check if the user was attempting to exceed the number of permitted sessions. | ||||
|           However, this approach required that an HTTP session be created in advance, which is | ||||
|           undesirable. In Spring Security 3, the user is first authenticated by the | ||||
|             <classname>ConcurrentSessionControlStrategy</classname>. <note> | ||||
|             <para>Previously the concurrent authentication check was made by the | ||||
|                 <classname>ProviderManager</classname>, which could be injected with a | ||||
|                 <literal>ConcurrentSessionController</literal>. The latter would check if the user | ||||
|                 was attempting to exceed the number of permitted sessions. However, this approach | ||||
|                 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 | ||||
|           authenticated, a session is created and the check is made whether they are allowed to have | ||||
|           another session open.</para></note></para> | ||||
|                 authenticated, a session is created and the check is made whether they are allowed | ||||
|                 to have another session open.</para> | ||||
|             </note></para> | ||||
|         <para>To use concurrent session support, you'll need to add the following to | ||||
|             <literal>web.xml</literal>: <programlisting><![CDATA[ | ||||
|   <listener> | ||||
|  | @ -89,13 +96,14 @@ | |||
|     </listener-class> | ||||
|   </listener> ]]> | ||||
|         </programlisting></para> | ||||
|     <para>In addition, you will need to add the <literal>ConcurrentSessionFilter</literal> to your | ||||
|         <classname>FilterChainProxy</classname>. The <classname>ConcurrentSessionFilter</classname> | ||||
|       requires two properties, <literal>sessionRegistry</literal>, which generally points to an | ||||
|       instance of <classname>SessionRegistryImpl</classname>, and <literal>expiredUrl</literal>, which | ||||
|       points to the page to display when a session has expired. A configuration using the namespace | ||||
|       to create the <classname>FilterChainProxy</classname> and other default beans might look like | ||||
|       this: <programlisting><![CDATA[ | ||||
|         <para>In addition, you will need to add the <literal>ConcurrentSessionFilter</literal> to | ||||
|             your <classname>FilterChainProxy</classname>. The | ||||
|             <classname>ConcurrentSessionFilter</classname> requires two properties, | ||||
|             <literal>sessionRegistry</literal>, which generally points to an instance of | ||||
|             <classname>SessionRegistryImpl</classname>, and <literal>expiredUrl</literal>, which | ||||
|             points to the page to display when a session has expired. A configuration using the | ||||
|             namespace to create the <classname>FilterChainProxy</classname> and other default beans | ||||
|             might look like this: <programlisting><![CDATA[ | ||||
| <http> | ||||
|   <custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter" /> | ||||
|   <custom-filter position="FORM_LOGIN_FILTER" ref="myAuthFilter" /> | ||||
|  | @ -127,10 +135,10 @@ | |||
|     </programlisting></para> | ||||
|         <para>Adding the listener to <filename>web.xml</filename> causes an | ||||
|             <literal>ApplicationEvent</literal> to be published to the Spring | ||||
|         <literal>ApplicationContext</literal> every time a <literal>HttpSession</literal> commences | ||||
|       or terminates. This is critical, as it allows the <classname>SessionRegistryImpl</classname> | ||||
|       to be notified when a session ends. Without it, a user will never be able to log back in again | ||||
|       once they have exceeded their session allowance, even if they log out of another session or it | ||||
|       times out.</para> | ||||
|             <literal>ApplicationContext</literal> every time a <literal>HttpSession</literal> | ||||
|             commences or terminates. This is critical, as it allows the | ||||
|             <classname>SessionRegistryImpl</classname> to be notified when a session ends. Without | ||||
|             it, a user will never be able to log back in again once they have exceeded their session | ||||
|             allowance, even if they log out of another session or it times out.</para> | ||||
|     </section> | ||||
| </chapter> | ||||
|  |  | |||
|  | @ -1,7 +1,10 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <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"> | ||||
|   <info><title>Spring Security</title><subtitle>Reference Documentation</subtitle><authorgroup> | ||||
|     <info> | ||||
|         <title>Spring Security</title> | ||||
|         <subtitle>Reference Documentation</subtitle> | ||||
|         <authorgroup> | ||||
|             <author> | ||||
|                 <personname>Ben Alex</personname> | ||||
|             </author> | ||||
|  | @ -16,72 +19,78 @@ | |||
|     <preface xml:id="preface"> | ||||
|         <title>Preface</title> | ||||
|         <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 | ||||
|       have tried to provide you a useful and highly configurable security system.</para> | ||||
|             software applications. As you will discover as you venture through this reference guide, | ||||
|             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, | ||||
|       system-wide approach. In security circles we encourage you to adopt "layers of security", so | ||||
|       that each layer tries to be as secure as possible in its own right, with successive layers | ||||
|       providing additional security. The "tighter" the security of each layer, the more robust and | ||||
|       safe your application will be. At the bottom level you'll need to deal with issues such as | ||||
|       transport security and system identification, in order to mitigate man-in-the-middle attacks. | ||||
|       Next you'll generally utilise firewalls, perhaps with VPNs or IP security to ensure only | ||||
|       authorised systems can attempt to connect. In corporate environments you may deploy a DMZ to | ||||
|       separate public-facing servers from backend database and application servers. Your operating | ||||
|       system will also play a critical part, addressing issues such as running processes as | ||||
|       non-privileged users and maximising file system security. An operating system will usually | ||||
|       also be configured with its own firewall. Hopefully somewhere along the way you'll be trying | ||||
|       to prevent denial of service and brute force attacks against the system. An intrusion | ||||
|       detection system will also be especially useful for monitoring and responding to attacks, with | ||||
|       such systems able to take protective action such as blocking offending TCP/IP addresses in | ||||
|       real-time. Moving to the higher layers, your Java Virtual Machine will hopefully be configured | ||||
|       to minimize the permissions granted to different Java types, and then your application will | ||||
|       add its own problem domain-specific security configuration. Spring Security makes this latter | ||||
|       area - application security - much easier. </para> | ||||
|     <para>Of course, you will need to properly address all security layers mentioned above, together | ||||
|       with managerial factors that encompass every layer. A non-exhaustive list of such managerial | ||||
|       factors would include security bulletin monitoring, patching, personnel vetting, audits, | ||||
|       change control, engineering management systems, data backup, disaster recovery, performance | ||||
|       benchmarking, load monitoring, centralised logging, incident response procedures etc.</para> | ||||
|     <para>With Spring Security being focused on helping you with the enterprise application security | ||||
|       layer, you will find that there are as many different requirements as there are business | ||||
|       problem domains. A banking application has different needs from an ecommerce application. An | ||||
|       ecommerce application has different needs from a corporate sales force automation tool. These | ||||
|       custom requirements make application security interesting, challenging and rewarding. </para> | ||||
|     <para>Please read <xref linkend="getting-started"/>, in its entirety to begin with. This will | ||||
|       introduce you to the framework and the namespace-based configuration system with which you can | ||||
|       get up and running quite quickly. To get more of an understanding of how Spring Security | ||||
|       works, and some of the classes you might need to use, you should then read <xref | ||||
|         linkend="overall-architecture"/>. The remaining parts of this guide are structured in a more | ||||
|       traditional reference style, designed to be read on an as-required basis. We'd also recommend | ||||
|       that you read up as much as possible on application security issues in general. Spring | ||||
|       Security is not a panacea which will solve all security issues. It is important that the | ||||
|       application is designed with security in mind from the start. Attempting to retrofit it is not | ||||
|       a good idea. In particular, if you are building a web application, you should be aware of the | ||||
|       many potential vulnerabilities such as cross-site scripting, request-forgery and | ||||
|       session-hijacking which you should be taking into account from the start. The OWASP web site | ||||
|       (http://www.owasp.org/) maintains a top ten list of web application vulnerabilities as well as | ||||
|       a lot of useful reference 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> | ||||
|             system-wide approach. In security circles we encourage you to adopt "layers of | ||||
|             security", so that each layer tries to be as secure as possible in its own right, with | ||||
|             successive layers providing additional security. The "tighter" the security of each | ||||
|             layer, the more robust and safe your application will be. At the bottom level you'll | ||||
|             need to deal with issues such as transport security and system identification, in order | ||||
|             to mitigate man-in-the-middle attacks. Next you'll generally utilise firewalls, perhaps | ||||
|             with VPNs or IP security to ensure only authorised systems can attempt to connect. In | ||||
|             corporate environments you may deploy a DMZ to separate public-facing servers from | ||||
|             backend database and application servers. Your operating system will also play a | ||||
|             critical part, addressing issues such as running processes as non-privileged users and | ||||
|             maximising file system security. An operating system will usually also be configured | ||||
|             with its own firewall. Hopefully somewhere along the way you'll be trying to prevent | ||||
|             denial of service and brute force attacks against the system. An intrusion detection | ||||
|             system will also be especially useful for monitoring and responding to attacks, with | ||||
|             such systems able to take protective action such as blocking offending TCP/IP addresses | ||||
|             in real-time. Moving to the higher layers, your Java Virtual Machine will hopefully be | ||||
|             configured to minimize the permissions granted to different Java types, and then your | ||||
|             application will add its own problem domain-specific security configuration. Spring | ||||
|             Security makes this latter area - application security - much easier. </para> | ||||
|         <para>Of course, you will need to properly address all security layers mentioned above, | ||||
|             together with managerial factors that encompass every layer. A non-exhaustive list of | ||||
|             such managerial factors would include security bulletin monitoring, patching, personnel | ||||
|             vetting, audits, change control, engineering management systems, data backup, disaster | ||||
|             recovery, performance benchmarking, load monitoring, centralised logging, incident | ||||
|             response procedures etc.</para> | ||||
|         <para>With Spring Security being focused on helping you with the enterprise application | ||||
|             security layer, you will find that there are as many different requirements as there are | ||||
|             business problem domains. A banking application has different needs from an ecommerce | ||||
|             application. An ecommerce application has different needs from a corporate sales force | ||||
|             automation tool. These custom requirements make application security interesting, | ||||
|             challenging and rewarding. </para> | ||||
|         <para>Please read <xref linkend="getting-started"/>, in its entirety to begin with. This | ||||
|             will introduce you to the framework and the namespace-based configuration system with | ||||
|             which you can get up and running quite quickly. To get more of an understanding of how | ||||
|             Spring Security works, and some of the classes you might need to use, you should then | ||||
|             read <xref linkend="overall-architecture"/>. The remaining parts of this guide are | ||||
|             structured in a more traditional reference style, designed to be read on an as-required | ||||
|             basis. We'd also recommend that you read up as much as possible on application security | ||||
|             issues in general. Spring Security is not a panacea which will solve all security | ||||
|             issues. It is important that the application is designed with security in mind from the | ||||
|             start. Attempting to retrofit it is not a good idea. In particular, if you are building | ||||
|             a web application, you should be aware of the many potential vulnerabilities such as | ||||
|             cross-site scripting, request-forgery and session-hijacking which you should be taking | ||||
|             into account from the start. The OWASP web site (http://www.owasp.org/) maintains a top | ||||
|             ten list of web application vulnerabilities as well as a lot of useful reference | ||||
|             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> | ||||
|     <part xml:id="getting-started"> | ||||
|         <title>Getting Started</title> | ||||
|         <partintro> | ||||
|             <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 | ||||
|         serious customization. In this part, we'll introduce Spring Security 3.0, give a brief | ||||
|         overview of the project's history and take a slightly gentler look at how to get started | ||||
|         using the framework. In particular, we'll look at namespace configuration which provides a | ||||
|         much simpler way of securing your application compared to the traditional Spring bean | ||||
|         approach where you have to wire up all the implementation classes individually. </para> | ||||
|       <para> We'll also take a look at the sample applications that are available. It's worth trying | ||||
|         to run these and experimenting with them a bit even before you read the later sections - you | ||||
|         can dip back into them as your understanding of the framework increases. Please also check | ||||
|         out the <link 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> | ||||
|                 architecture and implementation classes, which you need to understand if you want to | ||||
|                 do any serious customization. In this part, we'll introduce Spring Security 3.0, | ||||
|                 give a brief overview of the project's history and take a slightly gentler look at | ||||
|                 how to get started using the framework. In particular, we'll look at namespace | ||||
|                 configuration which provides a much simpler way of securing your application | ||||
|                 compared to the traditional Spring bean approach where you have to wire up all the | ||||
|                 implementation classes individually. </para> | ||||
|             <para> We'll also take a look at the sample applications that are available. It's worth | ||||
|                 trying to run these and experimenting with them a bit even before you read the later | ||||
|                 sections - you can dip back into them as your understanding of the framework | ||||
|                 increases. Please also check out the <link | ||||
|                     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> | ||||
|         <xi:include href="introduction.xml"/> | ||||
|         <xi:include href="namespace-config.xml"/> | ||||
|  | @ -91,13 +100,13 @@ | |||
|     <part xml:id="overall-architecture"> | ||||
|         <title>Architecture and Implementation</title> | ||||
|         <partintro> | ||||
|       <para>Once you are familiar with setting up and running some namespace-configuration based | ||||
|         applications, you may wish to develop more of an understanding of how the framework actually | ||||
|         works behind the namespace facade. Like most software, Spring Security has certain central | ||||
|         interfaces, classes and conceptual abstractions that are commonly used throughout the | ||||
|         framework. In this part of the reference guide we will look at some of these and see how | ||||
|         they work together to support authentication and access-control within Spring | ||||
|         Security.</para> | ||||
|             <para>Once you are familiar with setting up and running some namespace-configuration | ||||
|                 based applications, you may wish to develop more of an understanding of how the | ||||
|                 framework actually works behind the namespace facade. Like most software, Spring | ||||
|                 Security has certain central interfaces, classes and conceptual abstractions that | ||||
|                 are commonly used throughout the framework. In this part of the reference guide we | ||||
|                 will look at some of these and see how they work together to support authentication | ||||
|                 and access-control within Spring Security.</para> | ||||
|         </partintro> | ||||
|         <xi:include href="technical-overview.xml"/> | ||||
|         <xi:include href="core-services.xml"/> | ||||
|  | @ -105,13 +114,14 @@ | |||
|     <part xml:id="web-app-security"> | ||||
|         <title>Web Application Security</title> | ||||
|         <partintro> | ||||
|       <para> Most Spring Security users will be using the framework in applications which make user | ||||
|         of HTTP and the Servlet API. In this part, we'll take a look at how Spring Security provides | ||||
|         authentication and access-control features for the web layer of an application. We'll look | ||||
|         behind the facade of the namespace and see which classes and interfaces are actually | ||||
|         assembled to provide web-layer security. In some situations it is necessary to use | ||||
|         traditional bean configuration to provide full control over the configuration, so we'll also | ||||
|         see how to configure these classes directly without the namespace.</para> | ||||
|             <para> Most Spring Security users will be using the framework in applications which make | ||||
|                 user of HTTP and the Servlet API. In this part, we'll take a look at how Spring | ||||
|                 Security provides authentication and access-control features for the web layer of an | ||||
|                 application. We'll look behind the facade of the namespace and see which classes and | ||||
|                 interfaces are actually assembled to provide web-layer security. In some situations | ||||
|                 it is necessary to use traditional bean configuration to provide full control over | ||||
|                 the configuration, so we'll also see how to configure these classes directly without | ||||
|                 the namespace.</para> | ||||
|         </partintro> | ||||
|         <xi:include href="security-filter-chain.xml"/> | ||||
|         <xi:include href="core-filters.xml"/> | ||||
|  | @ -148,16 +158,16 @@ | |||
|     <part xml:id="authorization"> | ||||
|         <title>Authorization</title> | ||||
|         <partintro> | ||||
|       <para>The advanced authorization capabilities within Spring Security represent one of the most | ||||
|         compelling reasons for its popularity. Irrespective of how you choose to authenticate - | ||||
|         whether using a Spring Security-provided mechanism and provider, or integrating with a | ||||
|         container or other non-Spring Security authentication authority - you will find the | ||||
|         authorization services can be used within your application in a consistent and simple | ||||
|         way.</para> | ||||
|             <para>The advanced authorization capabilities within Spring Security represent one of | ||||
|                 the most compelling reasons for its popularity. Irrespective of how you choose to | ||||
|                 authenticate - whether using a Spring Security-provided mechanism and provider, or | ||||
|                 integrating with a container or other non-Spring Security authentication authority - | ||||
|                 you will find the authorization services can be used within your application in a | ||||
|                 consistent and simple way.</para> | ||||
|             <para>In this part we'll explore the different | ||||
|           <classname>AbstractSecurityInterceptor</classname> implementations, which were introduced | ||||
|         in Part I. We then move on to explore how to fine-tune authorization through use of domain | ||||
|         access control lists.</para> | ||||
|                     <classname>AbstractSecurityInterceptor</classname> implementations, which were | ||||
|                 introduced in Part I. We then move on to explore how to fine-tune authorization | ||||
|                 through use of domain access control lists.</para> | ||||
|         </partintro> | ||||
|         <xi:include href="authorization-common.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 | ||||
|     --> | ||||
|         <partintro> | ||||
|       <para> In this part we cover features which require a knowledge of previous chapters  as well | ||||
|         as some of the more advanced and less-commonly used features of the framework.</para> | ||||
|             <para> In this part we cover features which require a knowledge of previous chapters as | ||||
|                 well as some of the more advanced and less-commonly used features of the | ||||
|                 framework.</para> | ||||
|         </partintro> | ||||
|         <xi:include href="domain-acls.xml"/> | ||||
|         <xi:include href="preauth.xml"/> | ||||
|  |  | |||
|  | @ -17,12 +17,12 @@ | |||
|             <para>The legacy options from Spring Security 2.0 are also supported, but | ||||
|                 discouraged.</para> | ||||
|             </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. | ||||
|             The expression evaluation will be delegated to the | ||||
|                 <interfacename>WebSecurityExpressionHandler</interfacename> defined in the | ||||
|             application context (you should have web expressions enabled in your | ||||
|                 <literal><http></literal> namespace configuration to make sure this service is | ||||
|             available). So, for example, you might | ||||
|             expression</link>, specified in the <literal>access</literal> attribute of the tag. The | ||||
|             expression evaluation will be delegated to the | ||||
|             <interfacename>WebSecurityExpressionHandler</interfacename> defined in the application | ||||
|             context (you should have web expressions enabled in your <literal><http></literal> | ||||
|             namespace configuration to make sure this service is available). So, for example, you | ||||
|             might | ||||
|             have<programlisting><sec:authorize access="hasRole('supervisor')"> | ||||
| 
 | ||||
| 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 | ||||
|             <interfacename>Authentication</interfacename> is an instance of Spring Security's | ||||
|             <interfacename>UserDetails</interfacename> object, then using | ||||
|                 <literal><sec:authentication property="principal.username" /></literal> will | ||||
|             render the name of the current user.</para> | ||||
|             <literal><sec:authentication property="principal.username" /></literal> will render | ||||
|             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 | ||||
|             prefer to keep as little logic as possible in the view. You can access the | ||||
|                 <interfacename>Authentication</interfacename> object in your MVC controller (by | ||||
|             calling <code>SecurityContextHolder.getContext().getAuthentication()</code>) and add the | ||||
|             data directly to your model for rendering by the view.</para> | ||||
|             <interfacename>Authentication</interfacename> object in your MVC controller (by calling | ||||
|             <code>SecurityContextHolder.getContext().getAuthentication()</code>) and add the data | ||||
|             directly to your model for rendering by the view.</para> | ||||
|     </section> | ||||
|     <section> | ||||
|         <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> | ||||
|         <para>The permissions are passed to the <interfacename>PermissionFactory</interfacename> | ||||
|             defined in the application context, converting them to ACL | ||||
|                 <interfacename>Permission</interfacename> instances, so they may be any format which | ||||
|             is supported by the factory - they don't have to be integers, they could be strings like | ||||
|             <interfacename>Permission</interfacename> instances, so they may be any format which is | ||||
|             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 | ||||
|             <interfacename>PermissionFactory</interfacename> is found, an instance of | ||||
|             <classname>DefaultPermissionFactory</classname> will be used. The | ||||
|                 <interfacename>AclService</interfacename>from the application context will be used | ||||
|             to load the <interfacename>Acl</interfacename> instance for the supplied object. The | ||||
|             <interfacename>AclService</interfacename>from the application context will be used to | ||||
|             load the <interfacename>Acl</interfacename> instance for the supplied object. The | ||||
|             <interfacename>Acl</interfacename> will be invoked with the required permissions to | ||||
|             check if any of them are granted.</para> | ||||
|     </section> | ||||
|  |  | |||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -7,29 +7,32 @@ | |||
|     <section xml:id="filters"> | ||||
|         <title>The Security Filter Chain</title> | ||||
|         <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 | ||||
|       it has no strong links to any particular web technology. It deals in | ||||
|         <classname>HttpServletRequest</classname>s and <classname>HttpServletResponse</classname>s | ||||
|       and doesn't care whether the requests come from a browser, a web service client, an | ||||
|         <classname>HttpInvoker</classname> or an AJAX application. </para> | ||||
|             doesn't use servlets or any other servlet-based frameworks (such as Spring MVC) | ||||
|             internally, so it has no strong links to any particular web technology. It deals in | ||||
|             <classname>HttpServletRequest</classname>s and | ||||
|             <classname>HttpServletResponse</classname>s and doesn't care whether the requests come | ||||
|             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 | ||||
|       particular responsibility and filters are added or removed from the configuration depending on | ||||
|       which services are required. The ordering of the filters is important as there are | ||||
|       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 to define any Spring beans explicitly but here may be times when you want full control | ||||
|       over the security filter 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> | ||||
|             particular responsibility and filters are added or removed from the configuration | ||||
|             depending on which services are required. The ordering of the filters is important as | ||||
|             there are 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 to define any Spring beans | ||||
|             explicitly but here may be times when you want full control over the security filter | ||||
|             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"> | ||||
|             <title><classname>DelegatingFilterProxy</classname></title> | ||||
|             <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 | ||||
|         Security, the filter classes are also Spring beans defined in the application context and | ||||
|         thus able to take advantage of Spring's rich dependency-injection facilities and lifecycle | ||||
|         interfaces. Spring's <classname>DelegatingFilterProxy</classname> provides the link between | ||||
|                 <filename>web.xml</filename>, or they will be ignored by the servlet container. In | ||||
|                 Spring Security, the filter classes are also Spring beans defined in the application | ||||
|                 context and thus able to take advantage of Spring's rich dependency-injection | ||||
|                 facilities and lifecycle interfaces. Spring's | ||||
|                 <classname>DelegatingFilterProxy</classname> provides the link between | ||||
|                 <filename>web.xml</filename> and the application context. </para> | ||||
|       <para>When using <classname>DelegatingFilterProxy</classname>, you will see something like | ||||
|         this in the <filename>web.xml</filename> file: <programlisting><![CDATA[ | ||||
|             <para>When using <classname>DelegatingFilterProxy</classname>, you will see something | ||||
|                 like this in the <filename>web.xml</filename> file: <programlisting><![CDATA[ | ||||
|   <filter> | ||||
|     <filter-name>myFilter</filter-name> | ||||
|     <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> | ||||
|  | @ -40,29 +43,31 @@ | |||
|     <url-pattern>/*</url-pattern> | ||||
|   </filter-mapping>]]> | ||||
|         </programlisting> Notice that the filter is actually a | ||||
|           <literal>DelegatingFilterProxy</literal>, and not the class that will actually implement | ||||
|         the logic of the filter. What <classname>DelegatingFilterProxy</classname> does is delegate | ||||
|         the <interfacename>Filter</interfacename>'s methods through to a bean which is obtained from | ||||
|         the Spring application context. This enables the bean to benefit from the Spring web | ||||
|         application context lifecycle support and configuration flexibility. The bean must implement | ||||
|           <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 | ||||
|                 <literal>DelegatingFilterProxy</literal>, and not the class that will actually | ||||
|                 implement the logic of the filter. What <classname>DelegatingFilterProxy</classname> | ||||
|                 does is delegate the <interfacename>Filter</interfacename>'s methods through to a | ||||
|                 bean which is obtained from the Spring application context. This enables the bean to | ||||
|                 benefit from the Spring web application context lifecycle support and configuration | ||||
|                 flexibility. The bean must implement | ||||
|                 <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> | ||||
|         </section> | ||||
|         <section xml:id="filter-chain-proxy"> | ||||
|             <title><classname>FilterChainProxy</classname></title> | ||||
|       <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 | ||||
|           <classname>DelegatingFilterProxy</classname> entry to <filename>web.xml</filename> for | ||||
|         each filter, making sure that they are ordered correctly. This is a cumbersome approach and | ||||
|         clutters up the <filename>web.xml</filename> file quickly if we have a lot of filters. We | ||||
|         would prefer to just add a single entry to <filename>web.xml</filename> and deal entirely | ||||
|         with the application context file for managing our web security beans. This is where Spring | ||||
|         Secuiryt's <classname>FilterChainProxy</classname> comes in. It is wired using a | ||||
|           <literal>DelegatingFilterProxy</literal>, just like in the example above, but with the | ||||
|           <literal>filter-name</literal> set to the bean name <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[ | ||||
|             <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 | ||||
|                 <classname>DelegatingFilterProxy</classname> entry to <filename>web.xml</filename> | ||||
|                 for each filter, making sure that they are ordered correctly. This is a cumbersome | ||||
|                 approach and clutters up the <filename>web.xml</filename> file quickly if we have a | ||||
|                 lot of filters. We would prefer to just add a single entry to | ||||
|                 <filename>web.xml</filename> and deal entirely with the application context file for | ||||
|                 managing our web security beans. This is where Spring Secuiryt's | ||||
|                 <classname>FilterChainProxy</classname> comes in. It is wired using a | ||||
|                 <literal>DelegatingFilterProxy</literal>, just like in the example above, but with | ||||
|                 the <literal>filter-name</literal> set to the bean name | ||||
|                 <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"> | ||||
|   <sec:filter-chain-map path-type="ant"> | ||||
|      <sec:filter-chain pattern="/webServices/**" filters=" | ||||
|  | @ -78,127 +83,134 @@ | |||
|   </sec:filter-chain-map> | ||||
| </bean> | ||||
| ]]> | ||||
|       </programlisting> The namespace element <literal>filter-chain-map</literal> is | ||||
|         used to set 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 | ||||
|             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 | ||||
|         names specified in the <literal>filters</literal> element. Both regular expressions 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 | ||||
|         current web request and the list of filter beans specified by the <literal>filters</literal> | ||||
|         attribute will be applied to that request. The filters will be invoked in the order they are | ||||
|         defined, so you have complete control over the filter chain which is applied to a particular | ||||
|         URL.</para> | ||||
|       </programlisting> The namespace element <literal>filter-chain-map</literal> is used to set | ||||
|                 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 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 names specified in the <literal>filters</literal> element. Both regular | ||||
|                 expressions 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 current web request and the list of filter beans specified | ||||
|                 by the <literal>filters</literal> attribute will be applied to that request. The | ||||
|                 filters will be invoked in the order they are defined, so you have complete control | ||||
|                 over the filter chain which is applied to a particular URL.</para> | ||||
|             <para>You may have noticed we have declared two | ||||
|                 <classname>SecurityContextPersistenceFilter</classname>s in the filter chain | ||||
|           (<literal>ASC</literal> is short for <literal>allowSessionCreation</literal>, a property | ||||
|         of <classname>SecurityContextPersistenceFilter</classname>). As web services will never | ||||
|         present a <literal>jsessionid</literal> on future requests, creating | ||||
|           <literal>HttpSession</literal>s for such user agents would be wasteful. If you had a | ||||
|         high-volume application which required maximum scalability, we recommend you use the | ||||
|         approach shown above. For smaller applications, using a single | ||||
|                 (<literal>ASC</literal> is short for <literal>allowSessionCreation</literal>, a | ||||
|                 property of <classname>SecurityContextPersistenceFilter</classname>). As web | ||||
|                 services will never present a <literal>jsessionid</literal> on future requests, | ||||
|                 creating <literal>HttpSession</literal>s for such user agents would be wasteful. If | ||||
|                 you had a high-volume application which required maximum scalability, we recommend | ||||
|                 you use the 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 | ||||
|                 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>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="#namespace-auto-config">namespace configuration</link>, we used a | ||||
|                 <literal>DelegatingFilterProxy</literal> with the name | ||||
|           <quote>springSecurityFilterChain</quote>. You should now be able to see that this is the | ||||
|         name of the <classname>FilterChainProxy</classname> which is created by the namespace. </para> | ||||
|                 <quote>springSecurityFilterChain</quote>. You should now be able to see that this is | ||||
|                 the name of the <classname>FilterChainProxy</classname> which is created by the | ||||
|                 namespace. </para> | ||||
|             <section> | ||||
|                 <title>Bypassing the Filter Chain</title> | ||||
|         <para> As with the namespace, you can use the attribute <literal>filters = "none"</literal> | ||||
|           as an alternative to supplying a filter bean list. This will omit the request pattern from | ||||
|           the security filter chain entirely. Note that anything matching this path will then have | ||||
|           no authentication or authorization services applied and will be freely accessible. If you | ||||
|           want to make use of the contents of the <classname>SecurityContext</classname> contents | ||||
|           during a request, then it must have passed through the security filter chain. Otherwise | ||||
|           the <classname>SecurityContextHolder</classname> will not have been populated and the | ||||
|           contents will be null.</para> | ||||
|                 <para> As with the namespace, you can use the attribute <literal>filters = | ||||
|                     "none"</literal> as an alternative to supplying a filter bean list. This will | ||||
|                     omit the request pattern from the security filter chain entirely. Note that | ||||
|                     anything matching this path will then have no authentication or authorization | ||||
|                     services applied and will be freely accessible. If you want to make use of the | ||||
|                     contents of the <classname>SecurityContext</classname> contents during a | ||||
|                     request, then it must have passed through the security filter chain. Otherwise | ||||
|                     the <classname>SecurityContextHolder</classname> will not have been populated | ||||
|                     and the contents will be null.</para> | ||||
|             </section> | ||||
|         </section> | ||||
|         <section> | ||||
|             <title>Filter Ordering</title> | ||||
|       <para>The order that filters are defined in the chain is very important. Irrespective of which | ||||
|         filters you are actually using, the order should be as follows: | ||||
|         <orderedlist> | ||||
|             <para>The order that filters are defined in the chain is very important. Irrespective of | ||||
|                 which filters you are actually using, the order should be as follows: <orderedlist> | ||||
|                 <listitem> | ||||
|             <para><classname>ChannelProcessingFilter</classname>, because it might need to redirect | ||||
|               to a different protocol</para> | ||||
|                     <para><classname>ChannelProcessingFilter</classname>, because it might need to | ||||
|                         redirect to a different protocol</para> | ||||
|                 </listitem> | ||||
|                 <listitem> | ||||
|                     <para><classname>ConcurrentSessionFilter</classname>, because it doesn't use any | ||||
|                 <classname>SecurityContextHolder</classname> functionality but needs to update the | ||||
|                 <interfacename>SessionRegistry</interfacename> to reflect ongoing requests from the | ||||
|               principal</para> | ||||
|                         <classname>SecurityContextHolder</classname> functionality but needs to | ||||
|                         update the <interfacename>SessionRegistry</interfacename> to reflect ongoing | ||||
|                         requests from the principal</para> | ||||
|                 </listitem> | ||||
|                 <listitem> | ||||
|                     <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> | ||||
|                         <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>CasProcessingFilter</classname>, | ||||
|                         <classname>BasicProcessingFilter</classname> etc - so that the | ||||
|                 <classname>SecurityContextHolder</classname> can be modified to contain a valid | ||||
|                 <interfacename>Authentication</interfacename> request token</para> | ||||
|                         <classname>SecurityContextHolder</classname> can be modified to contain a | ||||
|                         valid <interfacename>Authentication</interfacename> request token</para> | ||||
|                 </listitem> | ||||
|                 <listitem> | ||||
|             <para>The <literal>SecurityContextHolderAwareRequestFilter</literal>, if you are using | ||||
|               it to install a Spring Security aware <literal>HttpServletRequestWrapper</literal> | ||||
|               into your servlet container</para> | ||||
|                     <para>The <literal>SecurityContextHolderAwareRequestFilter</literal>, if you are | ||||
|                         using it to install a Spring Security aware | ||||
|                         <literal>HttpServletRequestWrapper</literal> into your servlet | ||||
|                         container</para> | ||||
|                 </listitem> | ||||
|                 <listitem> | ||||
|                     <para><classname>RememberMeProcessingFilter</classname>, so that if no earlier | ||||
|                         authentication processing mechanism updated the | ||||
|                 <classname>SecurityContextHolder</classname>, and the request presents a cookie that | ||||
|               enables remember-me services to take place, a suitable remembered | ||||
|                 <interfacename>Authentication</interfacename> object will be put there</para> | ||||
|                         <classname>SecurityContextHolder</classname>, and the request presents a | ||||
|                         cookie that enables remember-me services to take place, a suitable | ||||
|                         remembered <interfacename>Authentication</interfacename> object will be put | ||||
|                         there</para> | ||||
|                 </listitem> | ||||
|                 <listitem> | ||||
|                     <para><classname>AnonymousProcessingFilter</classname>, so that if no earlier | ||||
|                         authentication processing mechanism updated the | ||||
|                         <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> | ||||
|             <para><classname>ExceptionTranslationFilter</classname>, to catch any Spring Security | ||||
|               exceptions so that either an HTTP error response can be returned or an appropriate | ||||
|                 <interfacename>AuthenticationEntryPoint</interfacename> can be launched</para> | ||||
|                     <para><classname>ExceptionTranslationFilter</classname>, to catch any Spring | ||||
|                         Security exceptions so that either an HTTP error response can be returned or | ||||
|                         an appropriate <interfacename>AuthenticationEntryPoint</interfacename> can | ||||
|                         be launched</para> | ||||
|                 </listitem> | ||||
|                 <listitem> | ||||
|             <para><classname>FilterSecurityInterceptor</classname>, to protect web URIs and raise | ||||
|               exceptions when access is denied</para> | ||||
|                     <para><classname>FilterSecurityInterceptor</classname>, to protect web URIs and | ||||
|                         raise exceptions when access is denied</para> | ||||
|                 </listitem> | ||||
|                 </orderedlist></para> | ||||
|         </section> | ||||
|         <section> | ||||
|             <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 that the Spring Security filters come first. This enables the | ||||
|           <classname>SecurityContextHolder</classname> to be populated in time for use by the other | ||||
|         filters. Examples are the use of SiteMesh to decorate your web pages or a web framework like | ||||
|         Wicket which uses a filter to handle its requests. </para> | ||||
|             <para>If you're using some other framework that is also filter-based, then you need to | ||||
|                 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 filters. Examples are the use of SiteMesh to decorate your web pages or a web | ||||
|                 framework like Wicket which uses a filter to handle its requests. </para> | ||||
|         </section> | ||||
|     </section> | ||||
| <!-- | ||||
|     <!-- | ||||
|   <section xml:id="taglib"> | ||||
|     <info> | ||||
|       <title>Tag Libraries</title> | ||||
|  |  | |||
|  | @ -1,7 +1,12 @@ | |||
| <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 | ||||
|             of a server when using SSL, most commonly when using HTTPS from a browser. The browser | ||||
|  | @ -10,37 +15,46 @@ | |||
|             maintains.</para> | ||||
|         <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 | ||||
|             will authenticate the client by checking that its certificate is signed by an | ||||
|             acceptable authority. If a valid certificate has been provided, it can be obtained | ||||
|             through the servlet API in an application. Spring Security X.509 module extracts the | ||||
|             certificate using a filter. It maps the certificate to an application user and loads that | ||||
|             user's set of granted authorities for use with the standard Spring Security infrastructure.</para> | ||||
|             will authenticate the client by checking that its certificate is signed by an acceptable | ||||
|             authority. If a valid certificate has been provided, it can be obtained through the | ||||
|             servlet API in an application. Spring Security X.509 module extracts the certificate | ||||
|             using a filter. It maps the certificate to an application user and loads that user's set | ||||
|             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 | ||||
|             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 | ||||
|             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 get this working before trying it out with Spring Security</para> | ||||
|             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 | ||||
|             get this working before trying it out with Spring Security</para> | ||||
|     </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> | ||||
|  ... | ||||
|     <x509 subject-principal-regex="CN=(.*?)," user-service-ref="userService"/> | ||||
|  ... | ||||
| </http> | ||||
|             </programlisting> The element has two optional attributes: <itemizedlist> | ||||
|             </programlisting> | ||||
|             The element has two optional attributes: <itemizedlist> | ||||
|             <listitem> | ||||
|                 <para><literal>subject-principal-regex</literal>. The regular expression used to | ||||
|                     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 | ||||
|                     user.</para> | ||||
|                     shown above. This is the username which will be passed to the | ||||
|                     <interfacename>UserDetailsService</interfacename> to load the authorities for | ||||
|                     the user.</para> | ||||
|             </listitem> | ||||
|             <listitem> | ||||
|                 <para><literal>user-service-ref</literal>. This is the bean Id of the | ||||
|                             <interfacename>UserDetailsService</interfacename> to be used with X.509. | ||||
|                         It isn't needed if there is only one defined in your application | ||||
|                     context.</para> | ||||
|                     <interfacename>UserDetailsService</interfacename> to be used with X.509. It | ||||
|                     isn't needed if there is only one defined in your application context.</para> | ||||
|             </listitem> | ||||
|             </itemizedlist> The <literal>subject-principal-regex</literal> should contain a single | ||||
|             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> | ||||
|     </section> | ||||
|     <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 | ||||
|             <filename>samples/certificate</filename> directory in the Spring Security project. | ||||
|             You can use these to enable SSL for testing if you don't want to generate your own. The file | ||||
|             <filename>samples/certificate</filename> directory in the Spring Security project. You | ||||
|             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 | ||||
|             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 | ||||
|             SSL client authentication. | ||||
|         </para> | ||||
|         <para> | ||||
|             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 | ||||
|             for the users from the sample applications. You can install these in your browser to | ||||
|             enable SSL client authentication. </para> | ||||
|         <para> 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 | ||||
|             <programlisting> | ||||
| <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" scheme="https" secure="true" | ||||
|  | @ -77,10 +91,10 @@ | |||
|             truststoreType="JKS" truststorePass="password" | ||||
| /> | ||||
|                 </programlisting> | ||||
|             <parameter>clientAuth</parameter> can also be set to <parameter>want</parameter> if you still | ||||
|             want SSL connections to succeed even if the client doesn't provide a certificate. | ||||
|             <parameter>clientAuth</parameter> can also be set to <parameter>want</parameter> if you | ||||
|             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 | ||||
|             Spring Security unless you use a non-X.509 authentication mechanism, such as form authentication. | ||||
|         </para> | ||||
|             Spring Security unless you use a non-X.509 authentication mechanism, such as form | ||||
|             authentication. </para> | ||||
|     </section> | ||||
| </chapter> | ||||
		Loading…
	
		Reference in New Issue