container-adapters.xml 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. <chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="ca"><info><title>Container Adapter Authentication</title></info>
  2. <section xml:id="ca-overview">
  3. <info><title>Overview</title></info>
  4. <para>Very early versions of Spring Security exclusively used
  5. Container Adapters for interfacing authentication with end users.
  6. Whilst this worked well, it required considerable time to support
  7. multiple container versions and the configuration itself was
  8. relatively time-consuming for developers. For this reason the HTTP
  9. Form Authentication and HTTP Basic Authentication approaches were
  10. developed, and are today recommended for almost all
  11. applications.</para>
  12. <para>Container Adapters enable Spring Security to integrate directly
  13. with the containers used to host end user applications. This
  14. integration means that applications can continue to leverage the
  15. authentication and authorization capabilities built into containers
  16. (such as <literal>isUserInRole()</literal> and form-based or basic
  17. authentication), whilst benefiting from the enhanced security
  18. interception capabilities provided by Spring Security (it should be
  19. noted that Spring Security also offers
  20. <literal>ContextHolderAwareRequestWrapper</literal> to deliver
  21. <literal>isUserInRole()</literal> and similar Servlet Specification
  22. compatibility methods).</para>
  23. <para>The integration between a container and Spring Security is
  24. achieved through an adapter. The adapter provides a
  25. container-compatible user authentication provider, and needs to return
  26. a container-compatible user object.</para>
  27. <para>The adapter is instantiated by the container and is defined in a
  28. container-specific configuration file. The adapter then loads a Spring
  29. application context which defines the normal authentication manager
  30. settings, such as the authentication providers that can be used to
  31. authenticate the request. The application context is usually named
  32. <literal>acegisecurity.xml</literal> and is placed in a
  33. container-specific location.</para>
  34. <para>Spring Security currently supports Jetty, Catalina (Tomcat),
  35. JBoss and Resin. Additional container adapters can easily be
  36. written</para>
  37. </section>
  38. <section xml:id="ca-adapter"><info><title>Adapter Authentication Provider</title></info>
  39. <para>As is always the case, the container adapter generated
  40. <literal>Authentication</literal> object still needs to be
  41. authenticated by an <literal>AuthenticationManager</literal> when
  42. requested to do so by the
  43. <literal>AbstractSecurityInterceptor</literal>. The
  44. <literal>AuthenticationManager</literal> needs to be certain the
  45. adapter-provided <literal>Authentication</literal> object is valid and
  46. was actually authenticated by a trusted adapter.</para>
  47. <para>Adapters create <literal>Authentication</literal> objects which
  48. are immutable and implement the <literal>AuthByAdapter</literal>
  49. interface. These objects store the hash of a key that is defined by
  50. the adapter. This allows the <literal>Authentication</literal> object
  51. to be validated by the <literal>AuthByAdapterProvider</literal>. This
  52. authentication provider is defined as follows:</para>
  53. <para><programlisting>&lt;bean id="authByAdapterProvider"
  54. class="org.springframework.security.adapters.AuthByAdapterProvider"&gt;
  55. &lt;property name="key"&gt;&lt;value&gt;my_password&lt;/value&gt;&lt;/property&gt;
  56. &lt;/bean&gt; </programlisting></para>
  57. <para>The key must match the key that is defined in the
  58. container-specific configuration file that starts the adapter. The
  59. <literal>AuthByAdapterProvider</literal> automatically accepts as
  60. valid any <literal>AuthByAdapter</literal> implementation that returns
  61. the expected hash of the key.</para>
  62. <para>To reiterate, this means the adapter will perform the initial
  63. authentication using providers such as
  64. <literal>DaoAuthenticationProvider</literal>, returning an
  65. <literal>AuthByAdapter</literal> instance that contains a hash code of
  66. the key. Later, when an application calls a security interceptor
  67. managed resource, the <literal>AuthByAdapter</literal> instance in the
  68. <literal>SecurityContext</literal> in the
  69. <literal>SecurityContextHolder</literal> will be tested by the
  70. application's <literal>AuthByAdapterProvider</literal>. There is no
  71. requirement for additional authentication providers such as
  72. <literal>DaoAuthenticationProvider</literal> within the
  73. application-specific application context, as the only type of
  74. <literal>Authentication</literal> instance that will be presented by
  75. the application is from the container adapter.</para>
  76. <para>Classloader issues are frequent with containers and the use of
  77. container adapters illustrates this further. Each container requires a
  78. very specific configuration. The installation instructions are
  79. provided below. Once installed, please take the time to try the sample
  80. application to ensure your container adapter is properly
  81. configured.</para>
  82. <para>When using container adapters with the
  83. <literal>DaoAuthenticationProvider</literal>, ensure you set its
  84. <literal>forcePrincipalAsString</literal> property to
  85. <literal>true</literal>.</para>
  86. </section>
  87. <section xml:id="ca-jetty"><info><title>Jetty</title></info>
  88. <para>The following was tested with Jetty 4.2.18.</para>
  89. <para><literal>$JETTY_HOME</literal> refers to the root of your Jetty
  90. installation.</para>
  91. <para>Edit your <literal>$JETTY_HOME/etc/jetty.xml</literal> file so
  92. the <literal>&lt;Configure class&gt;</literal> section has a new
  93. <literal>addRealm</literal> call:</para>
  94. <para><programlisting>
  95. &lt;Call name="addRealm"&gt;
  96. &lt;Arg&gt;
  97. &lt;New class="org.springframework.security.adapters.jetty.JettySpringSecurityUserRealm"&gt;
  98. &lt;Arg&gt;Spring Powered Realm&lt;/Arg&gt;
  99. &lt;Arg&gt;my_password&lt;/Arg&gt;
  100. &lt;Arg&gt;etc/acegisecurity.xml&lt;/Arg&gt;
  101. &lt;/New&gt;
  102. &lt;/Arg&gt;
  103. &lt;/Call&gt;
  104. </programlisting></para>
  105. <para>Copy <literal>acegisecurity.xml</literal> into
  106. <literal>$JETTY_HOME/etc</literal>.</para>
  107. <para>Copy the following files into
  108. <literal>$JETTY_HOME/ext</literal>:<itemizedlist>
  109. <listitem>
  110. <para><literal>aopalliance.jar</literal></para>
  111. </listitem>
  112. <listitem>
  113. <para><literal>commons-logging.jar</literal></para>
  114. </listitem>
  115. <listitem>
  116. <para><literal>spring.jar</literal></para>
  117. </listitem>
  118. <listitem>
  119. <para><literal>acegi-security-jetty-XX.jar</literal></para>
  120. </listitem>
  121. <listitem>
  122. <para><literal>commons-codec.jar</literal></para>
  123. </listitem>
  124. <listitem>
  125. <para><literal>burlap.jar</literal></para>
  126. </listitem>
  127. <listitem>
  128. <para><literal>hessian.jar</literal></para>
  129. </listitem>
  130. </itemizedlist></para>
  131. <para>None of the above JAR files (or
  132. <literal>acegi-security-XX.jar</literal>) should be in your
  133. application's <literal>WEB-INF/lib</literal>. The realm name indicated
  134. in your <literal>web.xml</literal> does matter with Jetty. The
  135. <literal>web.xml</literal> must express the same
  136. <literal>&lt;realm-name&gt;</literal> as your
  137. <literal>jetty.xml</literal> (in the example above, "Spring Powered
  138. Realm").</para>
  139. </section>
  140. <section xml:id="ca-jboss"><info><title>JBoss</title></info>
  141. <para>The following was tested with JBoss 3.2.6.</para>
  142. <para><literal>$JBOSS_HOME</literal> refers to the root of your JBoss
  143. installation.</para>
  144. <para>There are two different ways of making spring context available
  145. to the Jboss integration classes.</para>
  146. <para>The first approach is by editing your
  147. <literal>$JBOSS_HOME/server/your_config/conf/login-config.xml</literal>
  148. file so that it contains a new entry under the
  149. <literal>&lt;Policy&gt;</literal> section:</para>
  150. <para><programlisting>
  151. &lt;application-policy name = "SpringPoweredRealm"&gt;
  152. &lt;authentication&gt;
  153. &lt;login-module code = "org.springframework.security.adapters.jboss.JbossSpringSecurityLoginModule"
  154. flag = "required"&gt;
  155. &lt;module-option name = "appContextLocation"&gt;acegisecurity.xml&lt;/module-option&gt;
  156. &lt;module-option name = "key"&gt;my_password&lt;/module-option&gt;
  157. &lt;/login-module&gt;
  158. &lt;/authentication&gt;
  159. &lt;/application-policy&gt;
  160. </programlisting></para>
  161. <para>Copy <literal>acegisecurity.xml</literal> into
  162. <literal>$JBOSS_HOME/server/your_config/conf</literal>.</para>
  163. <para>In this configuration <literal>acegisecurity.xml</literal>
  164. contains the spring context definition including all the
  165. authentication manager beans. You have to bear in mind though, that
  166. <literal>SecurityContext</literal> is created and destroyed on each
  167. login request, so the login operation might become costly.
  168. Alternatively, the second approach is to use Spring singleton
  169. capabilities through
  170. <literal>org.springframework.beans.factory.access.SingletonBeanFactoryLocator</literal>.
  171. The required configuration for this approach is:</para>
  172. <para><programlisting>
  173. &lt;application-policy name = "SpringPoweredRealm"&gt;
  174. &lt;authentication&gt;
  175. &lt;login-module code = "org.springframework.security.adapters.jboss.JbossSpringSecurityLoginModule"
  176. flag = "required"&gt;
  177. &lt;module-option name = "singletonId"&gt;springRealm&lt;/module-option&gt;
  178. &lt;module-option name = "key"&gt;my_password&lt;/module-option&gt;
  179. &lt;module-option name = "authenticationManager"&gt;authenticationManager&lt;/module-option&gt;
  180. &lt;/login-module&gt;
  181. &lt;/authentication&gt;
  182. &lt;/application-policy&gt;
  183. </programlisting></para>
  184. <para>In the above code fragment,
  185. <literal>authenticationManager</literal> is a helper property that
  186. defines the expected name of the
  187. <literal>AuthenticationManager</literal> in case you have several
  188. defined in the IoC container. The <literal>singletonId</literal>
  189. property references a bean defined in a
  190. <literal>beanRefFactory.xml</literal> file. This file needs to be
  191. available from anywhere on the JBoss classpath, including
  192. <literal>$JBOSS_HOME/server/your_config/conf</literal>. The
  193. <literal>beanRefFactory.xml</literal> contains the following
  194. declaration:</para>
  195. <para><programlisting>
  196. &lt;beans&gt;
  197. &lt;bean id="springRealm" singleton="true" lazy-init="true" class="org.springframework.context.support.ClassPathXmlApplicationContext"&gt;
  198. &lt;constructor-arg&gt;
  199. &lt;list&gt;
  200. &lt;value&gt;acegisecurity.xml&lt;/value&gt;
  201. &lt;/list&gt;
  202. &lt;/constructor-arg&gt;
  203. &lt;/bean&gt;
  204. &lt;/beans&gt;
  205. </programlisting></para>
  206. <para>Finally, irrespective of the configuration approach you need to
  207. copy the following files into
  208. <literal>$JBOSS_HOME/server/your_config/lib</literal>:<itemizedlist>
  209. <listitem>
  210. <para><literal>aopalliance.jar</literal></para>
  211. </listitem>
  212. <listitem>
  213. <para><literal>spring.jar</literal></para>
  214. </listitem>
  215. <listitem>
  216. <para><literal>acegi-security-jboss-XX.jar</literal></para>
  217. </listitem>
  218. <listitem>
  219. <para><literal>commons-codec.jar</literal></para>
  220. </listitem>
  221. <listitem>
  222. <para><literal>burlap.jar</literal></para>
  223. </listitem>
  224. <listitem>
  225. <para><literal>hessian.jar</literal></para>
  226. </listitem>
  227. </itemizedlist></para>
  228. <para>None of the above JAR files (or
  229. <literal>acegi-security-XX.jar</literal>) should be in your
  230. application's <literal>WEB-INF/lib</literal>. The realm name indicated
  231. in your <literal>web.xml</literal> does not matter with JBoss.
  232. However, your web application's
  233. <literal>WEB-INF/jboss-web.xml</literal> must express the same
  234. <literal>&lt;security-domain&gt;</literal> as your
  235. <literal>login-config.xml</literal>. For example, to match the above
  236. example, your <literal>jboss-web.xml</literal> would look like
  237. this:</para>
  238. <para><programlisting>
  239. &lt;jboss-web&gt;
  240. &lt;security-domain&gt;java:/jaas/SpringPoweredRealm&lt;/security-domain&gt;
  241. &lt;/jboss-web&gt;</programlisting></para>
  242. <para>JBoss is a widely-used container adapter (mostly due to the need
  243. to support legacy EJBs), so please let us know if you have any
  244. difficulties.</para>
  245. </section>
  246. <section xml:id="ca-resin"><info><title>Resin</title></info>
  247. <para>The following was tested with Resin 3.0.6.</para>
  248. <para><literal>$RESIN_HOME</literal> refers to the root of your Resin
  249. installation.</para>
  250. <para>Resin provides several ways to support the container adapter. In
  251. the instructions below we have elected to maximise consistency with
  252. other container adapter configurations. This will allow Resin users to
  253. simply deploy the sample application and confirm correct
  254. configuration. Developers comfortable with Resin are naturally able to
  255. use its capabilities to package the JARs with the web application
  256. itself, and/or support single sign-on.</para>
  257. <para>Copy the following files into
  258. <literal>$RESIN_HOME/lib</literal>:<itemizedlist>
  259. <listitem>
  260. <para><literal>aopalliance.jar</literal></para>
  261. </listitem>
  262. <listitem>
  263. <para><literal>commons-logging.jar</literal></para>
  264. </listitem>
  265. <listitem>
  266. <para><literal>spring.jar</literal></para>
  267. </listitem>
  268. <listitem>
  269. <para><literal>acegi-security-resin-XX.jar</literal></para>
  270. </listitem>
  271. <listitem>
  272. <para><literal>commons-codec.jar</literal></para>
  273. </listitem>
  274. <listitem>
  275. <para><literal>burlap.jar</literal></para>
  276. </listitem>
  277. <listitem>
  278. <para><literal>hessian.jar</literal></para>
  279. </listitem>
  280. </itemizedlist></para>
  281. <para>Unlike the container-wide <literal>acegisecurity.xml</literal>
  282. files used by other container adapters, each Resin web application
  283. will contain its own
  284. <literal>WEB-INF/resin-acegisecurity.xml</literal> file. Each web
  285. application will also contain a <literal>resin-web.xml</literal> file
  286. which Resin uses to start the container adapter:</para>
  287. <para><programlisting>
  288. &lt;web-app&gt;
  289. &lt;authenticator&gt;
  290. &lt;type&gt;org.springframework.security.adapters.resin.ResinAcegiAuthenticator&lt;/type&gt;
  291. &lt;init&gt;
  292. &lt;app-context-location&gt;WEB-INF/resin-acegisecurity.xml&lt;/app-context-location&gt;
  293. &lt;key&gt;my_password&lt;/key&gt;
  294. &lt;/init&gt;
  295. &lt;/authenticator&gt;
  296. &lt;/web-app&gt;
  297. </programlisting></para>
  298. <para>With the basic configuration provided above, none of the JAR
  299. files listed (or <literal>acegi-security-XX.jar</literal>) should be
  300. in your application's <literal>WEB-INF/lib</literal>. The realm name
  301. indicated in your <literal>web.xml</literal> does not matter with
  302. Resin, as the relevant authentication class is indicated by the
  303. <literal>&lt;authenticator&gt;</literal> setting</para>
  304. </section>
  305. <section xml:id="ca-tomcat"><info><title>Tomcat</title></info>
  306. <para>The following was tested with Jakarta Tomcat 4.1.30 and
  307. 5.0.19.</para>
  308. <para><literal>$CATALINA_HOME</literal> refers to the root of your
  309. Catalina (Tomcat) installation.</para>
  310. <para>Edit your <literal>$CATALINA_HOME/conf/server.xml</literal> file
  311. so the <literal>&lt;Engine&gt;</literal> section contains only one
  312. active <literal>&lt;Realm&gt;</literal> entry. An example realm
  313. entry:</para>
  314. <para><programlisting> &lt;Realm
  315. className="org.springframework.security.adapters.catalina.CatalinaSpringSecurityUserRealm"
  316. appContextLocation="conf/acegisecurity.xml"
  317. key="my_password" /&gt;</programlisting></para>
  318. <para>Be sure to remove any other <literal>&lt;Realm&gt;</literal>
  319. entry from your <literal>&lt;Engine&gt;</literal> section.</para>
  320. <para>Copy <literal>acegisecurity.xml</literal> into
  321. <literal>$CATALINA_HOME/conf</literal>.</para>
  322. <para>Copy <literal>spring-security-catalina-XX.jar</literal> into
  323. <literal>$CATALINA_HOME/server/lib</literal>.</para>
  324. <para>Copy the following files into
  325. <literal>$CATALINA_HOME/common/lib</literal>:</para>
  326. <itemizedlist>
  327. <listitem>
  328. <para><literal>aopalliance.jar</literal></para>
  329. </listitem>
  330. <listitem>
  331. <para><literal>spring.jar</literal></para>
  332. </listitem>
  333. <listitem>
  334. <para><literal>commons-codec.jar</literal></para>
  335. </listitem>
  336. <listitem>
  337. <para><literal>burlap.jar</literal></para>
  338. </listitem>
  339. <listitem>
  340. <para><literal>hessian.jar</literal></para>
  341. </listitem>
  342. </itemizedlist>
  343. <para>None of the above JAR files (or
  344. <literal>spring-security-XX.jar</literal>) should be in your
  345. application's <literal>WEB-INF/lib</literal>. The realm name indicated
  346. in your <literal>web.xml</literal> does not matter with
  347. Catalina.</para>
  348. <para>We have received reports of problems using this Container
  349. Adapter with Mac OS X. A work-around is to use a script such as
  350. follows:</para>
  351. <para><programlisting>#!/bin/sh
  352. export CATALINA_HOME="/Library/Tomcat"
  353. export JAVA_HOME="/Library/Java/Home"
  354. cd /
  355. $CATALINA_HOME/bin/startup.sh</programlisting></para>
  356. <para>Finally, restart Tomcat.</para>
  357. </section>
  358. </chapter>