supporting-infrastructure.xml 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. <chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="supporting-infrastructure" xmlns:xlink="http://www.w3.org/1999/xlink">
  2. <info><title>Supporting Infrastructure</title></info>
  3. <para>This chapter introduces some of the supplementary and supporting
  4. infrastructure used by Spring Security. If a capability is not directly
  5. related to security, yet included in the Spring Security project, we
  6. will discuss it in this chapter.</para>
  7. <section xml:id="localization">
  8. <title>Localization</title>
  9. <para>Spring Security supports localization of exception messages that
  10. end users are likely to see. If your application is designed for
  11. English users, you don't need to do anything as by default all
  12. Security Security messages are in English. If you need to support
  13. other locales, everything you need to know is contained in this
  14. section.</para>
  15. <para>All exception messages can be localized, including messages
  16. related to authentication failures and access being denied
  17. (authorization failures). Exceptions and logging that is focused on
  18. developers or system deployers (including incorrect attributes,
  19. interface contract violations, using incorrect constructors, startup
  20. time validation, debug-level logging) etc are not localized and
  21. instead are hard-coded in English within Spring Security's
  22. code.</para>
  23. <para>Shipping in the <literal>spring-security-core-xx.jar</literal> you
  24. will find an <literal>org.springframework.security</literal> package
  25. that in turn contains a <literal>messages.properties</literal> file.
  26. This should be referred to by your
  27. <literal>ApplicationContext</literal>, as Spring Security classes
  28. implement Spring's <literal>MessageSourceAware</literal> interface and
  29. expect the message resolver to be dependency injected at application
  30. context startup time. Usually all you need to do is register a bean
  31. inside your application context to refer to the messages. An example
  32. is shown below:</para>
  33. <para><programlisting><![CDATA[
  34. <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
  35. <property name="basename" value="org/springframework/security/messages"/>
  36. </bean>
  37. ]]></programlisting></para>
  38. <para>The <literal>messages.properties</literal> is named in
  39. accordance with standard resource bundles and represents the default
  40. language supported by Spring Security messages. This default file is
  41. in English. If you do not register a message source, Spring Security
  42. will still work correctly and fallback to hard-coded English versions
  43. of the messages.</para>
  44. <para>If you wish to customize the
  45. <literal>messages.properties</literal> file, or support other
  46. languages, you should copy the file, rename it accordingly, and
  47. register it inside the above bean definition. There are not a large
  48. number of message keys inside this file, so localization should not be
  49. considered a major initiative. If you do perform localization of this
  50. file, please consider sharing your work with the community by logging
  51. a JIRA task and attaching your appropriately-named localized version
  52. of <literal>messages.properties</literal>.</para>
  53. <para>Rounding out the discussion on localization is the Spring
  54. <literal>ThreadLocal</literal> known as
  55. <literal>org.springframework.context.i18n.LocaleContextHolder</literal>.
  56. You should set the <literal>LocaleContextHolder</literal> to represent
  57. the preferred <literal>Locale</literal> of each user. Spring Security
  58. will attempt to locate a message from the message source using the
  59. <literal>Locale</literal> obtained from this
  60. <literal>ThreadLocal</literal>. Please refer to Spring documentation
  61. for further details on using <literal>LocaleContextHolder</literal>
  62. and the helper classes that can automatically set it for you (eg
  63. <literal>AcceptHeaderLocaleResolver</literal>,
  64. <literal>CookieLocaleResolver</literal>,
  65. <literal>FixedLocaleResolver</literal>,
  66. <literal>SessionLocaleResolver</literal> etc)</para>
  67. </section>
  68. <section xml:id="filters">
  69. <info><title>Filters</title></info>
  70. <para>Spring Security uses many filters, as referred to throughout the
  71. remainder of this reference guide. If you are using <link xlink:href="#ns-config">namespace configuration</link>,
  72. then the you don't usually have to declare the filter beans explicitly. There may be times when you want full control
  73. over the security filter chain, either because you are using features which aren't supported in the namespace, or you
  74. are using your own customized versions of classes.</para>
  75. <para>In this case, you have a choice in how these filters are added to your web application, in that you can use either
  76. Spring's <literal>DelegatingFilterProxy</literal> or
  77. <classname>FilterChainProxy</classname>. We'll look at both below.</para>
  78. <para>When using <literal>DelegatingFilterProxy</literal>, you will see
  79. something like this in the web.xml file:
  80. <programlisting>
  81. &lt;filter&gt;
  82. &lt;filter-name&gt;myFilter&lt;/filter-name&gt;
  83. &lt;filter-class&gt;org.springframework.web.filter.DelegatingFilterProxy&lt;/filter-class&gt;
  84. &lt;/filter&gt;
  85. &lt;filter-mapping&gt;
  86. &lt;filter-name&gt;myFilter&lt;/filter-name&gt;
  87. &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
  88. &lt;/filter-mapping&gt;
  89. </programlisting>
  90. Notice that the filter is actually a <literal>DelegatingFilterProxy</literal>,
  91. and not the filter that will actually implement the logic of the filter. What
  92. <literal>DelegatingFilterProxy</literal> does is delegate the
  93. <literal>Filter</literal>'s methods through to a bean which is
  94. obtained from the Spring application context. This enables the bean to
  95. benefit from the Spring web application context lifecycle support and
  96. configuration flexibility. The bean must implement
  97. <literal>javax.servlet.Filter</literal> and it must have the same name as that in
  98. the <literal>filter-name</literal> element.</para>
  99. <para>There is a lifecycle issue to consider when hosting
  100. <literal>Filter</literal>s in an IoC container instead of a servlet
  101. container. Specifically, which container should be responsible for
  102. calling the <literal>Filter</literal>'s "startup" and "shutdown"
  103. methods? It is noted that the order of initialization and destruction
  104. of a <literal>Filter</literal> can vary by servlet container, and this
  105. can cause problems if one <literal>Filter</literal> depends on
  106. configuration settings established by an earlier initialized
  107. <literal>Filter</literal>. The Spring IoC container on the other hand
  108. has more comprehensive lifecycle/IoC interfaces (such as
  109. <literal>InitializingBean</literal>,
  110. <literal>DisposableBean</literal>, <literal>BeanNameAware</literal>,
  111. <literal>ApplicationContextAware</literal> and many others) as well as
  112. a well-understood interface contract, predictable method invocation
  113. ordering, autowiring support, and even options to avoid implementing
  114. Spring interfaces (eg the <literal>destroy-method</literal> attribute
  115. in Spring XML). For this reason we recommend the use of Spring
  116. lifecycle services instead of servlet container lifecycle services
  117. wherever possible. Read the Javadoc for <classname>DelegatingFilterProxy</classname>
  118. for more information</para>
  119. <para>Rather than using <literal>DelegatingFilterProxy</literal>, we
  120. strongly recommend that you use <classname>FilterChainProxy</classname> instead.
  121. Whilst <literal>DelegatingFilterProxy</literal> is a very useful class,
  122. the problem is that the number of lines of code required for
  123. <literal>&lt;filter&gt;</literal> and
  124. <literal>&lt;filter-mapping&gt;</literal> entries in
  125. <literal>web.xml</literal> explodes when using more than a few
  126. filters. To overcome this issue, Spring Security provides a
  127. <classname>FilterChainProxy</classname> class. It is wired using a
  128. <literal>DelegatingFilterProxy</literal> (just like in the example above),
  129. but the target class is
  130. <literal>org.springframework.security.util.FilterChainProxy</literal>.
  131. The filter chain is then declared in the application context, using
  132. code such as this:</para>
  133. <para><programlisting><![CDATA[
  134. <bean id="filterChainProxy" class="org.springframework.security.util.FilterChainProxy">
  135. <sec:filter-chain-map path-type="ant">
  136. <sec:filter-chain pattern="/webServices/**"
  137. filters="httpSessionContextIntegrationFilterWithASCFalse,basicProcessingFilter,exceptionTranslationFilter,filterSecurityInterceptor"/>
  138. <sec:filter-chain pattern="/**"
  139. filters="httpSessionContextIntegrationFilterWithASCTrue,authenticationProcessingFilter,exceptionTranslationFilter,filterSecurityInterceptor"/>
  140. </sec:filter-chain-map>
  141. </bean>
  142. ]]>
  143. </programlisting></para>
  144. <para>You may notice similarities with the way
  145. <classname>FilterSecurityInterceptor</classname> is declared. Both regular
  146. expressions and Ant Paths are supported, and the most specific URIs
  147. appear first. At runtime the <classname>FilterChainProxy</classname> will
  148. locate the first URI pattern that matches the current web request and the list
  149. of filter beans specified by the <literal>filters</literal> attribute
  150. will be applied to that request. The filters will be invoked in the order
  151. they are defined, so you have complete control over the filter chain
  152. which is applied to a particular URL.</para>
  153. <para>You may have noticed we have declared two
  154. <classname>HttpSessionContextIntegrationFilter</classname>s in the filter
  155. chain (<literal>ASC</literal> is short for
  156. <literal>allowSessionCreation</literal>, a property of
  157. <classname>HttpSessionContextIntegrationFilter</classname>). As web
  158. services will never present a <literal>jsessionid</literal> on future
  159. requests, creating <literal>HttpSession</literal>s for such user
  160. agents would be wasteful. If you had a high-volume application which
  161. required maximum scalability, we recommend you use the approach shown
  162. above. For smaller applications, using a single
  163. <classname>HttpSessionContextIntegrationFilter</classname> (with its
  164. default <literal>allowSessionCreation</literal> as
  165. <literal>true</literal>) would likely be sufficient.</para>
  166. <para>In relation to lifecycle issues, the
  167. <classname>FilterChainProxy</classname> will always delegate
  168. <literal>init(FilterConfig)</literal> and <literal>destroy()</literal>
  169. methods through to the underlaying <literal>Filter</literal>s if such
  170. methods are called against <classname>FilterChainProxy</classname> itself.
  171. In this case, <classname>FilterChainProxy</classname> guarantees to only
  172. initialize and destroy each <literal>Filter</literal> once,
  173. irrespective of how many times it is declared by the
  174. <interfacename>FilterInvocationDefinitionSource</interfacename>. You control the
  175. overall choice as to whether these methods are called or not via the
  176. <literal>targetFilterLifecycle</literal> initialization parameter of the
  177. <literal>DelegatingFilterProxy</literal> that proxies
  178. <literal>DelegatingFilterProxy</literal>. As discussed above, by default
  179. any servlet container lifecycle invocations are not delegated through
  180. to <literal>DelegatingFilterProxy</literal>.</para>
  181. <para>You can use the attribute <literal>filters = "none"</literal>
  182. in the same way that you do when using <link xlink:href="#namespace-auto-config">namespace configuration</link>
  183. to build the <classname>FilterChainProxy</classname>. This will omit the
  184. request pattern from the security filter chain entirely.
  185. Note that anything matching this path will then have
  186. no authentication or authorization services applied and will be freely
  187. accessible.</para>
  188. <para>The order that filters are defined in <literal>web.xml</literal>
  189. is very important. Irrespective of which filters you are actually
  190. using, the order of the <literal>&lt;filter-mapping&gt;</literal>s
  191. should be as follows:</para>
  192. <orderedlist inheritnum="ignore" continuation="restarts">
  193. <listitem>
  194. <para><literal>ChannelProcessingFilter</literal>, because it might
  195. need to redirect to a different protocol</para>
  196. </listitem>
  197. <listitem>
  198. <para><literal>ConcurrentSessionFilter</literal>, because it
  199. doesn't use any <classname>SecurityContextHolder</classname>
  200. functionality but needs to update the
  201. <interfacename>SessionRegistry</interfacename> to reflect ongoing requests
  202. from the principal</para>
  203. </listitem>
  204. <listitem>
  205. <para><classname>HttpSessionContextIntegrationFilter</classname>, so a
  206. <interfacename>SecurityContext</interfacename> can be setup in the
  207. <classname>SecurityContextHolder</classname> at the beginning of a web
  208. request, and any changes to the <interfacename>SecurityContext</interfacename>
  209. can be copied to the <literal>HttpSession</literal> when the web
  210. request ends (ready for use with the next web request)</para>
  211. </listitem>
  212. <listitem>
  213. <para>Authentication processing mechanisms -
  214. <literal>AuthenticationProcessingFilter</literal>,
  215. <literal>CasProcessingFilter</literal>,
  216. <literal>BasicProcessingFilter, HttpRequestIntegrationFilter,
  217. JbossIntegrationFilter</literal> etc - so that the
  218. <classname>SecurityContextHolder</classname> can be modified to
  219. contain a valid <interfacename>Authentication</interfacename> request
  220. token</para>
  221. </listitem>
  222. <listitem>
  223. <para>The
  224. <literal>SecurityContextHolderAwareRequestFilter</literal>, if you
  225. are using it to install a Spring Security aware
  226. <literal>HttpServletRequestWrapper</literal> into your servlet
  227. container</para>
  228. </listitem>
  229. <listitem>
  230. <para><classname>RememberMeProcessingFilter</classname>, so that if no
  231. earlier authentication processing mechanism updated the
  232. <classname>SecurityContextHolder</classname>, and the request presents
  233. a cookie that enables remember-me services to take place, a
  234. suitable remembered
  235. <interfacename>Authentication</interfacename> object will
  236. be put there</para>
  237. </listitem>
  238. <listitem>
  239. <para><literal>AnonymousProcessingFilter</literal>, so that if no
  240. earlier authentication processing mechanism updated the
  241. <classname>SecurityContextHolder</classname>, an anonymous
  242. <interfacename>Authentication</interfacename> object will be put there</para>
  243. </listitem>
  244. <listitem>
  245. <para><classname>ExceptionTranslationFilter</classname>, to catch any
  246. Spring Security exceptions so that either an HTTP error response
  247. can be returned or an appropriate
  248. <interfacename>AuthenticationEntryPoint</interfacename> can be launched</para>
  249. </listitem>
  250. <listitem>
  251. <para><classname>FilterSecurityInterceptor</classname>, to protect web
  252. URIs</para>
  253. </listitem>
  254. </orderedlist>
  255. <para>All of the above filters use
  256. <literal>DelegatingFilterProxy</literal> or
  257. <classname>FilterChainProxy</classname>. It is recommended that a single
  258. <literal>DelegatingFilterProxy</literal> proxy through to a single
  259. <classname>FilterChainProxy</classname> for each application, with that
  260. <classname>FilterChainProxy</classname> defining all of Spring Security
  261. filters.</para>
  262. <para>If you're using SiteMesh, ensure Spring Security filters execute
  263. before the SiteMesh filters are called. This enables the
  264. <classname>SecurityContextHolder</classname> to be populated in time for
  265. use by SiteMesh decorators</para>
  266. </section>
  267. <section xml:id="taglib">
  268. <info><title>Tag Libraries</title></info>
  269. <para>Spring Security comes bundled with several JSP tag libraries which provide a range of different
  270. services.</para>
  271. <section xml:id="taglib-config">
  272. <info><title>Configuration</title></info>
  273. <para>All taglib classes are included in the core
  274. <literal>spring-security-xx.jar</literal> file, with the
  275. <literal>security.tld</literal> located in the JAR's
  276. <literal>META-INF</literal> directory. This means for JSP 1.2+ web
  277. containers you can simply include the JAR in the WAR's
  278. <literal>WEB-INF/lib</literal> directory and it will be available. If
  279. you're using a JSP 1.1 container, you'll need to declare the JSP
  280. taglib in your <literal>web.xml file</literal>, and include
  281. <literal>security.tld</literal> in the <literal>WEB-INF/lib</literal>
  282. directory. The following fragment is added to
  283. <literal>web.xml</literal>:
  284. <programlisting><![CDATA[
  285. <taglib>
  286. <taglib-uri>http://www.springframework.org/security/tags</taglib-uri>
  287. <taglib-location>/WEB-INF/security.tld</taglib-location>
  288. </taglib>
  289. ]]></programlisting></para>
  290. </section>
  291. <section xml:id="taglib-usage">
  292. <info><title>Usage</title></info>
  293. <para>Now that you've configured the tag libraries, refer to the
  294. individual reference guide sections for details on how to use them.
  295. Note that when using the tags, you should include the taglib reference
  296. in your JSP:
  297. <programlisting>
  298. &lt;%@ taglib prefix='security' uri='http://www.springframework.org/security/tags' %&gt;
  299. </programlisting></para>
  300. </section>
  301. </section>
  302. </chapter>