preauth.xml 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  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 linkend="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. <para> Like other Spring Security authentication filters, the pre-authentication filter
  55. has an <literal>authenticationDetailsSource</literal> property which by default will
  56. create a <classname>WebAuthenticationDetails</classname> object to store additional
  57. information such as the session-identifier and originating IP address in the
  58. <literal>details</literal> property of the
  59. <interfacename>Authentication</interfacename> object. In cases where user role
  60. information can be obtained from the pre-authentication mechanism, the data is also
  61. stored in this property, with the details implementing the
  62. <interfacename>GrantedAuthoritiesContainer</interfacename> interface. This
  63. enables the authentication provider to read the authorities which were externally
  64. allocated to the user. We'll look at a concrete example next. </para>
  65. <section xml:id="j2ee-preauth-details">
  66. <title>J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource</title>
  67. <para> If the filter is configured with an
  68. <literal>authenticationDetailsSource</literal> which is an instance of this
  69. class, the authority information is obtained by calling the
  70. <methodname>isUserInRole(String role)</methodname> method for each of a
  71. pre-determined set of <quote>mappable roles</quote>. The class gets these from a
  72. configured <interfacename>MappableAttributesRetriever</interfacename>. Possible
  73. implementations include hard-coding a list in the application context and
  74. reading the role information from the <literal>&lt;security-role&gt;</literal>
  75. information in a <filename>web.xml</filename> file. The pre-authentication
  76. sample application uses the latter approach.</para>
  77. <para>There is an additional stage where the roles (or attributes) are mapped to
  78. Spring Security <interfacename>GrantedAuthority</interfacename> objects using a
  79. configured <interfacename>Attributes2GrantedAuthoritiesMapper</interfacename>.
  80. The default will just add the usual <literal>ROLE_</literal> prefix to the
  81. names, but it gives you full control over the behaviour. </para>
  82. </section>
  83. </section>
  84. <section>
  85. <title>PreAuthenticatedAuthenticationProvider</title>
  86. <para> The pre-authenticated provider has little more to do than load the
  87. <interfacename>UserDetails</interfacename> object for the user. It does this by
  88. delegating to a <interfacename>AuthenticationUserDetailsService</interfacename>. The
  89. latter is similar to the standard <interfacename>UserDetailsService</interfacename>
  90. but takes an <interfacename>Authentication</interfacename> object rather than just
  91. user name:
  92. <programlisting language="java">
  93. public interface AuthenticationUserDetailsService {
  94. UserDetails loadUserDetails(Authentication token) throws UsernameNotFoundException;
  95. }
  96. </programlisting>
  97. This interface may have also other uses but with pre-authentication it allows access
  98. to the authorities which were packaged in the
  99. <interfacename>Authentication</interfacename> object, as we saw in the previous
  100. section. The
  101. <classname>PreAuthenticatedGrantedAuthoritiesUserDetailsService</classname> class
  102. does this. Alternatively, it may delegate to a standard
  103. <interfacename>UserDetailsService</interfacename> via the
  104. <classname>UserDetailsByNameServiceWrapper</classname> implementation. </para>
  105. </section>
  106. <section>
  107. <title>Http403ForbiddenEntryPoint</title>
  108. <para> The <interfacename>AuthenticationEntryPoint</interfacename> was discussed in the
  109. <link linkend="tech-intro-auth-entry-point">technical overview</link> chapter.
  110. Normally it is responsible for kick-starting the authentication process for an
  111. unauthenticated user (when they try to access a protected resource), but in the
  112. pre-authenticated case this doesn't apply. You would only configure the
  113. <classname>ExceptionTranslationFilter</classname> with an instance of this class if
  114. you aren't using pre-authentication in combination with other authentication
  115. mechanisms. It will be called if the user is rejected by the
  116. <classname>AbstractPreAuthenticatedProcessingFilter</classname> resulting in a null
  117. authentication. It always returns a <literal>403</literal>-forbidden response code
  118. if called. </para>
  119. </section>
  120. </section>
  121. <section>
  122. <title>Concrete Implementations</title>
  123. <para> X.509 authentication is covered in its <link linkend="x509">own chapter</link>.
  124. Here we'll look at some classes which provide support for other pre-authenticated
  125. scenarios. </para>
  126. <section>
  127. <title>Request-Header Authentication (Siteminder)</title>
  128. <para> An external authentication system may supply information to the application by
  129. setting specific headers on the HTTP request. A well known example of this is
  130. Siteminder, which passes the username in a header called <literal>SM_USER</literal>.
  131. This mechanism is supported by the class
  132. <classname>RequestHeaderAuthenticationFilter</classname> which simply extracts the
  133. username from the header. It defaults to using the name <literal>SM_USER</literal>
  134. as the header name. See the Javadoc for more details. </para>
  135. <tip>
  136. <para>Note that when using a system like this, the framework performs no
  137. authentication checks at all and it is <emphasis>extremely</emphasis> important
  138. that the external system is configured properly and protects all access to the
  139. application. If an attacker is able to forge the headers in their original
  140. request without this being detected then they could potentially choose any
  141. username they wished. </para>
  142. </tip>
  143. <section>
  144. <title>Siteminder Example Configuration</title>
  145. <para> A typical configuration using this filter would look like this: <programlisting language="xml"><![CDATA[
  146. <security:http>
  147. <!-- Additional http configuration omitted -->
  148. <security:custom-filter position="PRE_AUTH_FILTER" ref="siteminderFilter" />
  149. </security:http>
  150. <bean id="siteminderFilter" class=
  151. "org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter">
  152. <property name="principalRequestHeader" value="SM_USER"/>
  153. <property name="authenticationManager" ref="authenticationManager" />
  154. </bean>
  155. <bean id="preauthAuthProvider"
  156. class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
  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. <security:authentication-provider ref="preauthAuthProvider" />
  166. </security:authentication-manager>
  167. ]]>
  168. </programlisting> We've assumed here that the <link linkend="ns-config">security namespace</link>
  169. is being used for configuration. It's also assumed that you have added a
  170. <interfacename>UserDetailsService</interfacename> (called
  171. <quote>userDetailsService</quote>) to your configuration to load the user's
  172. roles. </para>
  173. </section>
  174. </section>
  175. <section>
  176. <title>J2EE Container Authentication</title>
  177. <para> The class <classname>J2eePreAuthenticatedProcessingFilter</classname> will
  178. extract the username from the <literal>userPrincipal</literal> property of the
  179. <interfacename>HttpServletRequest</interfacename>. Use of this filter would usually
  180. be combined with the use of J2EE roles as described above in <xref
  181. linkend="j2ee-preauth-details"/>. </para>
  182. <para> There is a sample application in the codebase which uses this approach, so get
  183. hold of the code from subversion and have a look at the application context file if
  184. you are interested. The code is in the <filename>samples/preauth</filename>
  185. directory. </para>
  186. </section>
  187. </section>
  188. </chapter>