namespace-config.xml 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="ns-config" xmlns:xlink="http://www.w3.org/1999/xlink">
  3. <info>
  4. <title>Security Namespace Configuration</title>
  5. </info>
  6. <section>
  7. <title>Introduction</title>
  8. <para>
  9. Namespace configuration has been available since version 2.0 of the Spring framework. It
  10. allows you to supplement the traditional Spring beans application context syntax with elements
  11. from additional XML schema. You can find more information in the Spring
  12. <link xlink:href="http://static.springframework.org/spring/docs/2.5.x/reference/xsd-config.html">
  13. Reference Documentation</link>. A namespace element can be used simply to allow a more
  14. concise way of configuring an individual bean or, more powerfully, to define an alternative
  15. configuration syntax which more closely matches the problem domain and hides the underlying
  16. complexity from the user. A simple element may conceal the fact that multiple beans and
  17. processing steps are being added to the application context. For example, adding the following
  18. element from the security namespace to an application context will start up an embedded LDAP
  19. server for testing use within the application:
  20. <programlisting><![CDATA[
  21. <security:ldap-server />
  22. ]]></programlisting>
  23. This is much simpler than wiring up the equivalent Apache Directory Server beans. The most
  24. common alternative configuration requirements are supported by attributes on the
  25. <literal>ldap-server</literal>
  26. element and the user is isolated from worrying about which beans they need to be set on and
  27. what the bean property names are.
  28. <footnote>
  29. <para>You can find out more about the use of the
  30. <literal>ldap-server</literal>
  31. element in the chapter on
  32. <link xlink:href="#ldap">LDAP</link>.</para>
  33. </footnote>. Use of a good XML editor while editing the application context file should
  34. provide information on the attributes and elements that are available. We would recommend that
  35. you try out the
  36. <link xlink:href="http://www.springsource.com/products/sts">SpringSource Tool Suite</link>
  37. as it has special features for working with the Spring portfolio namespaces.
  38. </para>
  39. <para>
  40. To start using the security namespace in your application context, all you need to do is add
  41. the schema declaration to your application context file:
  42. <programlisting>
  43. <![CDATA[
  44. <beans xmlns="http://www.springframework.org/schema/beans"
  45. xmlns:security="http://www.springframework.org/schema/security"
  46. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  47. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
  48. http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd">
  49. ...
  50. </beans>
  51. ]]></programlisting>
  52. In many of the examples you will see (and in the sample) applications, we will often use
  53. "security" as the default namespace rather than "beans", which means we can omit the prefix on
  54. all the security namespace elements, making the context easier to read. You may also want to
  55. do this if you have your application context divided up into separate files and have most of
  56. your security configuration in one of them. Your security application context file would then
  57. start like this
  58. <programlisting><![CDATA[
  59. <beans:beans xmlns="http://www.springframework.org/schema/security"
  60. xmlns:beans="http://www.springframework.org/schema/beans"
  61. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  62. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
  63. http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd">
  64. ...
  65. </beans:beans>
  66. ]]></programlisting>
  67. We'll assume this syntax is being used from now on in this chapter.
  68. </para>
  69. <section>
  70. <title>Design of the Namespace</title>
  71. <para>
  72. The namespace is designed to capture the most common uses of the framework and provide a
  73. simplified and concise syntax for enabling them within an application. The design is largely
  74. based around the large-scale dependencies within the framework, and can be divided up into
  75. the following areas:
  76. <itemizedlist>
  77. <listitem>
  78. <para>
  79. <emphasis>Web/HTTP Security</emphasis>
  80. - the most complex part. Sets up the filters and related service beans used to apply
  81. the framework authentication mechanisms, to secure URLs, render login and error pages
  82. and much more.</para>
  83. </listitem>
  84. <listitem>
  85. <para>
  86. <emphasis>Business Object (Method) Security</emphasis>
  87. - options for securing the service layer.</para>
  88. </listitem>
  89. <listitem>
  90. <para>
  91. <emphasis>AuthenticationManager</emphasis>
  92. - handles authentication requests from other parts of the framework. A default
  93. instance will be registered internally by the namespace.</para>
  94. </listitem>
  95. <listitem>
  96. <para>
  97. <emphasis>AccessDecisionManager</emphasis>
  98. - provides access decisions for web and method security. A default one will be
  99. registered, but you can also choose to use a custom one, declared using normal Spring
  100. bean syntax.</para>
  101. </listitem>
  102. <listitem>
  103. <para>
  104. <emphasis>AuthenticationProvider</emphasis>s - mechanisms against which the
  105. authentication manager authenticates users. The namespace provides supports for
  106. several standard options and also a means of adding custom beans declared using a
  107. traditional syntax.
  108. </para>
  109. </listitem>
  110. <listitem>
  111. <para>
  112. <emphasis>UserDetailsService</emphasis>
  113. - closely related to authentication providers, but often also required by other beans.</para>
  114. </listitem>
  115. <!-- todo: diagram and link to other sections which describe the interfaces -->
  116. </itemizedlist>
  117. </para>
  118. <para>We'll see how these work together in the following sections.</para>
  119. </section>
  120. </section>
  121. <section xml:id="ns-getting-started">
  122. <title>Getting Started with Security Namespace Configuration</title>
  123. <para>
  124. In this section, we'll look at how you can build up a namespace configuration to use some of the main
  125. features of the framework. Let's assume you initially want to get up and running as quickly as possible
  126. and add authentication support and access control to an existing web application, with a few
  127. test logins. Then we'll look at how to change over to authenticating against a database or other
  128. security information repository. In later sections we'll introduce more advanced namespace configuration
  129. options.
  130. </para>
  131. <section xml:id="ns-web-xml">
  132. <title><literal>web.xml</literal> Configuration</title>
  133. <para>
  134. The first thing you need to do is add the following filter declaration to your
  135. <literal>web.xml</literal>
  136. file:
  137. <programlisting>
  138. <![CDATA[
  139. <filter>
  140. <filter-name>springSecurityFilterChain</filter-name>
  141. <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  142. </filter>
  143. <filter-mapping>
  144. <filter-name>springSecurityFilterChain</filter-name>
  145. <url-pattern>/*</url-pattern>
  146. </filter-mapping>]]>
  147. </programlisting>
  148. This provides a hook into the Spring Security web infrastructure. <classname>DelegatingFilterProxy</classname>
  149. is a Spring Framework class which delegates to a filter implementation which is defined as a Spring bean in your
  150. application context. In this case, the bean is named "springSecurityFilterChain", which is an internal infrastructure
  151. bean created by the namespace to handle web security. Note that you should not use this bean name yourself.
  152. Once you've added this to your <filename>web.xml</filename>, you're ready to start editing your application
  153. context file. Web security services are configured using the <literal>&lt;http&gt;</literal>
  154. element.
  155. </para>
  156. </section>
  157. <section xml:id="ns-minimal">
  158. <title>A Minimal <literal>&lt;http&gt;</literal> Configuration</title>
  159. <para>
  160. All you need to enable web security to begin with is
  161. <programlisting><![CDATA[
  162. <http auto-config='true'>
  163. <intercept-url pattern="/**" access="ROLE_USER" />
  164. </http>
  165. ]]>
  166. </programlisting>
  167. Which says that we want all URLs within our application to be secured, requiring the role
  168. <literal>ROLE_USER</literal> to access them.</para>
  169. <note><para>You can use multiple <literal>&lt;intercept-url&gt;</literal> elements to define
  170. different access requirements for different sets of URLs, but they will be evaluated in the
  171. order listed and the first match will be used. So you must put the most specific matches at the top.</para></note>
  172. <para>
  173. To add some users, you can define a set of test data directly in the
  174. namespace:
  175. <programlisting><![CDATA[
  176. <authentication-provider>
  177. <user-service>
  178. <user name="jimi" password="jimispassword" authorities="ROLE_USER, ROLE_ADMIN" />
  179. <user name="bob" password="bobspassword" authorities="ROLE_USER" />
  180. </user-service>
  181. </authentication-provider>
  182. ]]>
  183. </programlisting>
  184. </para>
  185. <sidebar>
  186. <para>If you are familiar with previous versions of the framework, you can probably
  187. already guess roughly what's going on here. The &lt;http&gt; element is
  188. responsible for creating a <classname>FilterChainProxy</classname> and the
  189. filter beans which it uses. Common issues like incorrect filter ordering are no
  190. longer an issue as the filter positions are predefined.</para>
  191. <para>The <literal>&lt;authentication-provider&gt;</literal>
  192. element creates a <classname>DaoAuthenticationProvider</classname>
  193. bean and the <literal>&lt;user-service&gt;</literal> element creates an
  194. <classname>InMemoryDaoImpl</classname>. A <literal>ProviderManager</literal>
  195. bean is always created by the namespace processing system and the
  196. <classname>DaoAuthenticationProvider</classname>
  197. is automatically registered with it. You can find more detailed
  198. information on the beans that are created in the <link xlink:href="#appendix-namespace">namespace appendix</link>.
  199. </para>
  200. </sidebar>
  201. <para>
  202. The configuration above defines two users, their passwords and their roles within the application (which will
  203. be used for access control). It is also possible to load user information from
  204. a standard properties file using the <literal>properties</literal> attribute on
  205. <literal>user-service</literal>. See the section on
  206. <link xlink:href="#in-memory-service">in-memory authentication</link> for more details.
  207. Using the <literal>&lt;authentication-provider&gt;</literal>
  208. element means that the user information will be used by the authentication
  209. manager to process authentication requests.
  210. </para>
  211. <para>
  212. At this point you should be able to start up your application and you will be required to
  213. log in to proceed. Try it out, or try experimenting with the "tutorial" sample application
  214. that comes with the project. The above configuration actually adds quite a few services to
  215. the application because we have used the
  216. <literal>auto-config</literal>
  217. attribute. For example, form login processing and "remember-me" services are automatically
  218. enabled.
  219. </para>
  220. <section xml:id="ns-auto-config">
  221. <title>What does <literal>auto-config</literal> Include?</title>
  222. <para>
  223. The <literal>auto-config</literal> attribute, as we have used it above, is just a
  224. shorthand syntax for:
  225. <programlisting><![CDATA[
  226. <http>
  227. <intercept-url pattern="/**" access="ROLE_USER" />
  228. <form-login />
  229. <anonymous />
  230. <http-basic />
  231. <logout />
  232. <remember-me />
  233. </http>
  234. ]]>
  235. </programlisting>
  236. These other elements are responsible for setting up form-login,
  237. <link xlink:href="#anonymous">anonymous authentication</link>, basic authentication, logout handling and remember-me services
  238. respectively. They each have attributes which can be used to alter their behaviour.
  239. </para>
  240. <tip>
  241. <title><literal>auto-config</literal> Requires a UserDetailsService</title>
  242. <para>An error can occur when using auto-config without a <interfacename>UserDetailsService</interfacename> in
  243. your application context (for example, if you are using LDAP authentication).
  244. This is because remember-me is automatically enabled when <literal>auto-config="true"</literal> and it requires
  245. an authentication mechanism which uses a <interfacename>UserDetailsService</interfacename> to function (see
  246. the <link xlink:href="#remember-me">Remember-me chapter</link> for more details). If you have an error caused
  247. by a missing <interfacename>UserDetailsService</interfacename> then try removing the <literal>auto-config</literal>
  248. setting (and any <literal>remember-me</literal> setting you might have).
  249. </para>
  250. </tip>
  251. </section>
  252. <section xml:id="ns-form-and-basic">
  253. <title>Form and Basic Login Options</title>
  254. <para>
  255. You might be wondering where the login form came from when you were prompted
  256. to log in, since we made no mention of any HTML files or JSPs. In fact, since we didn't explicitly
  257. set a URL for the login page, Spring Security generates one automatically, based on the features
  258. that are enabled and using standard values for the URL which processes the submitted login,
  259. the default target URL the user will be sent to and so on. However, the namespace offers plenty of
  260. suppport to allow you to customize these options.
  261. For example, if you want to supply your own login page, you could use:
  262. <programlisting><![CDATA[
  263. <http auto-config='true'>
  264. <intercept-url pattern="/login.jsp*" filters="none"/>
  265. <intercept-url pattern="/**" access="ROLE_USER" />
  266. <form-login login-page='/login.jsp'/>
  267. </http>
  268. ]]>
  269. </programlisting>
  270. Note that you can still use <literal>auto-config</literal>. The <literal>form-login</literal> element just overrides the
  271. default settings. Also note that we've added an extra <literal>intercept-url</literal> element to say that any requests
  272. for the login page should be excluded from processing by the security filters. Otherwise the request would be matched by
  273. the pattern <literal>/**</literal> and it wouldn't be possible to access the login page itself!
  274. If you want to use basic authentication instead of form login, then change the configuration to
  275. <programlisting><![CDATA[
  276. <http auto-config='true'>
  277. <intercept-url pattern="/**" access="ROLE_USER" />
  278. <http-basic />
  279. </http>
  280. ]]>
  281. </programlisting>
  282. Basic authentication will then take precedence and will be used to prompt for a login when a user attempts to access
  283. a protected resource. Form login is still available in this configuration if you wish to use it, for example
  284. through a login form embedded in another web page.
  285. </para>
  286. <section xml:id="ns-form-target">
  287. <title>Setting a Default Post-Login Destination</title>
  288. <para>
  289. If a form login isn't prompted by an attempt to access a protected resource, the <literal>default-target-url</literal>
  290. option comes into play. This is the URL the user will be taken to after logging in, and defaults to "/". You can
  291. also configure things so that they user <emphasis>always</emphasis> ends up at this page (regardless of whether
  292. the login was "on-demand" or they explicitly chose to log in) by setting the
  293. <literal>always-use-default-target</literal> attribute to "true". This is useful if your application always
  294. requires that the user starts at a "home" page, for example:
  295. <programlisting><![CDATA[
  296. <http>
  297. <intercept-url pattern='/login.htm*' filters='none'/>
  298. <intercept-url pattern='/**' access='ROLE_USER' />
  299. <form-login login-page='/login.htm' default-target-url='/home.htm' always-use-default-target='true' />
  300. </http>
  301. ]]>
  302. </programlisting>
  303. </para>
  304. </section>
  305. </section>
  306. </section>
  307. <section xml:id="ns-auth-providers">
  308. <title>Using other Authentication Providers</title>
  309. <para>
  310. In practice you will need a more scalable source of user information than a few names added to the application context file.
  311. Most likely you will want to store your user information in something like a database or an LDAP server. LDAP namespace
  312. configuration is dealt with in the <link xlink:href="#ldap">LDAP chapter</link>, so we won't cover it here. If you have a
  313. custom implementation of Spring Security's <classname>UserDetailsService</classname>, called "myUserDetailsService" in your
  314. application context, then you can authenticate against this using
  315. <programlisting><![CDATA[
  316. <authentication-provider user-service-ref='myUserDetailsService'/>
  317. ]]>
  318. </programlisting>
  319. If you want to use a database, then you can use
  320. <programlisting><![CDATA[
  321. <authentication-provider>
  322. <jdbc-user-service data-source-ref="securityDataSource"/>
  323. </authentication-provider>
  324. ]]>
  325. </programlisting>
  326. Where "securityDataSource" is the name of a <classname>DataSource</classname> bean in the application context,
  327. pointing at a database containing the standard Spring Security user data tables. Alternatively, you could configure
  328. a Spring Security <classname>JdbcDaoImpl</classname> bean and point at that using the <literal>user-service-ref</literal>
  329. attribute:
  330. <programlisting><![CDATA[
  331. <authentication-provider user-service-ref='myUserDetailsService'/>
  332. <beans:bean id="myUserDetailsService" class="org.springframework.security.userdetails.jdbc.JdbcDaoImpl">
  333. <beans:property name="dataSource" ref="dataSource"/>
  334. </beans:bean>
  335. ]]>
  336. </programlisting>
  337. You can also use standard <interfacename>AuthenticationProvider</interfacename> beans by adding the
  338. <literal>&lt;custom-authentication-provider&gt;</literal> element within the bean definition. See
  339. <xref linkend="ns-auth-manager"/> for more on this.
  340. </para>
  341. <section><title>Adding a Password Encoder</title>
  342. <para>
  343. Often your password data will be encoded using a hashing algorithm. This is supported by the <literal>&lt;password-encoder&gt;</literal>
  344. element. With SHA encoded passwords, the original authentication provider configuration would look like this:
  345. <programlisting><![CDATA[
  346. <authentication-provider>
  347. <password-encoder hash="sha"/>
  348. <user-service>
  349. <user name="jimi" password="d7e6351eaa13189a5a3641bab846c8e8c69ba39f" authorities="ROLE_USER, ROLE_ADMIN" />
  350. <user name="bob" password="4e7421b1b8765d8f9406d87e7cc6aa784c4ab97f" authorities="ROLE_USER" />
  351. </user-service>
  352. </authentication-provider>
  353. ]]>
  354. </programlisting>
  355. </para>
  356. <para>
  357. When using hashed passwords, it's also a good idea to use a salt value to protect against dictionary attacks and Spring Security supports this too.
  358. Ideally you would want to use a randomly generated salt value for each user, but you can use any property of the <classname>UserDetails</classname>
  359. object which is loaded by your <classname>UserDetailsService</classname>. For example, to use the <literal>username</literal> property, you would use
  360. <programlisting><![CDATA[
  361. <password-encoder hash="sha">
  362. <salt-source user-property="username"/>
  363. </password-encoder>
  364. ]]></programlisting>
  365. You can use a custom password encoder bean by using the <literal>ref</literal> attribute of <literal>password-encoder</literal>. This should
  366. contain the name of a bean in the application context which is an instance of Spring Security's <interfacename>PasswordEncoder</interfacename>
  367. interface.
  368. </para>
  369. </section>
  370. </section>
  371. </section>
  372. <section xml:id="ns-web-advanced">
  373. <title>Advanced Web Features</title>
  374. <section xml:id="ns-remember-me">
  375. <title>Remember-Me Authentication</title>
  376. <para>See the separate <link xlink:href="#remember-me">Remember-Me chapter</link> for information on remember-me namespace configuration.</para>
  377. </section>
  378. <section xml:id="ns-requires-channel">
  379. <title>Adding HTTP/HTTPS Channel Security</title>
  380. <para>If your application supports both HTTP and HTTPS, and you require that particular URLs can only be accessed over HTTPS, then this is
  381. directly supported using the <literal>requires-channel</literal> attribute on <literal>&lt;intercept-url&gt;</literal>:
  382. <programlisting><![CDATA[
  383. <http>
  384. <intercept-url pattern="/secure/**" access="ROLE_USER" requires-channel="https"/>
  385. <intercept-url pattern="/**" access="ROLE_USER" requires-channel="any"/>
  386. ...
  387. </http>]]>
  388. </programlisting>
  389. With this configuration in place, if a user attempts to access anything matching the "/secure/**"
  390. pattern using HTTP, they will first be redirected to an HTTPS URL.
  391. The available options are "http", "https" or "any". Using the value "any" means that either HTTP or HTTPS
  392. can be used.
  393. </para>
  394. <para>
  395. If your application uses non-standard ports for HTTP and/or HTTPS, you can specify a list of port mappings as follows:
  396. <programlisting>
  397. <![CDATA[
  398. <http>
  399. ...
  400. <port-mappings>
  401. <port-mapping http="9080" https="9443"/>
  402. </port-mappings>
  403. </http>]]>
  404. </programlisting>
  405. You can find a more in-depth discussion of channel security in <xref xlink:href="#channel-security"/>.
  406. </para>
  407. </section>
  408. <section xml:id="ns-concurrent-session">
  409. <title>Concurrent Session Control</title>
  410. <para>
  411. If you wish to place constraints on a single user's ability to log in to your application,
  412. Spring Security supports this out of the box with the following simple additions. First you need to add the
  413. following listener to your <filename>web.xml</filename> file to keep Spring Security updated about
  414. session lifecycle events:
  415. <programlisting>
  416. <![CDATA[
  417. <listener>
  418. <listener-class>org.springframework.security.ui.session.HttpSessionEventPublisher</listener-class>
  419. </listener>
  420. ]]></programlisting>
  421. Then add the following line to your application context:
  422. <programlisting><![CDATA[
  423. <http>
  424. ...
  425. <concurrent-session-control max-sessions="1" />
  426. </http>]]>
  427. </programlisting>
  428. This will prevent a user from logging in multiple times - a second login will cause the first to
  429. be invalidated. Often you would prefer to prevent a second login, in which case you can use
  430. <programlisting><![CDATA[
  431. <http>
  432. ...
  433. <concurrent-session-control max-sessions="1" exception-if-maximum-exceeded="true"/>
  434. </http>]]>
  435. </programlisting>
  436. The second login will then be rejected. <!-- TODO: Link to main section in docs -->
  437. </para>
  438. </section>
  439. <section xml:id="ns-openid">
  440. <title>OpenID Login</title>
  441. <para>The namespace supports <link xlink:href="http://openid.net/">OpenID</link> login either instead of, or in addition to
  442. normal form-based login, with a simple change:
  443. <programlisting><![CDATA[
  444. <http>
  445. <intercept-url pattern="/**" access="ROLE_USER" />
  446. <openid-login />
  447. </http>
  448. ]]></programlisting>
  449. You should then register yourself with an OpenID provider (such as myopenid.com), and
  450. add the user information to your in-memory <literal>&lt;user-service&gt;</literal>:
  451. <programlisting><![CDATA[
  452. <user name="http://jimi.hendrix.myopenid.com/" password="notused" authorities="ROLE_USER" />
  453. ]]></programlisting>
  454. You should be able to login using the <literal>myopenid.com</literal> site to authenticate.
  455. </para>
  456. </section>
  457. <section xml:id="ns-custom-filters">
  458. <title>Adding in Your Own Filters</title>
  459. <para>If you've used Spring Security before, you'll know that the framework maintains a chain
  460. of filters in order to apply its services. You may want to add your own filters to the stack at
  461. particular locations or use a Spring Security filter for which there isn't currently a namespace
  462. configuration option (CAS, for example). Or you might want to use a customized version of a
  463. standard namespace filter, such as the <literal>AuthenticationProcessingFilter</literal> which is created by the
  464. <literal>&lt;form-login&gt;</literal> element, taking advantage of some of the extra configuration options which are
  465. available by using defining the bean directly. How can you do this with namespace configuration,
  466. since the filter chain is not directly exposed?
  467. </para>
  468. <para>The order of the filters is always strictly enforced when using the namespace. Each Spring Security
  469. filter implements the Spring <interfacename>Ordered</interfacename> interface and the filters created by the namespace
  470. are sorted during initialization. The standard Spring Security filters each have an alias in the namespace. The filters, aliases
  471. and namespace elements/attributes which create the filters are shown in <xref linkend="filter-stack"/>.
  472. <table xml:id="filter-stack">
  473. <title>Standard Filter Aliases and Ordering</title>
  474. <tgroup cols="3" align="left">
  475. <thead><row>
  476. <entry align="center">Alias</entry><entry align="center">Filter Class</entry><entry align="center">Namespace Element or Attribute</entry>
  477. </row></thead>
  478. <tbody>
  479. <row>
  480. <entry> CHANNEL_FILTER</entry>
  481. <entry><literal>ChannelProcessingFilter</literal></entry>
  482. <entry><literal>http/intercept-url</literal></entry>
  483. </row>
  484. <row>
  485. <entry> CONCURRENT_SESSION_FILTER</entry>
  486. <entry><literal>ConcurrentSessionFilter</literal>
  487. </entry><entry><literal>http/concurrent-session-control</literal></entry>
  488. </row>
  489. <row>
  490. <entry> SESSION_CONTEXT_INTEGRATION_FILTER</entry>
  491. <entry><classname>HttpSessionContextIntegrationFilter</classname></entry>
  492. <entry><literal>http</literal></entry>
  493. </row>
  494. <row>
  495. <entry> LOGOUT_FILTER </entry>
  496. <entry><literal>LogoutFilter</literal></entry>
  497. <entry><literal>http/logout</literal></entry>
  498. </row>
  499. <row>
  500. <entry> X509_FILTER </entry>
  501. <entry><literal>X509PreAuthenticatedProcessigFilter</literal></entry>
  502. <entry><literal>http/x509</literal></entry>
  503. </row>
  504. <row>
  505. <entry> PRE_AUTH_FILTER </entry>
  506. <entry><literal>AstractPreAuthenticatedProcessingFilter</literal> Subclasses</entry>
  507. <entry>N/A</entry>
  508. </row>
  509. <row>
  510. <entry> CAS_PROCESSING_FILTER </entry>
  511. <entry><literal>CasProcessingFilter</literal></entry>
  512. <entry>N/A</entry>
  513. </row>
  514. <row>
  515. <entry> AUTHENTICATION_PROCESSING_FILTER </entry>
  516. <entry><literal>AuthenticationProcessingFilter</literal></entry>
  517. <entry><literal>http/form-login</literal></entry>
  518. </row>
  519. <row>
  520. <entry> BASIC_PROCESSING_FILTER </entry>
  521. <entry><literal>BasicProcessingFilter</literal></entry>
  522. <entry><literal>http/http-basic</literal></entry>
  523. </row>
  524. <row>
  525. <entry> SERVLET_API_SUPPORT_FILTER</entry>
  526. <entry><literal>SecurityContextHolderAwareRequestFilter</literal></entry>
  527. <entry><literal>http/@servlet-api-provision</literal></entry>
  528. </row>
  529. <row>
  530. <entry> REMEMBER_ME_FILTER </entry>
  531. <entry><classname>RememberMeProcessingFilter</classname></entry>
  532. <entry><literal>http/remember-me</literal></entry>
  533. </row>
  534. <row>
  535. <entry> ANONYMOUS_FILTER </entry>
  536. <entry><literal>AnonymousProcessingFilter</literal></entry>
  537. <entry><literal>http/anonymous</literal></entry>
  538. </row>
  539. <row>
  540. <entry> EXCEPTION_TRANSLATION_FILTER </entry>
  541. <entry><classname>ExceptionTranslationFilter</classname></entry>
  542. <entry><literal>http</literal></entry>
  543. </row>
  544. <row>
  545. <entry> NTLM_FILTER </entry>
  546. <entry><literal>NtlmProcessingFilter</literal></entry>
  547. <entry>N/A</entry>
  548. </row>
  549. <row>
  550. <entry> FILTER_SECURITY_INTERCEPTOR </entry>
  551. <entry><classname>FilterSecurityInterceptor</classname></entry>
  552. <entry><literal>http</literal></entry>
  553. </row>
  554. <row>
  555. <entry> SWITCH_USER_FILTER </entry>
  556. <entry><literal>SwitchUserProcessingFilter</literal></entry>
  557. <entry>N/A</entry>
  558. </row>
  559. </tbody>
  560. </tgroup>
  561. </table>
  562. You can add your own filter to the stack, using the <literal>custom-filter</literal> element and one of these
  563. names to specify the position your filter should appear at:
  564. <programlisting><![CDATA[
  565. <beans:bean id="myFilter" class="com.mycompany.MySpecialAuthenticationFilter">
  566. <custom-filter position="AUTHENTICATION_PROCESSING_FILTER"/>
  567. </beans:bean>
  568. ]]></programlisting>
  569. You can also use the <literal>after</literal> or <literal>before</literal> attribtues if you want your filter
  570. to be inserted before or after another filter in the stack. The names "FIRST" and "LAST" can be used with the
  571. <literal>position</literal> attribute to indicate that you want your filter to appear before or after the entire stack, respectively.
  572. </para>
  573. <tip>
  574. <title>Avoiding filter position conflicts</title>
  575. <para>
  576. If you are inserting a custom filter which may occupy the same position as one of the standard filters created by the namespace
  577. then it's important that you don't include the namespace versions by mistake. Avoid using the
  578. <literal>auto-config</literal> attribute and remove any elements which create filters whose functionality you want to replace.
  579. </para>
  580. <para>
  581. Note that you can't replace filters which are created by the use of the <literal>&lt;http&gt;</literal>
  582. element itself - <classname>HttpSessionContextIntegrationFilter</classname>, <classname>ExceptionTranslationFilter</classname> or
  583. <classname>FilterSecurityInterceptor</classname>.
  584. </para>
  585. </tip>
  586. <para>
  587. If you're replacing a namespace filter which requires an authentication entry point (i.e. where the authentication process is triggered by
  588. an attempt by an unauthenticated user to access to a secured resource), you will need to add a custom entry point bean too.
  589. </para>
  590. <section xml:id="ns-entry-point-ref">
  591. <title>Setting a Custom <interfacename>AuthenticationEntryPoint</interfacename></title>
  592. <para>
  593. If you aren't using form login, OpenID or basic authentication through the namespace, you may
  594. want to define an authentication filter and entry point using a traditional bean syntax and link them
  595. into the namespace, as we've just seen. The corresponding <interfacename>AuthenticationEntryPoint</interfacename> can be set using the
  596. <literal>entry-point-ref</literal> attribute on the <literal>&lt;http&gt;</literal> element.
  597. </para>
  598. <para>
  599. The CAS sample application is a good example of the use of custom beans with the namespace, including this syntax. If you aren't
  600. familiar with authentication entry points, they are discussed in the <link xlink:href="#tech-auth-entry-point">technical
  601. overview</link> chapter.
  602. </para>
  603. </section>
  604. </section>
  605. <section xml:id="ns-session-fixation">
  606. <title>Session Fixation Attack Protection</title>
  607. <para>
  608. <link xlink:href="http://en.wikipedia.org/wiki/Session_fixation">Session fixation</link>
  609. attacks are a potential risk where it is possible for a malicious attacker to create
  610. a session by accessing a site, then persuade another user to log in with the same session
  611. (by sending them a link containing the session identifier as a parameter, for example). Spring Security
  612. protects against this automatically by creating a new session when a user logs in. If you don't require
  613. this protection, or it conflicts with some other requirement, you can control the behaviour using the
  614. <literal>session-fixation-protection</literal> attribute on <literal>&lt;http&gt;</literal>, which
  615. has three options
  616. <itemizedlist>
  617. <listitem><para><literal>migrateSession</literal> - creates a new session and copies the existing
  618. session attributes to the new session. This is the default.</para></listitem>
  619. <listitem><para><literal>none</literal> - Don't do anything. The original session will be retained.</para></listitem>
  620. <listitem><para><literal>newSession</literal> - Create a new "clean" session, without copying the existing session data.</para></listitem>
  621. </itemizedlist>
  622. </para>
  623. </section>
  624. </section>
  625. <section xml:id="ns-method-security">
  626. <title>Method Security</title>
  627. <para>
  628. Spring Security 2.0 has improved support substantially for adding security to your service layer methods. If you are
  629. using Java 5 or greater, then support for JSR-250 security annotations is provided, as well as the framework's native
  630. <literal>@Secured</literal> annotation. You can apply security to a single bean, using the <literal>intercept-methods</literal>
  631. element to decorate the bean declaration, or you can secure multiple beans across the entire service layer using the
  632. AspectJ style pointcuts.
  633. </para>
  634. <section xml:id="ns-global-method">
  635. <title>The <literal>&lt;global-method-security&gt;</literal> Element</title>
  636. <para>
  637. This element is used to enable annotation-based security in your application (by setting the appropriate
  638. attributes on the element), and also to group together security pointcut declarations which will be applied across your
  639. entire application context. You should only declare one <literal>&lt;global-method-security&gt;</literal> element.
  640. The following declaration would enable support for both Spring Security's <literal>@Secured</literal>, and JSR-250 annotations:
  641. <programlisting><![CDATA[
  642. <global-method-security secured-annotations="enabled" jsr250-annotations="enabled"/>
  643. ]]>
  644. </programlisting>
  645. Adding an annotation to a method (on an class or interface) would then limit the access to that method
  646. accordingly. Spring Security's native annotation support defines a set of attributes for the method. These
  647. will be passed to the <interfacename>AccessDecisionManager</interfacename> for it to make the actual decision.
  648. This example is taken from the <link xlink:href="#tutorial-sample">tutorial sample</link>, which is a good
  649. starting point if you want to use method security in your application:
  650. <programlisting>
  651. public interface BankService {
  652. @Secured("IS_AUTHENTICATED_ANONYMOUSLY")
  653. public Account readAccount(Long id);
  654. @Secured("IS_AUTHENTICATED_ANONYMOUSLY")
  655. public Account[] findAccounts();
  656. @Secured("ROLE_TELLER")
  657. public Account post(Account account, double amount);
  658. }
  659. </programlisting>
  660. </para>
  661. <section xml:id="ns-protect-pointcut">
  662. <title>Adding Security Pointcuts using <literal>protect-pointcut</literal></title>
  663. <para>
  664. The use of <literal>protect-pointcut</literal> is particularly powerful, as it allows you to
  665. apply security to many beans with only a simple declaration. Consider the following example:
  666. <programlisting><![CDATA[
  667. <global-method-security>
  668. <protect-pointcut expression="execution(* com.mycompany.*Service.*(..))" access="ROLE_USER"/>
  669. </global-method-security>
  670. ]]>
  671. </programlisting>
  672. This will protect all methods on beans declared in the application context whose classes
  673. are in the <literal>com.mycompany</literal> package and whose class names end in "Service".
  674. Only users with the <literal>ROLE_USER</literal> role will be able to invoke these methods.
  675. As with URL matching, the most specific matches must come first in the list of pointcuts, as the
  676. first matching expression will be used.
  677. </para>
  678. </section>
  679. </section>
  680. <section xml:id="ns-intercept-methods">
  681. <title>The <literal>intercept-methods</literal> Bean Decorator</title>
  682. <para>
  683. This alternative syntax allows you to specify security for a specific bean by adding this element within the bean itself.
  684. <programlisting><![CDATA[
  685. <bean:bean id="target" class="com.mycompany.myapp.MyBean">
  686. <intercept-methods>
  687. <protect method="set*" access="ROLE_ADMIN" />
  688. <protect method="get*" access="ROLE_ADMIN,ROLE_USER" />
  689. <protect method="doSomething" access="ROLE_USER" />
  690. </intercept-methods>
  691. </bean:bean>
  692. ]]></programlisting>
  693. This allows you to configure security attributes for individual methods on the bean or simple wildcarded patterns.
  694. </para>
  695. </section>
  696. </section>
  697. <section xml:id="ns-access-manager">
  698. <title>The Default AccessDecisionManager</title>
  699. <para>
  700. This section assumes you have some knowledge of the underlying architecture for access-control within
  701. Spring Security. If you don't you can skip it and come back to it later, as this section is only really relevant for
  702. people who need to do some customization in order to use more than simple role based security.
  703. </para>
  704. <para>
  705. When you use a namespace configuration, a default instance of <interfacename>AccessDecisionManager</interfacename>
  706. is automatically registered for you and will be used for making access decisions for method invocations
  707. and web URL access, based on the access attributes you specify in your <literal>intercept-url</literal> and
  708. <literal>protect-pointcut</literal> declarations (and in annotations if you are using annotation secured methods).
  709. </para>
  710. <para>
  711. The default strategy is to use an <classname>AffirmativeBased</classname> <interfacename>AccessDecisionManager</interfacename>
  712. with a <classname>RoleVoter</classname> and an <classname>AuthenticatedVoter</classname>.
  713. </para>
  714. <section xml:id="ns-custom-access-mgr">
  715. <title>Customizing the AccessDecisionManager</title>
  716. <para>
  717. If you need to use a more complicated access control strategy then it is easy to set an alternative for both
  718. method and web security.
  719. </para>
  720. <para>
  721. For method security, you do this by setting the <literal>access-decision-manager-ref</literal> attribute
  722. on <literal>global-method-security</literal>to the Id of the appropriate
  723. <interfacename>AccessDecisionManager</interfacename> bean in the application context:
  724. <programlisting><![CDATA[
  725. <global-method-security access-decision-manager-ref="myAccessDecisionManagerBean">
  726. ...
  727. </global-method-security>
  728. ]]></programlisting>
  729. </para>
  730. <para>
  731. The syntax for web security is the same, but on the <literal>http</literal> element:
  732. <programlisting><![CDATA[
  733. <http access-decision-manager-ref="myAccessDecisionManagerBean">
  734. ...
  735. </http>
  736. ]]></programlisting>
  737. </para>
  738. </section>
  739. </section>
  740. <section xml:id="ns-auth-manager">
  741. <title>The Default Authentication Manager</title>
  742. <para>
  743. We've touched on the idea that the namespace configuration automatically registers an authentication manager bean for
  744. you. This is an instance of Spring Security's <classname>ProviderManager</classname> class, which you may already
  745. be familiar with if you've used the framework before. You can't use a custom <classname>AuthenticationProvider</classname> if you are
  746. using either HTTP or method security through the namespace, but this should not be a problem as you have full control over
  747. the <classname>AuthenticationProvider</classname>s that are used.
  748. </para>
  749. <para>
  750. You may want to register additional <classname>AuthenticationProvider</classname> beans with the <classname>ProviderManager</classname>
  751. and you can do this using the <literal>&lt;custom-authentication-provider&gt;</literal> element within the bean. For example:
  752. <programlisting><![CDATA[
  753. <bean id="casAuthenticationProvider"
  754. class="org.springframework.security.providers.cas.CasAuthenticationProvider">
  755. <security:custom-authentication-provider />
  756. ...
  757. </bean>
  758. ]]></programlisting>
  759. </para>
  760. <para>
  761. Another common requirement is that another bean in the context may require a reference to the <interfacename>AuthenticationManager</interfacename>.
  762. There is a special element which lets you register an alias for the <interfacename>AuthenticationManager</interfacename> and you can then
  763. use this name elsewhere in your application context.
  764. <programlisting><![CDATA[
  765. <security:authentication-manager alias="authenticationManager"/>
  766. <bean id="customizedFormLoginFilter" class="org.springframework.security.ui.webapp.AuthenticationProcessingFilter">
  767. <security:custom-filter position="AUTHENTICATION_PROCESSING_FILTER "/>
  768. <property name="authenticationManager" ref="authenticationManager"/>
  769. ...
  770. </bean>
  771. ]]></programlisting>
  772. </para>
  773. </section>
  774. </chapter>