web-infrastructure.xml 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. <chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="web-infrastructure"
  2. xmlns:xlink="http://www.w3.org/1999/xlink">
  3. <info>
  4. <title>Web Application Infrastructure</title>
  5. </info>
  6. <section xml:id="filters">
  7. <title>The Security Filter Chain</title>
  8. <para>Spring Security's web infrastructure is based entirely on standard servlet filters. It
  9. doesn't use servlets or any other servlet-based frameworks (such as Spring MVC)
  10. internally, so it has no strong links to any particular web technology. It deals in
  11. <classname>HttpServletRequest</classname>s and
  12. <classname>HttpServletResponse</classname>s and doesn't care whether the requests come
  13. from a browser, a web service client, an <classname>HttpInvoker</classname> or an AJAX
  14. application. </para>
  15. <para> Spring Security maintains a filter chain internally where each of the filters has a
  16. particular responsibility and filters are added or removed from the configuration
  17. depending on which services are required. The ordering of the filters is important as
  18. there are dependencies between them. If you have been using <link
  19. xlink:href="#ns-config">namespace configuration</link>, then the filters are
  20. automatically configured for you and you don't have to define any Spring beans
  21. explicitly but here may be times when you want full control over the security filter
  22. chain, either because you are using features which aren't supported in the namespace, or
  23. you are using your own customized versions of classes.</para>
  24. <section xml:id="delegating-filter-proxy">
  25. <title><classname>DelegatingFilterProxy</classname></title>
  26. <para> When using servlet filters, you obviously need to declare them in your
  27. <filename>web.xml</filename>, or they will be ignored by the servlet container. In
  28. Spring Security, the filter classes are also Spring beans defined in the application
  29. context and thus able to take advantage of Spring's rich dependency-injection
  30. facilities and lifecycle interfaces. Spring's
  31. <classname>DelegatingFilterProxy</classname> provides the link between
  32. <filename>web.xml</filename> and the application context. </para>
  33. <para>When using <classname>DelegatingFilterProxy</classname>, you will see something
  34. like this in the <filename>web.xml</filename> file: <programlisting><![CDATA[
  35. <filter>
  36. <filter-name>myFilter</filter-name>
  37. <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  38. </filter>
  39. <filter-mapping>
  40. <filter-name>myFilter</filter-name>
  41. <url-pattern>/*</url-pattern>
  42. </filter-mapping>]]>
  43. </programlisting> Notice that the filter is actually a
  44. <literal>DelegatingFilterProxy</literal>, and not the class that will actually
  45. implement the logic of the filter. What <classname>DelegatingFilterProxy</classname>
  46. does is delegate the <interfacename>Filter</interfacename>'s methods through to a
  47. bean which is obtained from the Spring application context. This enables the bean to
  48. benefit from the Spring web application context lifecycle support and configuration
  49. flexibility. The bean must implement
  50. <interfacename>javax.servlet.Filter</interfacename> and it must have the same name
  51. as that in the <literal>filter-name</literal> element. Read the Javadoc for
  52. <classname>DelegatingFilterProxy</classname> for more information</para>
  53. </section>
  54. <section xml:id="filter-chain-proxy">
  55. <title><classname>FilterChainProxy</classname></title>
  56. <para> It should now be clear that you can declare each Spring Security filter bean that
  57. you require in your application context file and add a corresponding
  58. <classname>DelegatingFilterProxy</classname> entry to <filename>web.xml</filename>
  59. for each filter, making sure that they are ordered correctly. This is a cumbersome
  60. approach and clutters up the <filename>web.xml</filename> file quickly if we have a
  61. lot of filters. We would prefer to just add a single entry to
  62. <filename>web.xml</filename> and deal entirely with the application context file for
  63. managing our web security beans. This is where Spring Secuiryt's
  64. <classname>FilterChainProxy</classname> comes in. It is wired using a
  65. <literal>DelegatingFilterProxy</literal>, just like in the example above, but with
  66. the <literal>filter-name</literal> set to the bean name
  67. <quote>filterChainProxy</quote>. The filter chain is then declared in the
  68. application context with the same bean name. Here's an example: <programlisting language="xml"><![CDATA[
  69. <bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
  70. <sec:filter-chain-map path-type="ant">
  71. <sec:filter-chain pattern="/webServices/**" filters="
  72. securityContextPersistenceFilterWithASCFalse,
  73. basicProcessingFilter,
  74. exceptionTranslationFilter,
  75. filterSecurityInterceptor" />
  76. <sec:filter-chain pattern="/**" filters="
  77. securityContextPersistenceFilterWithASCTrue,
  78. authenticationProcessingFilter,
  79. exceptionTranslationFilter,
  80. filterSecurityInterceptor" />
  81. </sec:filter-chain-map>
  82. </bean>
  83. ]]>
  84. </programlisting> The namespace element <literal>filter-chain-map</literal> is used to set
  85. up the security filter chain(s) which are required within the application<footnote>
  86. <para>Note that you'll need to include the security namespace in your application
  87. context XML file in order to use this syntax.</para>
  88. </footnote>. It maps a particular URL pattern to a chain of filters built up from
  89. the bean names specified in the <literal>filters</literal> element. Both regular
  90. expressions and Ant Paths are supported, and the most specific URIs appear first. At
  91. runtime the <classname>FilterChainProxy</classname> will locate the first URI
  92. pattern that matches the current web request and the list of filter beans specified
  93. by the <literal>filters</literal> attribute will be applied to that request. The
  94. filters will be invoked in the order they are defined, so you have complete control
  95. over the filter chain which is applied to a particular URL.</para>
  96. <para>You may have noticed we have declared two
  97. <classname>SecurityContextPersistenceFilter</classname>s in the filter chain
  98. (<literal>ASC</literal> is short for <literal>allowSessionCreation</literal>, a
  99. property of <classname>SecurityContextPersistenceFilter</classname>). As web
  100. services will never present a <literal>jsessionid</literal> on future requests,
  101. creating <literal>HttpSession</literal>s for such user agents would be wasteful. If
  102. you had a high-volume application which required maximum scalability, we recommend
  103. you use the approach shown above. For smaller applications, using a single
  104. <classname>SecurityContextPersistenceFilter</classname> (with its default
  105. <literal>allowSessionCreation</literal> as <literal>true</literal>) would likely be
  106. sufficient.</para>
  107. <para>In relation to lifecycle issues, the <classname>FilterChainProxy</classname> will
  108. always delegate <methodname>init(FilterConfig)</methodname> and
  109. <methodname>destroy()</methodname> methods through to the underlaying
  110. <interfacename>Filter</interfacename>s if such methods are called against
  111. <classname>FilterChainProxy</classname> itself. In this case,
  112. <classname>FilterChainProxy</classname> guarantees to only initialize and destroy
  113. each <literal>Filter</literal> bean once, no matter how many times it is declared in
  114. the filter chain(s). You control the overall choice as to whether these methods are
  115. called or not via the <literal>targetFilterLifecycle</literal> initialization
  116. parameter of <literal>DelegatingFilterProxy</literal>. By default this property is
  117. <literal>false</literal> and servlet container lifecycle invocations are not
  118. delegated through <literal>DelegatingFilterProxy</literal>.</para>
  119. <para> When we looked at how to set up web security using <link
  120. xlink:href="#namespace-auto-config">namespace configuration</link>, we used a
  121. <literal>DelegatingFilterProxy</literal> with the name
  122. <quote>springSecurityFilterChain</quote>. You should now be able to see that this is
  123. the name of the <classname>FilterChainProxy</classname> which is created by the
  124. namespace. </para>
  125. <section>
  126. <title>Bypassing the Filter Chain</title>
  127. <para> As with the namespace, you can use the attribute <literal>filters =
  128. "none"</literal> as an alternative to supplying a filter bean list. This will
  129. omit the request pattern from the security filter chain entirely. Note that
  130. anything matching this path will then have no authentication or authorization
  131. services applied and will be freely accessible. If you want to make use of the
  132. contents of the <classname>SecurityContext</classname> contents during a
  133. request, then it must have passed through the security filter chain. Otherwise
  134. the <classname>SecurityContextHolder</classname> will not have been populated
  135. and the contents will be null.</para>
  136. </section>
  137. </section>
  138. <section>
  139. <title>Filter Ordering</title>
  140. <para>The order that filters are defined in the chain is very important. Irrespective of
  141. which filters you are actually using, the order should be as follows: <orderedlist>
  142. <listitem>
  143. <para><classname>ChannelProcessingFilter</classname>, because it might need to
  144. redirect to a different protocol</para>
  145. </listitem>
  146. <listitem>
  147. <para><classname>ConcurrentSessionFilter</classname>, because it doesn't use any
  148. <classname>SecurityContextHolder</classname> functionality but needs to
  149. update the <interfacename>SessionRegistry</interfacename> to reflect ongoing
  150. requests from the principal</para>
  151. </listitem>
  152. <listitem>
  153. <para><classname>SecurityContextPersistenceFilter</classname>, so a
  154. <interfacename>SecurityContext</interfacename> can be set up in the
  155. <classname>SecurityContextHolder</classname> at the beginning of a web
  156. request, and any changes to the
  157. <interfacename>SecurityContext</interfacename> can be copied to the
  158. <literal>HttpSession</literal> when the web request ends (ready for use with
  159. the next web request)</para>
  160. </listitem>
  161. <listitem>
  162. <para>Authentication processing mechanisms -
  163. <classname>UsernamePasswordAuthenticationFilter</classname>,
  164. <classname>CasProcessingFilter</classname>,
  165. <classname>BasicProcessingFilter</classname> etc - so that the
  166. <classname>SecurityContextHolder</classname> can be modified to contain a
  167. valid <interfacename>Authentication</interfacename> request token</para>
  168. </listitem>
  169. <listitem>
  170. <para>The <literal>SecurityContextHolderAwareRequestFilter</literal>, if you are
  171. using it to install a Spring Security aware
  172. <literal>HttpServletRequestWrapper</literal> into your servlet
  173. container</para>
  174. </listitem>
  175. <listitem>
  176. <para><classname>RememberMeProcessingFilter</classname>, so that if no earlier
  177. authentication processing mechanism updated the
  178. <classname>SecurityContextHolder</classname>, and the request presents a
  179. cookie that enables remember-me services to take place, a suitable
  180. remembered <interfacename>Authentication</interfacename> object will be put
  181. there</para>
  182. </listitem>
  183. <listitem>
  184. <para><classname>AnonymousProcessingFilter</classname>, so that if no earlier
  185. authentication processing mechanism updated the
  186. <classname>SecurityContextHolder</classname>, an anonymous
  187. <interfacename>Authentication</interfacename> object will be put
  188. there</para>
  189. </listitem>
  190. <listitem>
  191. <para><classname>ExceptionTranslationFilter</classname>, to catch any Spring
  192. Security exceptions so that either an HTTP error response can be returned or
  193. an appropriate <interfacename>AuthenticationEntryPoint</interfacename> can
  194. be launched</para>
  195. </listitem>
  196. <listitem>
  197. <para><classname>FilterSecurityInterceptor</classname>, to protect web URIs and
  198. raise exceptions when access is denied</para>
  199. </listitem>
  200. </orderedlist></para>
  201. </section>
  202. <section>
  203. <title>Use with other Filter-Based Frameworks</title>
  204. <para>If you're using some other framework that is also filter-based, then you need to
  205. make sure that the Spring Security filters come first. This enables the
  206. <classname>SecurityContextHolder</classname> to be populated in time for use by the
  207. other filters. Examples are the use of SiteMesh to decorate your web pages or a web
  208. framework like Wicket which uses a filter to handle its requests. </para>
  209. </section>
  210. </section>
  211. <!--
  212. <section xml:id="taglib">
  213. <info>
  214. <title>Tag Libraries</title>
  215. </info>
  216. <para>Spring Security comes bundled with several JSP tag libraries which provide a range of
  217. different services.</para>
  218. <section xml:id="taglib-config">
  219. <info>
  220. <title>Configuration</title>
  221. </info>
  222. <para>All taglib classes are included in the core
  223. <literal>spring-security-taglibs-&lt;version>.jar</literal> file, with the
  224. <literal>security.tld</literal> located in the JAR's <literal>META-INF</literal>
  225. directory. This means for JSP 1.2+ web containers you can simply include the JAR in the
  226. WAR's <literal>WEB-INF/lib</literal> directory and it will be available.</para>
  227. </section>
  228. <section xml:id="taglib-usage">
  229. <info>
  230. <title>Usage</title>
  231. </info>
  232. <para>Now that you've configured the tag libraries, refer to the individual reference guide
  233. sections for details on how to use them. Note that when using the tags, you should include
  234. the taglib reference in your JSP:
  235. <programlisting>
  236. &lt;%@ taglib prefix='security' uri='http://www.springframework.org/security/tags' %&gt;
  237. </programlisting></para>
  238. </section>
  239. </section>
  240. <section xml:id="authentication-taglibs">
  241. <info>
  242. <title>Authentication Tag Libraries</title>
  243. </info>
  244. <para><literal>AuthenticationTag</literal> is used to simply output a property of the current
  245. <interfacename>Authentication</interfacename> object to the web page.</para>
  246. <para>The following JSP fragment illustrates how to use the
  247. <literal>AuthenticationTag</literal>:</para>
  248. <para>
  249. <programlisting>&lt;security:authentication property="principal.username"/&gt;</programlisting>
  250. </para>
  251. <para>This tag would cause the principal's name to be output. Here we are assuming the
  252. <literal>Authentication.getPrincipal()</literal> is a
  253. <interfacename>UserDetails</interfacename> object, which is generally the case when using
  254. one of Spring Security's stadard <classname>AuthenticationProvider</classname>
  255. implementations.</para>
  256. </section>
  257. -->
  258. </chapter>