preauth.xml 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="preauth"
  3. xmlns:xlink="http://www.w3.org/1999/xlink">
  4. <info>
  5. <title>Pre-Authentication Scenarios</title>
  6. </info>
  7. <para> There are situations where you want to use Spring Security for authorization, but the user
  8. has already been reliably authenticated by some external system prior to accessing the
  9. application. We refer to these situations as <quote>pre-authenticated</quote> scenarios.
  10. Examples include X.509, Siteminder and authentication by the J2EE container in which the
  11. application is running. When using pre-authentication, Spring Security has to
  12. <orderedlist>
  13. <listitem>
  14. <para>Identify the user making the request. </para>
  15. </listitem>
  16. <listitem>
  17. <para>Obtain the authorities for the user.</para>
  18. </listitem>
  19. </orderedlist>The details will depend on the external authentication mechanism. A user might be
  20. identified by their certificate information in the case of X.509, or by an HTTP request header
  21. in the case of Siteminder. If relying on container authentication, the user will be identified
  22. by calling the <methodname>getUserPrincipal()</methodname> method on the incoming HTTP request.
  23. In some cases, the external mechanism may supply role/authority information for the user but in
  24. others the authorities must be obtained from a separate source, such as a
  25. <interfacename>UserDetailsService</interfacename>.
  26. </para>
  27. <section>
  28. <title>Pre-Authentication Framework Classes</title>
  29. <para> Because most pre-authentication mechanisms follow the same pattern, Spring
  30. Security has a set of classes which provide an internal framework for implementing
  31. pre-authenticated authentication providers. This removes duplication and allows new
  32. implementations to be added in a structured fashion, without having to write everything from
  33. scratch. You don't need to know about these classes if you want to use something like
  34. <link xlink:href="#x509">X.509 authentication</link>, as it already has a namespace configuration
  35. option which is simpler to use and get started with. If you need to use explicit bean confiuration or
  36. are planning on writing your own implementation then an understanding of how the
  37. provided implementations work will be useful. You will find classes under the
  38. <package>org.springframework.security.web.authentication.preauth</package>. We just provide an outline
  39. here so you should consult the Javadoc and source where appropriate.
  40. </para>
  41. <section>
  42. <title>AbstractPreAuthenticatedProcessingFilter</title>
  43. <para>
  44. This class will check the current contents of the security context and, if empty, it will attempt to extract
  45. user information from the HTTP request and submit it to the <interfacename>AuthenticationManager</interfacename>.
  46. Subclasses override the following methods to obtain this information:
  47. <programlisting language="java">
  48. protected abstract Object getPreAuthenticatedPrincipal(HttpServletRequest request);
  49. protected abstract Object getPreAuthenticatedCredentials(HttpServletRequest request);
  50. </programlisting>
  51. After calling these, the filter will create a <classname>PreAuthenticatedAuthenticationToken</classname>
  52. containing the returned data and submit it for authentication. By <quote>authentication</quote> here, we
  53. really just mean further processing to perhaps load the user's authorities, but the standard Spring Security
  54. authentication architecture is followed.
  55. </para>
  56. </section>
  57. <section>
  58. <title>AbstractPreAuthenticatedAuthenticationDetailsSource</title>
  59. <para>
  60. Like other Spring Security authentication filters, the pre-authentication filter has an
  61. <literal>authenticationDetailsSource</literal> property which by default will create a
  62. <classname>WebAuthenticationDetails</classname> object to store additional information such as
  63. the session-identifier and originating IP address in the <literal>details</literal> property of
  64. the <interfacename>Authentication</interfacename> object.
  65. In cases where user role information can be obtained from the pre-authentication mechanism, the
  66. data is also stored in this property. Subclasses of
  67. <classname>AbstractPreAuthenticatedAuthenticationDetailsSource</classname> use an extended details
  68. object which implements the <interfacename>GrantedAuthoritiesContainer</interfacename> interface, thus enabling the
  69. authentication provider to read the authorities which were externally allocated to the user. We'll look at a concrete
  70. example next.
  71. </para>
  72. <section xml:id="j2ee-preauth-details">
  73. <title>J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource</title>
  74. <para>
  75. If the filter is configured with an <literal>authenticationDetailsSource</literal> which is an instance of this
  76. class, the authority information is obtained by calling the <methodname>isUserInRole(String role)</methodname> method
  77. for each of a pre-determined set of <quote>mappable roles</quote>. The class gets these from a configured
  78. <interfacename>MappableAttributesRetriever</interfacename>. Possible implementations include hard-coding a list in the application
  79. context and reading the role information from the <literal>&lt;security-role&gt;</literal> information in a
  80. <filename>web.xml</filename> file. The pre-authentication sample application uses the latter approach.
  81. </para>
  82. <para>There is an additional stage where the roles (or attributes) are mapped to Spring Security
  83. <interfacename>GrantedAuthority</interfacename> objects using a configured
  84. <interfacename>Attributes2GrantedAuthoritiesMapper</interfacename>. The default will just add the usual <literal>ROLE_</literal>
  85. prefix to the names, but it gives you full control over the behaviour.
  86. </para>
  87. </section>
  88. </section>
  89. <section>
  90. <title>PreAuthenticatedAuthenticationProvider</title>
  91. <para>
  92. The pre-authenticated provider has little more to do than load the <interfacename>UserDetails</interfacename>
  93. object for the user. It does this by delegating to a <interfacename>AuthenticationUserDetailsService</interfacename>.
  94. The latter is similar to the standard <interfacename>UserDetailsService</interfacename> but takes an
  95. <interfacename>Authentication</interfacename> object rather than just user name:
  96. <programlisting language="java">
  97. public interface AuthenticationUserDetailsService {
  98. UserDetails loadUserDetails(Authentication token) throws UsernameNotFoundException;
  99. }
  100. </programlisting>
  101. This interface may have also other uses but with pre-authentication it allows access to the authorities which
  102. were packaged in the <interfacename>Authentication</interfacename> object, as we saw in the previous section.
  103. The <classname>PreAuthenticatedGrantedAuthoritiesUserDetailsService</classname> class does this.
  104. Alternatively, it may delegate to a standard <interfacename>UserDetailsService</interfacename> via the
  105. <classname>UserDetailsByNameServiceWrapper</classname> implementation.
  106. </para>
  107. </section>
  108. <section>
  109. <title>Http403ForbiddenEntryPoint</title>
  110. <para>
  111. The <interfacename>AuthenticationEntryPoint</interfacename> was discussed in the <link xlink:href="#tech-auth-entry-point">technical
  112. overview</link> chapter. Normally it is responsible for kick-starting the authentication process for an unauthenticated user
  113. (when they try to access a protected resource), but in the pre-authenticated case this doesn't apply. You would only
  114. configure the <classname>ExceptionTranslationFilter</classname> with an instance of this class if you aren't
  115. using pre-authentication in combination with other authentication mechanisms.
  116. It will be called if the user is rejected by the <classname>AbstractPreAuthenticatedProcessingFilter</classname>
  117. resulting in a null authentication. It always returns a <literal>403</literal>-forbidden response code if called.
  118. </para>
  119. </section>
  120. </section>
  121. <section>
  122. <title>Concrete Implementations</title>
  123. <para>
  124. X.509 authentication is covered in its <link xlink:href="#x509">own chapter</link>. Here we'll look at some classes
  125. which provide support for other pre-authenticated scenarios.
  126. </para>
  127. <section>
  128. <title>Request-Header Authentication (Siteminder)</title>
  129. <para>
  130. An external authentication system may supply information to the application by setting specific headers on the HTTP request.
  131. A well known example of this is is Siteminder, which passes the username in a header called <literal>SM_USER</literal>.
  132. This mechanism is supported by the class <classname>RequestHeaderPreAuthenticatedProcessingFilter</classname> which
  133. simply extracts the username from the header. It defaults to using the name <literal>SM_USER</literal> as the
  134. header name. See the Javadoc for more details.
  135. </para>
  136. <tip>
  137. <para>Note that when using a system like this, the framework performs no authentication checks at all and
  138. it is <emphasis>extremely</emphasis> important that the external system is configured properly and protects all
  139. access to the application. If an attacker is able to forge the headers in their original request without this being
  140. detected then they could potentially choose any userame they wished.
  141. </para>
  142. </tip>
  143. <section>
  144. <title>Siteminder Example Configuration</title>
  145. <para>
  146. A typical configuration using this filter would look like this:
  147. <programlisting><![CDATA[
  148. <bean id="siteminderFilter" class=
  149. "org.springframework.security.web.authentication.preauth.header.RequestHeaderPreAuthenticatedProcessingFilter">
  150. <security:custom-filter position="PRE_AUTH_FILTER" />
  151. <property name="principalRequestHeader" value="SM_USER"/>
  152. <property name="authenticationManager" ref="authenticationManager" />
  153. </bean>
  154. <bean id="preauthAuthProvider"
  155. class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
  156. <security:custom-authentication-provider />
  157. <property name="preAuthenticatedUserDetailsService">
  158. <bean id="userDetailsServiceWrapper"
  159. class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
  160. <property name="userDetailsService" ref="userDetailsService"/>
  161. </bean>
  162. </property>
  163. </bean>
  164. <security:authentication-manager alias="authenticationManager" />
  165. ]]>
  166. </programlisting>
  167. We've assumed here that the security namespace is being used for configuration (hence the user of the <literal>custom-filter</literal>,
  168. <literal>authentication-manager</literal> and <literal>custom-authentication-provider</literal> elements (you can read more about them
  169. in the <link xlink:href="ns-config">namespace chapter</link>). You would leave these out of a traditional bean configuration.
  170. It's also assumed that you have added a <interfacename>UserDetailsService</interfacename> (called <quote>userDetailsService</quote>)
  171. to your configuration to load the user's roles.
  172. </para>
  173. </section>
  174. </section>
  175. <section>
  176. <title>J2EE Container Authentication</title>
  177. <para>
  178. The class <classname>J2eePreAuthenticatedProcessingFilter</classname> will extract the username from the
  179. <literal>userPrincipal</literal> property of the <interfacename>HttpServletRequest</interfacename>. use of this
  180. filter would usually be combined with the use of J2EE roles as described above in <xref linkend="j2ee-preauth-details"/>.
  181. </para>
  182. <para>
  183. There is a sample application in the codebase which uses this approach, so get hold of the code from subversion and
  184. have a look at the application context file if you are interested. The code is in the <filename>samples/preauth</filename>
  185. directory.
  186. </para>
  187. </section>
  188. </section>
  189. </chapter>