preauth.xml 13 KB

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