index.xml 204 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
  3. "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
  4. <book>
  5. <bookinfo>
  6. <title>Acegi Security System for Spring</title>
  7. <subtitle>Reference Documentation</subtitle>
  8. <releaseinfo>0.7</releaseinfo>
  9. <authorgroup>
  10. <author>
  11. <firstname>Ben</firstname>
  12. <surname>Alex</surname>
  13. </author>
  14. </authorgroup>
  15. </bookinfo>
  16. <toc></toc>
  17. <preface id="preface">
  18. <title>Preface</title>
  19. <para>This document provides a reference guide to the Acegi Security
  20. System for Spring, which is a series of classes that deliver
  21. authentication and authorization services within the Spring
  22. Framework.</para>
  23. <para>I would like to acknowledge this reference was prepared using the
  24. DocBook configuration included with the Spring Framework. The Spring team
  25. in turn acknowledge Chris Bauer (Hibernate) for his assistance with their
  26. DocBook.</para>
  27. </preface>
  28. <chapter id="security">
  29. <title>Security</title>
  30. <sect1 id="security-before-you-begin">
  31. <title>Before You Begin</title>
  32. <para>For your security, each official release JAR of Acegi Security has
  33. been signed by the project leader. This does not in any way alter the
  34. liability disclaimer contained in the License, but it does ensure you
  35. are using a properly reviewed, official build of Acegi Security. Please
  36. refer to the <literal>readme.txt</literal> file in the root of the
  37. release distribution for instructions on how to validate the JARs are
  38. correctly signed, and which certificate has been used to sign
  39. them.</para>
  40. </sect1>
  41. <sect1 id="security-introduction">
  42. <title>Introduction</title>
  43. <para>The Acegi Security System for Spring provides authentication and
  44. authorization capabilities for Spring-powered projects, with full
  45. integration with popular web containers. The security architecture was
  46. designed from the ground up using "The Spring Way" of development, which
  47. includes using bean contexts, interceptors and interface-driven
  48. programming. As a consequence, the Acegi Security System for Spring is
  49. useful out-of-the-box for those seeking to secure their Spring-based
  50. applications, and can be easily adapted to complex customized
  51. requirements.</para>
  52. <para>Security involves two distinct operations, authentication and
  53. authorization. The former relates to resolving whether or not a caller
  54. is who they claim to be. Authorization on the other hand relates to
  55. determining whether or not an authenticated caller is permitted to
  56. perform a given operation.</para>
  57. <para>Throughout the Acegi Security System for Spring, the user, system
  58. or agent that needs to be authenticated is referred to as a "principal".
  59. The security architecture does not have a notion of roles or groups,
  60. which you may be familiar with from other security
  61. implementations.</para>
  62. <sect2 id="security-introduction-status">
  63. <title>Current Status</title>
  64. <para>The Acegi Security System for Spring is widely used by members
  65. of the Spring Community. The APIs are considered stable and only minor
  66. changes are expected. Having said that, like many other projects we
  67. need to strike a balance between backward compatibility and
  68. improvement. Effective version 0.6.1, Acegi Security uses the Apache
  69. Portable Runtime Project versioning guidelines, available from
  70. <literal>http://apr.apache.org/versioning.html</literal>.</para>
  71. <para>Some improvements are currently intended prior to the 1.0.0
  72. release. These are:</para>
  73. <itemizedlist spacing="compact">
  74. <listitem>
  75. <para>Replacing the Ant build with a Maven build. When this
  76. happens the <literal>lib</literal> directory will no longer be
  77. distributed in ZIP releases or hosted in CVS.</para>
  78. </listitem>
  79. <listitem>
  80. <para>"Remember me" functionality. Some discussion on this can be
  81. found at
  82. <literal>http://sourceforge.net/mailarchive/forum.php?thread_id=5177499&amp;forum_id=40659</literal>.</para>
  83. </listitem>
  84. <listitem>
  85. <para>A sample web application which demonstrates the access
  86. control list package.</para>
  87. </listitem>
  88. <listitem>
  89. <para>Implementation of an
  90. <literal>ObjectDefinitionSource</literal> that retrieves its
  91. details from a database.</para>
  92. </listitem>
  93. <listitem>
  94. <para>Deprecation of Acegi Security's various EH-CACHE-based cache
  95. implementations. Instead Acegi Security will provide new cache
  96. implementations which use Spring Framework's new (currently in
  97. CVS) <literal>EhCacheManagerFactoryBean</literal> factory. The
  98. deprecated classes may be removed from the 1.0.0 release.</para>
  99. </listitem>
  100. </itemizedlist>
  101. <para>Whilst this list is subject to change and not in any particular
  102. order, none of the above improvements are likely to result in changes
  103. to the API. The improvements are also relatively minor to implement.
  104. Users of Acegi Security System for Spring should therefore be
  105. comfortable depending on the current version of the project in their
  106. applications.</para>
  107. </sect2>
  108. </sect1>
  109. <sect1 id="security-high-level-design">
  110. <title>High Level Design</title>
  111. <sect2 id="security-high-level-design-key-components">
  112. <title>Key Components</title>
  113. <para>The Acegi Security System for Spring essentially comprises seven
  114. key functional parts:</para>
  115. <itemizedlist spacing="compact">
  116. <listitem>
  117. <para>An <literal>Authentication</literal> object which holds the
  118. principal, credentials and the authorities granted to the
  119. principal. The object can also store additional information
  120. associated with an authentication request, such as the source
  121. TCP/IP address.</para>
  122. </listitem>
  123. <listitem>
  124. <para>A <literal>ContextHolder</literal> which holds the
  125. <literal>Authentication</literal> object in a
  126. <literal>ThreadLocal</literal>-bound object.</para>
  127. </listitem>
  128. <listitem>
  129. <para>An <literal>AuthenticationManager</literal> to authenticate
  130. the <literal>Authentication</literal> object presented via the
  131. <literal>ContextHolder</literal>.</para>
  132. </listitem>
  133. <listitem>
  134. <para>An <literal>AccessDecisionManager</literal> to authorize a
  135. given operation.</para>
  136. </listitem>
  137. <listitem>
  138. <para>A <literal>RunAsManager</literal> to optionally replace the
  139. <literal>Authentication</literal> object whilst a given operation
  140. is being executed.</para>
  141. </listitem>
  142. <listitem>
  143. <para>A "secure object" interceptor, which coordinates the
  144. authentication, authorization, run-as replacement and execution of
  145. a given operation.</para>
  146. </listitem>
  147. <listitem>
  148. <para>An acess control list (ACL) management package, which can be
  149. used to obtain ACLs for domain object instances.</para>
  150. </listitem>
  151. </itemizedlist>
  152. <para>Secure objects refer to any type of object that can have
  153. security applied to it. A secure object must provide some form of
  154. callback, so that the security interceptor can transparently do its
  155. work as required, and callback the object when it is time for it to
  156. proceed with the requested operation. If secure objects cannot provide
  157. a native callback approach, a wrapper needs to be written so this
  158. becomes possible.</para>
  159. <para>Each secure object has its own package under
  160. <literal>net.sf.acegisecurity.intercept</literal>. Every other package
  161. in the security system is secure object independent, in that it can
  162. support any type of secure object presented.</para>
  163. <para>Only developers contemplating an entirely new way of
  164. intercepting and authorizing requests would need to use secure objects
  165. directly. For example, it would be possible to build a new secure
  166. object to secure calls to a messaging system that does not use
  167. <literal>MethodInvocation</literal>s. Most Spring applications will
  168. simply use the three currently supported secure object types
  169. (<literal>MethodInvocation</literal>, <literal>JoinPoint</literal> and
  170. <literal>FilterInterceptor</literal>) with complete
  171. transparency.</para>
  172. <para>Each of the seven key parts is discussed in detail throughout
  173. this document.</para>
  174. </sect2>
  175. <sect2 id="security-high-level-design-supported-secure-objects">
  176. <title>Supported Secure Objects</title>
  177. <para>The Acegi Security System for Spring currently supports three
  178. secure objects.</para>
  179. <para>The first handles an AOP Alliance
  180. <literal>MethodInvocation</literal>. This is the secure object type
  181. used to protect Spring beans. Developers will generally use this
  182. secure object type to secure their business objects. To make a
  183. standard Spring-hosted bean available as a
  184. <literal>MethodInvocation</literal>, the bean is simply published
  185. through a <literal>ProxyFactoryBean</literal> or
  186. <literal>BeanNameAutoProxyCreator</literal> or
  187. <literal>DefaultAdvisorAutoProxyCreator</literal>. Most Spring
  188. developers would already be familiar with these due to their use in
  189. transactions and other areas of Spring.</para>
  190. <para>The second type is an AspectJ <literal>JoinPoint</literal>.
  191. AspectJ has a particular use in securing domain object instances, as
  192. these are most often managed outside the Spring bean container. By
  193. using AspectJ, standard constructs such as <literal>new
  194. Person();</literal> can be used and full security will be applied to
  195. them by Acegi Security. The
  196. <literal>AspectJSecurityInterceptor</literal> is still managed by
  197. Spring, which creates the aspect singleton and wires it with the
  198. appropriate authentication managers, access decision managers and so
  199. on.</para>
  200. <para>The third type is a <literal>FilterInvocation</literal>. This is
  201. an object included with the Acegi Security System for Spring. It is
  202. created by an included filter and simply wraps the HTTP
  203. <literal>ServletRequest</literal>, <literal>ServletResponse</literal>
  204. and <literal>FilterChain</literal>. The
  205. <literal>FilterInvocation</literal> enables HTTP resources to be
  206. secured. Developers do not usually need to understand the mechanics of
  207. how this works, because they just add the filters to their
  208. <literal>web.xml</literal> and let the security system do its
  209. work.</para>
  210. </sect2>
  211. <sect2 id="security-high-level-design-configuration-attributes">
  212. <title>Configuration Attributes</title>
  213. <para>Every secure object can represent an infinite number of
  214. individual requests. For example, a
  215. <literal>MethodInvocation</literal> can represent the invocation of
  216. any method with any arguments, whilst a
  217. <literal>FilterInvocation</literal> can represent any HTTP URL.</para>
  218. <para>The Acegi Security System for Spring needs to record the
  219. configuration that applies to each of these possible requests. The
  220. security configuration of a request to
  221. <literal>BankManager.getBalance(int accountNumber)</literal> needs to
  222. be very different from the security configuration of a request to
  223. <literal>BankManager.approveLoan(int applicationNumber)</literal>.
  224. Similarly, the security configuration of a request to
  225. <literal>http://some.bank.com/index.htm</literal> needs to be very
  226. different from the security configuration of
  227. <literal>http://some.bank.com/manage/timesheet.jsp</literal>.</para>
  228. <para>To store the various security configurations associated with
  229. different requests, a configuration attribute is used. At an
  230. implementation level a configuration attribute is represented by the
  231. <literal>ConfigAttribute</literal> interface. One concrete
  232. implementation of <literal>ConfigAttribute</literal> is provided,
  233. <literal>SecurityConfig</literal>, which simply stores a configuration
  234. attribute as a <literal>String</literal>.</para>
  235. <para>The collection of <literal>ConfigAttribute</literal>s associated
  236. with a particular request is held in a
  237. <literal>ConfigAttributeDefinition</literal>. This concrete class is
  238. simply a holder of <literal>ConfigAttribute</literal>s and does
  239. nothing special.</para>
  240. <para>When a request is received by the security interceptor, it needs
  241. to determine which configuration attributes apply. In other words, it
  242. needs to find the <literal>ConfigAttributeDefinition</literal> which
  243. applies to the request. This decision is handled by the
  244. <literal>ObjectDefinitionSource</literal> interface. The main method
  245. provided by this interface is <literal>public
  246. ConfigAttributeDefinition getAttributes(Object object)</literal>, with
  247. the <literal>Object</literal> being the secure object. Recall the
  248. secure object contains details of the request, so the
  249. <literal>ObjectDefinitionSource</literal> implementation will be able
  250. to extract the details it requires to lookup the relevant
  251. <literal>ConfigAttributeDefinition</literal>.</para>
  252. </sect2>
  253. </sect1>
  254. <sect1 id="security-request-contexts">
  255. <title>Request Contexts</title>
  256. <sect2 id="security-contexts">
  257. <title>Contexts</title>
  258. <para>Many applications require a way of sharing objects between
  259. classes, but without resorting to passing them in method signatures.
  260. This is commonly achieved by using a <literal>ThreadLocal</literal>.
  261. The Acegi Security System for Spring uses
  262. <literal>ThreadLocal</literal> functionality and introduces the
  263. concept of "request contexts".</para>
  264. <para>By placing an object into a request context, that object becomes
  265. available to any other object on the current thread of execution. The
  266. request context is not passed around as a method parameter, but is
  267. held in a <literal>ThreadLocal</literal>. The Acegi Security System
  268. for Spring uses the request context to pass around the authentication
  269. request and response.</para>
  270. <para>A request context is a concrete implementation of the
  271. <literal>Context</literal> interface, which exposes a single
  272. method:</para>
  273. <programlisting>public void validate() throws ContextInvalidException;</programlisting>
  274. <para>This <literal>validate()</literal> method is called to confirm
  275. the <literal>Context</literal> is properly setup. An implementation
  276. will typically use this method to check that the objects it holds are
  277. properly setup.</para>
  278. <para>The <literal>ContextHolder</literal> class makes the
  279. <literal>Context</literal> available to the current thread of
  280. execution using a <literal>ThreadLocal</literal>. A
  281. <literal>ContextInterceptor</literal> is also provided, which is
  282. intended to be chained into the bean context using
  283. <literal>ProxyFactoryBean</literal>. The
  284. <literal>ContextInterceptor</literal> simply calls
  285. <literal>Context.validate()</literal>, which guarantees to business
  286. methods that a valid <literal>Context</literal> is available from the
  287. <literal>ContextHolder</literal>.</para>
  288. </sect2>
  289. <sect2 id="security-contexts-secure-contexts">
  290. <title>Secure Contexts</title>
  291. <para>The Acegi Security System for Spring requires the
  292. <literal>ContextHolder</literal> to contain a request context that
  293. implements the <literal>SecureContext</literal> interface. An
  294. implementation is provided named <literal>SecureContextImpl</literal>.
  295. The <literal>SecureContext</literal> simply extends the
  296. <literal>Context</literal> discussed above and adds a holder and
  297. validation for an <literal>Authentication</literal> object.</para>
  298. </sect2>
  299. <sect2 id="security-contexts-custom-contexts">
  300. <title>Custom Contexts</title>
  301. <para>Developers can create their own request context classes to store
  302. application-specific objects. Such request context classes will need
  303. to implement the <literal>Context</literal> interface. If the Acegi
  304. Security System for Spring is to be used, developers must ensure any
  305. custom request contexts implement the <literal>SecureContext</literal>
  306. interface.</para>
  307. </sect2>
  308. </sect1>
  309. <sect1 id="security-interception">
  310. <title>Security Interception</title>
  311. <sect2 id="security-interception-all-secure-objects">
  312. <title>All Secure Objects</title>
  313. <para>As described in the High Level Design section, each secure
  314. object has its own security interceptor which is responsible for
  315. handling each request. Handling involves a number of
  316. operations:</para>
  317. <orderedlist>
  318. <listitem>
  319. <para>Store the configuration attributes that are associated with
  320. each secure request.</para>
  321. </listitem>
  322. <listitem>
  323. <para>Extract the <literal>ConfigAttributeDefinition</literal>
  324. that applies to the request from the relevant
  325. <literal>ObjectDefinitionSource</literal>.</para>
  326. </listitem>
  327. <listitem>
  328. <para>Obtain the <literal>Authentication</literal> object from the
  329. <literal>SecureContext</literal>, which is held in the
  330. <literal>ContextHolder</literal>.</para>
  331. </listitem>
  332. <listitem>
  333. <para>Pass the <literal>Authentication</literal> object to the
  334. <literal>AuthenticationManager</literal>, update the
  335. <literal>ContextHolder</literal> with the response.</para>
  336. </listitem>
  337. <listitem>
  338. <para>Pass the <literal>Authentication</literal> object, the
  339. <literal>ConfigAttributeDefinition</literal>, and the secure
  340. object to the <literal>AccessDecisionManager</literal>.</para>
  341. </listitem>
  342. <listitem>
  343. <para>Pass the <literal>Authentication</literal> object, the
  344. <literal>ConfigAttributeDefinition</literal>, and the secure
  345. object to the <literal>RunAsManager</literal>.</para>
  346. </listitem>
  347. <listitem>
  348. <para>If the <literal>RunAsManager</literal> returns a new
  349. <literal>Authentication</literal> object, update the
  350. <literal>ContextHolder</literal> with it.</para>
  351. </listitem>
  352. <listitem>
  353. <para>Proceed with the request execution of the secure
  354. object.</para>
  355. </listitem>
  356. <listitem>
  357. <para>If the <literal>RunAsManager</literal> earlier returned a
  358. new <literal>Authentication</literal> object, update the
  359. <literal>ContextHolder</literal> with the
  360. <literal>Authentication</literal> object that was previously
  361. returned by the <literal>AuthenticationManager</literal>.</para>
  362. </listitem>
  363. <listitem>
  364. <para>Return any result received from the secure object
  365. execution.</para>
  366. </listitem>
  367. </orderedlist>
  368. <para>Whilst this may seem quite involved, don't worry. Developers
  369. interact with the security process by simply implementing basic
  370. interfaces (such as <literal>AccessDecisionManager</literal>), which
  371. are fully documented below.</para>
  372. <para>The <literal>AbstractSecurityInterceptor</literal> handles the
  373. majority of the flow listed above. Each secure object has its own
  374. security interceptor which subclasses
  375. <literal>AbstractSecurityInterceptor</literal>. Each of these secure
  376. object-specific security interceptors are discussed below.</para>
  377. </sect2>
  378. <sect2 id="security-interception-aopalliance">
  379. <title>AOP Alliance (MethodInvocation) Security Interceptor</title>
  380. <para>To secure <literal>MethodInvocation</literal>s, developers
  381. simply add a properly configured
  382. <literal>MethodSecurityInterceptor</literal> into the application
  383. context. Next the beans requiring security are chained into the
  384. interceptor. This chaining is accomplished using Spring’s
  385. <literal>ProxyFactoryBean</literal> or
  386. <literal>BeanNameAutoProxyCreator</literal>, as commonly used by many
  387. other parts of Spring (refer to the sample application for examples).
  388. Alternatively, Acegi Security provides a
  389. <literal>MethodDefinitionSourceAdvisor</literal> which may be used
  390. with Spring's <literal>DefaultAdvisorAutoProxyCreator</literal> to
  391. automatically chain the security interceptor in front of any beans
  392. defined against the <literal>MethodSecurityInterceptor</literal>. The
  393. <literal>MethodSecurityInterceptor</literal> itself is configured as
  394. follows:</para>
  395. <para><programlisting>&lt;bean id="bankManagerSecurity" class="net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor"&gt;
  396. &lt;property name="validateConfigAttributes"&gt;&lt;value&gt;true&lt;/value&gt;&lt;/property&gt;
  397. &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
  398. &lt;property name="accessDecisionManager"&gt;&lt;ref bean="accessDecisionManager"/&gt;&lt;/property&gt;
  399. &lt;property name="runAsManager"&gt;&lt;ref bean="runAsManager"/&gt;&lt;/property&gt;
  400. &lt;property name="objectDefinitionSource"&gt;
  401. &lt;value&gt;
  402. net.sf.acegisecurity.context.BankManager.delete*=ROLE_SUPERVISOR,RUN_AS_SERVER
  403. net.sf.acegisecurity.context.BankManager.getBalance=ROLE_TELLER,ROLE_SUPERVISOR,BANKSECURITY_CUSTOMER,RUN_AS_SERVER
  404. &lt;/value&gt;
  405. &lt;/property&gt;
  406. &lt;/bean&gt;</programlisting></para>
  407. <para>As shown above, the <literal>MethodSecurityInterceptor</literal>
  408. is configured with a reference to an
  409. <literal>AuthenticationManager</literal>,
  410. <literal>AccessDecisionManager</literal> and
  411. <literal>RunAsManager</literal>, which are each discussed in separate
  412. sections below. The <literal>MethodSecurityInterceptor</literal> is
  413. also configured with configuration attributes that apply to different
  414. method signatures. A full discussion of configuration attributes is
  415. provided in the High Level Design section of this document.</para>
  416. <para>The <literal>MethodSecurityInterceptor</literal> can be
  417. configured with configuration attributes in three ways. The first is
  418. via a property editor and the application context, which is shown
  419. above. The second is via defining the configuration attributes in your
  420. source code using Jakarta Commons Attributes. The third is via writing
  421. your own <literal>ObjectDefinitionSource</literal>, although this is
  422. beyond the scope of this document. Irrespective of the approach used,
  423. the <literal>ObjectDefinitionSource</literal> is responsible for
  424. returning a <literal>ConfigAttributeDefinition</literal> object that
  425. contains all of the configuration attributes associated with a single
  426. secure method.</para>
  427. <para>It should be noted that the
  428. <literal>MethodSecurityInterceptor.setObjectDefinitionSource()</literal>
  429. method actually expects an instance of
  430. <literal>MethodDefinitionSource</literal>. This is a marker interface
  431. which subclasses <literal>ObjectDefinitionSource</literal>. It simply
  432. denotes the <literal>ObjectDefinitionSource</literal> understands
  433. <literal>MethodInvocation</literal>s. In the interests of simplicity
  434. we'll continue to refer to the
  435. <literal>MethodDefinitionSource</literal> as an
  436. <literal>ObjectDefinitionSource</literal>, as the distinction is of
  437. little relevance to most users of the
  438. <literal>MethodSecurityInterceptor</literal>.</para>
  439. <para>If using the application context property editor approach (as
  440. shown above), commas are used to delimit the different configuration
  441. attributes that apply to a given method pattern. Each configuration
  442. attribute is assigned into its own <literal>SecurityConfig</literal>
  443. object. The <literal>SecurityConfig</literal> object is discussed in
  444. the High Level Design section.</para>
  445. <para>If using the Jakarta Commons Attributes approach, your bean
  446. context will be configured differently:</para>
  447. <para><programlisting>&lt;bean id="attributes" class="org.springframework.metadata.commons.CommonsAttributes"/&gt;
  448. &lt;bean id="objectDefinitionSource" class="net.sf.acegisecurity.intercept.method.MethodDefinitionAttributes"&gt;
  449. &lt;property name="attributes"&gt;&lt;ref local="attributes"/&gt;&lt;/property&gt;
  450. &lt;/bean&gt;
  451. &lt;bean id="bankManagerSecurity" class="net.sf.acegisecurity.intercept.method.MethodSecurityInterceptor"&gt;
  452. &lt;property name="validateConfigAttributes"&gt;&lt;value&gt;false&lt;/value&gt;&lt;/property&gt;
  453. &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
  454. &lt;property name="accessDecisionManager"&gt;&lt;ref bean="accessDecisionManager"/&gt;&lt;/property&gt;
  455. &lt;property name="runAsManager"&gt;&lt;ref bean="runAsManager"/&gt;&lt;/property&gt;
  456. &lt;property name="objectDefinitionSource"&gt;&lt;ref bean="objectDefinitionSource"/&gt;&lt;/property&gt;
  457. &lt;/bean&gt;</programlisting></para>
  458. <para>In addition, your source code will contain Jakarta Commons
  459. Attributes tags that refer to a concrete implementation of
  460. <literal>ConfigAttribute</literal>. The following example uses the
  461. <literal>SecurityConfig</literal> implementation to represent the
  462. configuration attributes, and results in the same security
  463. configuration as provided by the property editor approach
  464. above:</para>
  465. <para><programlisting>public interface BankManager {
  466. /**
  467. * @@SecurityConfig("ROLE_SUPERVISOR")
  468. * @@SecurityConfig("RUN_AS_SERVER")
  469. */
  470. public void deleteSomething(int id);
  471. /**
  472. * @@SecurityConfig("ROLE_SUPERVISOR")
  473. * @@SecurityConfig("RUN_AS_SERVER")
  474. */
  475. public void deleteAnother(int id);
  476. /**
  477. * @@SecurityConfig("ROLE_TELLER")
  478. * @@SecurityConfig("ROLE_SUPERVISOR")
  479. * @@SecurityConfig("BANKSECURITY_CUSTOMER")
  480. * @@SecurityConfig("RUN_AS_SERVER")
  481. */
  482. public float getBalance(int id);
  483. }</programlisting></para>
  484. <para>You might have noticed the
  485. <literal>validateConfigAttributes</literal> property in the above
  486. <literal>MethodSecurityInterceptor</literal> examples. When set to
  487. <literal>true</literal> (the default), at startup time the
  488. <literal>MethodSecurityInterceptor</literal> will evaluate if the
  489. provided configuration attributes are valid. It does this by checking
  490. each configuration attribute can be processed by either the
  491. <literal>AccessDecisionManager</literal> or the
  492. <literal>RunAsManager</literal>. If neither of these can process a
  493. given configuration attribute, an exception is thrown. If using the
  494. Jakarta Commons Attributes method of configuration, you should set
  495. <literal>validateConfigAttributes</literal> to
  496. <literal>false</literal>.</para>
  497. </sect2>
  498. <sect2 id="security-interception-aspectj">
  499. <title>AspectJ (JoinPoint) Security Interceptor</title>
  500. <para>The AspectJ security interceptor is very similar to the AOP
  501. Alliance security interceptor discussed in the previous section.
  502. Indeed we will only discuss the differences in this section.</para>
  503. <para>The AspectJ interceptor is named
  504. <literal>AspectJSecurityInterceptor</literal>. Unlike the AOP Alliance
  505. security interceptor, which relies on the Spring application context
  506. to weave in the security interceptor via proxying, the
  507. <literal>AspectJSecurityInterceptor</literal> is weaved in via the
  508. AspectJ compiler. It would not be uncommon to use both types of
  509. security interceptors in the same application, with
  510. <literal>AspectJSecurityInterceptor</literal> being used for domain
  511. object instance security and the AOP Alliance
  512. <literal>MethodSecurityInterceptor</literal> being used for services
  513. layer security.</para>
  514. <para>Let's first consider how the
  515. <literal>AspectJSecurityInterceptor</literal> is configured in the
  516. Spring application context:</para>
  517. <para><programlisting>&lt;bean id="bankManagerSecurity" class="net.sf.acegisecurity.intercept.method.aspectj.AspectJSecurityInterceptor"&gt;
  518. &lt;property name="validateConfigAttributes"&gt;&lt;value&gt;true&lt;/value&gt;&lt;/property&gt;
  519. &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
  520. &lt;property name="accessDecisionManager"&gt;&lt;ref bean="accessDecisionManager"/&gt;&lt;/property&gt;
  521. &lt;property name="runAsManager"&gt;&lt;ref bean="runAsManager"/&gt;&lt;/property&gt;
  522. &lt;property name="objectDefinitionSource"&gt;
  523. &lt;value&gt;
  524. net.sf.acegisecurity.context.BankManager.delete*=ROLE_SUPERVISOR,RUN_AS_SERVER
  525. net.sf.acegisecurity.context.BankManager.getBalance=ROLE_TELLER,ROLE_SUPERVISOR,BANKSECURITY_CUSTOMER,RUN_AS_SERVER
  526. &lt;/value&gt;
  527. &lt;/property&gt;
  528. &lt;/bean&gt;</programlisting></para>
  529. <para>As you can see, aside from the class name, the
  530. <literal>AspectJSecurityInterceptor</literal> is exactly the same as
  531. the AOP Alliance security interceptor. Indeed the two interceptors can
  532. share the same <literal>objectDefinitionSource</literal>, as the
  533. <literal>ObjectDefinitionSource</literal> works with
  534. <literal>java.lang.reflect.Method</literal>s rather than an AOP
  535. library-specific class. Of course, your access decisions have access
  536. to the relevant AOP library-specific invocation (ie
  537. <literal>MethodInvocation</literal> or <literal>JoinPoint</literal>)
  538. and as such can consider a range of addition criteria when making
  539. access decisions (such as method arguments).</para>
  540. <para>Next you'll need to define an AspectJ <literal>aspect</literal>.
  541. For example:</para>
  542. <para><programlisting>package net.sf.acegisecurity.samples.aspectj;
  543. import net.sf.acegisecurity.intercept.method.aspectj.AspectJSecurityInterceptor;
  544. import net.sf.acegisecurity.intercept.method.aspectj.AspectJCallback;
  545. import org.springframework.beans.factory.InitializingBean;
  546. public aspect DomainObjectInstanceSecurityAspect implements InitializingBean {
  547. private AspectJSecurityInterceptor securityInterceptor;
  548. pointcut domainObjectInstanceExecution(): target(PersistableEntity)
  549. &amp;&amp; execution(public * *(..)) &amp;&amp; !within(DomainObjectInstanceSecurityAspect);
  550. Object around(): domainObjectInstanceExecution() {
  551. if (this.securityInterceptor != null) {
  552. AspectJCallback callback = new AspectJCallback() {
  553. public Object proceedWithObject() {
  554. return proceed();
  555. }
  556. };
  557. return this.securityInterceptor.invoke(thisJoinPoint, callback);
  558. } else {
  559. return proceed();
  560. }
  561. }
  562. public AspectJSecurityInterceptor getSecurityInterceptor() {
  563. return securityInterceptor;
  564. }
  565. public void setSecurityInterceptor(AspectJSecurityInterceptor securityInterceptor) {
  566. this.securityInterceptor = securityInterceptor;
  567. }
  568. public void afterPropertiesSet() throws Exception {
  569. if (this.securityInterceptor == null)
  570. throw new IllegalArgumentException("securityInterceptor required");
  571. }
  572. }</programlisting></para>
  573. <para>In the above example, the security interceptor will be applied
  574. to every instance of <literal>PersistableEntity</literal>, which is an
  575. abstract class not shown (you can use any other class or
  576. <literal>pointcut</literal> expression you like). For those curious,
  577. <literal>AspectJCallback</literal> is needed because the
  578. <literal>proceed();</literal> statement has special meaning only
  579. within an <literal>around()</literal> body. The
  580. <literal>AspectJSecurityInterceptor</literal> calls this anonymous
  581. <literal>AspectJCallback</literal> class when it wants the target
  582. object to continue.</para>
  583. <para>You will need to configure Spring to load the aspect and wire it
  584. with the <literal>AspectJSecurityInterceptor</literal>. A bean
  585. declaration which achieves this is shown below:</para>
  586. <para><programlisting>&lt;bean id="domainObjectInstanceSecurityAspect"
  587. class="net.sf.acegisecurity.samples.aspectj.DomainObjectInstanceSecurityAspect"
  588. factory-method="aspectOf"&gt;
  589. &lt;property name="securityInterceptor"&gt;&lt;ref bean="aspectJSecurityInterceptor"/&gt;&lt;/property&gt;
  590. &lt;/bean&gt;</programlisting></para>
  591. <para>That's it! Now you can create your beans from anywhere within
  592. your application, using whatever means you think fit (eg <literal>new
  593. Person();</literal>) and they will have the security interceptor
  594. applied.</para>
  595. </sect2>
  596. <sect2 id="security-interception-filterinvocation">
  597. <title>FilterInvocation Security Interceptor</title>
  598. <para>To secure <literal>FilterInvocation</literal>s, developers need
  599. to add a filter to their <literal>web.xml</literal> that delegates to
  600. the <literal>SecurityEnforcementFilter</literal>. A typical
  601. configuration example is provided below: <programlisting>&lt;filter&gt;
  602. &lt;filter-name&gt;Acegi HTTP Request Security Filter&lt;/filter-name&gt;
  603. &lt;filter-class&gt;net.sf.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
  604. &lt;init-param&gt;
  605. &lt;param-name&gt;targetClass&lt;/param-name&gt;
  606. &lt;param-value&gt;net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter&lt;/param-value&gt;
  607. &lt;/init-param&gt;
  608. &lt;/filter&gt;
  609. &lt;filter-mapping&gt;
  610. &lt;filter-name&gt;Acegi HTTP Request Security Filter&lt;/filter-name&gt;
  611. &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
  612. &lt;/filter-mapping&gt;</programlisting></para>
  613. <para>Notice that the filter is actually a
  614. <literal>FilterToBeanProxy</literal>. Most of the filters used by the
  615. Acegi Security System for Spring use this class. Refer to the Filters
  616. section to learn more about this bean.</para>
  617. <para>In the application context you will need to configure three
  618. beans:</para>
  619. <programlisting>&lt;bean id="securityEnforcementFilter" class="net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter"&gt;
  620. &lt;property name="filterSecurityInterceptor"&gt;&lt;ref bean="filterInvocationInterceptor"/&gt;&lt;/property&gt;
  621. &lt;property name="authenticationEntryPoint"&gt;&lt;ref bean="authenticationEntryPoint"/&gt;&lt;/property&gt;
  622. &lt;/bean&gt;
  623. &lt;bean id="authenticationEntryPoint" class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint"&gt;
  624. &lt;property name="loginFormUrl"&gt;&lt;value&gt;/acegilogin.jsp&lt;/value&gt;&lt;/property&gt;
  625. &lt;property name="forceHttps"&gt;&lt;value&gt;false&lt;/value&gt;&lt;/property&gt;
  626. &lt;/bean&gt;
  627. &lt;bean id="filterInvocationInterceptor" class="net.sf.acegisecurity.intercept.web.FilterSecurityInterceptor"&gt;
  628. &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
  629. &lt;property name="accessDecisionManager"&gt;&lt;ref bean="accessDecisionManager"/&gt;&lt;/property&gt;
  630. &lt;property name="runAsManager"&gt;&lt;ref bean="runAsManager"/&gt;&lt;/property&gt;
  631. &lt;property name="objectDefinitionSource"&gt;
  632. &lt;value&gt;
  633. CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
  634. \A/secure/super/.*\Z=ROLE_WE_DONT_HAVE
  635. \A/secure/.*\Z=ROLE_SUPERVISOR,ROLE_TELLER
  636. &lt;/value&gt;
  637. &lt;/property&gt;
  638. &lt;/bean&gt;</programlisting>
  639. <para>The <literal>AuthenticationEntryPoint</literal> will be called
  640. if the user requests a secure HTTP resource but they are not
  641. authenticated. The class handles presenting the appropriate response
  642. to the user so that authentication can begin. Three concrete
  643. implementations are provided with the Acegi Security System for
  644. Spring: <literal>AuthenticationProcessingFilterEntryPoint</literal>
  645. for commencing a form-based authentication,
  646. <literal>BasicProcessingFilterEntryPoint</literal> for commencing a
  647. Http Basic authentication process, and
  648. <literal>CasProcessingFilterEntryPoint</literal> for commencing a Yale
  649. Central Authentication Service (CAS) login. The
  650. <literal>AuthenticationProcessingFilterEntryPoint</literal> and
  651. <literal>CasProcessingFilterEntryPoint</literal> have optional
  652. properties related to forcing the use of HTTPS, so please refer to the
  653. JavaDocs if you require this.</para>
  654. <para>The <literal>PortMapper</literal> provides information on which
  655. HTTPS ports correspond to which HTTP ports. This is used by the
  656. <literal>AuthenticationProcessingFilterEntryPoint</literal> and
  657. several other beans. The default implementation,
  658. <literal>PortMapperImpl</literal>, knows the common HTTP ports 80 and
  659. 8080 map to HTTPS ports 443 and 8443 respectively. You can customise
  660. this mapping if desired.</para>
  661. <para>The <literal>SecurityEnforcementFilter</literal> primarily
  662. provides session management support and initiates authentication when
  663. required. It delegates actual <literal>FilterInvocation</literal>
  664. security decisions to the configured
  665. <literal>FilterSecurityInterceptor</literal>.</para>
  666. <para>Like any other security interceptor, the
  667. <literal>FilterSecurityInterceptor</literal> requires a reference to
  668. an <literal>AuthenticationManager</literal>,
  669. <literal>AccessDecisionManager</literal> and
  670. <literal>RunAsManager</literal>, which are each discussed in separate
  671. sections below. The <literal>FilterSecurityInterceptor</literal> is
  672. also configured with configuration attributes that apply to different
  673. HTTP URL requests. A full discussion of configuration attributes is
  674. provided in the High Level Design section of this document.</para>
  675. <para>The <literal>FilterSecurityInterceptor</literal> can be
  676. configured with configuration attributes in two ways. The first is via
  677. a property editor and the application context, which is shown above.
  678. The second is via writing your own
  679. <literal>ObjectDefinitionSource</literal>, although this is beyond the
  680. scope of this document. Irrespective of the approach used, the
  681. <literal>ObjectDefinitionSource</literal> is responsible for returning
  682. a <literal>ConfigAttributeDefinition</literal> object that contains
  683. all of the configuration attributes associated with a single secure
  684. HTTP URL.</para>
  685. <para>It should be noted that the
  686. <literal>FilterSecurityInterceptor.setObjectDefinitionSource()</literal>
  687. method actually expects an instance of
  688. <literal>FilterInvocationDefinitionSource</literal>. This is a marker
  689. interface which subclasses <literal>ObjectDefinitionSource</literal>.
  690. It simply denotes the <literal>ObjectDefinitionSource</literal>
  691. understands <literal>FilterInvocation</literal>s. In the interests of
  692. simplicity we'll continue to refer to the
  693. <literal>FilterInvocationDefinitionSource</literal> as an
  694. <literal>ObjectDefinitionSource</literal>, as the distinction is of
  695. little relevance to most users of the
  696. <literal>FilterSecurityInterceptor</literal>.</para>
  697. <para>If using the application context property editor approach (as
  698. shown above), commas are used to delimit the different configuration
  699. attributes that apply to each HTTP URL. Each configuration attribute
  700. is assigned into its own <literal>SecurityConfig</literal> object. The
  701. <literal>SecurityConfig</literal> object is discussed in the High
  702. Level Design section. The <literal>ObjectDefinitionSource</literal>
  703. created by the property editor,
  704. <literal>FilterInvocationDefinitionSource</literal>, matches
  705. configuration attributes against <literal>FilterInvocations</literal>
  706. based on expression evaluation of the request URL. Two standard
  707. expression syntaxes are supported. The default is to treat all
  708. expressions as regular expressions. Alternatively, the presence of a
  709. <literal>PATTERN_TYPE_APACHE_ANT</literal> directive will cause all
  710. expressions to be treated as Apache Ant paths. It is not possible to
  711. mix expression syntaxes within the same definition. For example, the
  712. earlier configuration could be generated using Apache Ant paths as
  713. follows:</para>
  714. <para><programlisting>&lt;bean id="filterInvocationInterceptor" class="net.sf.acegisecurity.intercept.web.FilterSecurityInterceptor"&gt;
  715. &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
  716. &lt;property name="accessDecisionManager"&gt;&lt;ref bean="accessDecisionManager"/&gt;&lt;/property&gt;
  717. &lt;property name="runAsManager"&gt;&lt;ref bean="runAsManager"/&gt;&lt;/property&gt;
  718. &lt;property name="objectDefinitionSource"&gt;
  719. &lt;value&gt;
  720. CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
  721. PATTERN_TYPE_APACHE_ANT
  722. /secure/super/**=ROLE_WE_DONT_HAVE
  723. /secure/**=ROLE_SUPERVISOR,ROLE_TELLER
  724. &lt;/value&gt;
  725. &lt;/property&gt;
  726. &lt;/bean&gt;</programlisting></para>
  727. <para>Irrespective of the type of expression syntax used, expressions
  728. are always evaluated in the order they are defined. Thus it is
  729. important that more specific expressions are defined higher in the
  730. list than less specific expressions. This is reflected in our example
  731. above, where the more specific <literal>/secure/super/</literal>
  732. pattern appears higher than the less specific
  733. <literal>/secure/</literal> pattern. If they were reversed, the
  734. <literal>/secure/</literal> pattern would always match and the
  735. <literal>/secure/super/</literal> pattern would never be
  736. evaluated.</para>
  737. <para>The special keyword
  738. <literal>CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON</literal> causes
  739. the <literal>FilterInvocationDefinitionSource</literal> to
  740. automatically convert a request URL to lowercase before comparison
  741. against the expressions. Whilst by default the case of the request URL
  742. is not converted, it is generally recommended to use
  743. <literal>CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON</literal> and
  744. write each expression assuming lowercase.</para>
  745. <para>As with other security interceptors, the
  746. <literal>validateConfigAttributes</literal> property is observed. When
  747. set to <literal>true</literal> (the default), at startup time the
  748. <literal>FilterSecurityInterceptor</literal> will evaluate if the
  749. provided configuration attributes are valid. It does this by checking
  750. each configuration attribute can be processed by either the
  751. <literal>AccessDecisionManager</literal> or the
  752. <literal>RunAsManager</literal>. If neither of these can process a
  753. given configuration attribute, an exception is thrown.</para>
  754. </sect2>
  755. </sect1>
  756. <sect1 id="security-authentication">
  757. <title>Authentication</title>
  758. <sect2 id="security-authentication-requests">
  759. <title>Authentication Requests</title>
  760. <para>Authentication requires a way for client code to present its
  761. security identification to the Acegi Security System for Spring. This
  762. is the role of the <literal>Authentication</literal> interface. The
  763. <literal>Authentication</literal> interface holds three important
  764. objects: the principal (the identity of the caller), the credentials
  765. (the proof of the identity of the caller, such as a password), and the
  766. authorities that have been granted to the principal. The principal and
  767. its credentials are populated by the client code, whilst the granted
  768. authorities are populated by the
  769. <literal>AuthenticationManager</literal>. The Acegi Security System
  770. for Spring includes several concrete <literal>Authentication</literal>
  771. implementations:</para>
  772. <itemizedlist spacing="compact">
  773. <listitem>
  774. <para><literal>UsernamePasswordAuthenticationToken</literal>
  775. allows a username and password to be presented as the principal
  776. and credentials respectively. It is also what is created by the
  777. HTTP Session Authentication system.</para>
  778. </listitem>
  779. <listitem>
  780. <para><literal>TestingAuthenticationToken</literal> facilitates
  781. unit testing by automatically being considered an authenticated
  782. object by its associated
  783. <literal>AuthenticationProvider</literal>.</para>
  784. </listitem>
  785. <listitem>
  786. <para><literal>RunAsUserToken</literal> is used by the default
  787. run-as authentication replacement implementation. This is
  788. discussed further in the Run-As Authentication Replacement
  789. section.</para>
  790. </listitem>
  791. <listitem>
  792. <para><literal>CasAuthenticationToken</literal> is used to
  793. represent a successful Yale Central Authentication Service (CAS)
  794. authentication. This is discussed further in the CAS
  795. section.</para>
  796. </listitem>
  797. <listitem>
  798. <para><literal>PrincipalAcegiUserToken</literal> and
  799. <literal>JettyAcegiUserToken</literal> implement
  800. <literal>AuthByAdapter</literal> (a subclass of
  801. <literal>Authentication</literal>) and are used whenever
  802. authentication is completed by Acegi Security System for Spring
  803. container adapters. This is discussed further in the Container
  804. Adapters section.</para>
  805. </listitem>
  806. </itemizedlist>
  807. <para>The authorities granted to a principal are represented by the
  808. <literal>GrantedAuthority</literal> interface. The
  809. <literal>GrantedAuthority</literal> interface is discussed at length
  810. in the Authorization section.</para>
  811. </sect2>
  812. <sect2 id="security-authentication-manager">
  813. <title>Authentication Manager</title>
  814. <para>As discussed in the Security Interception section, the
  815. <literal>AbstractSecurityInterceptor</literal> extracts the
  816. <literal>Authentication</literal> object from the
  817. <literal>SecureContext</literal> in the
  818. <literal>ContextHolder</literal>. This is then passed to an
  819. <literal>AuthenticationManager</literal>. The
  820. <literal>AuthenticationManager</literal> interface is very
  821. simple:</para>
  822. <programlisting>public Authentication authenticate(Authentication authentication) throws AuthenticationException;</programlisting>
  823. <para>Implementations of <literal>AuthenticationManager</literal> are
  824. required to throw an <literal>AuthenticationException</literal> should
  825. authentication fail, or return a fully populated
  826. <literal>Authentication</literal> object. In particular, the returned
  827. <literal>Authentication</literal> object should contain an array of
  828. <literal>GrantedAuthority</literal> objects. The
  829. <literal>SecurityInterceptor</literal> places the populated
  830. <literal>Authentication</literal> object back in the
  831. <literal>SecureContext</literal> in the
  832. <literal>ContextHolder</literal>, overwriting the original
  833. <literal>Authentication</literal> object.</para>
  834. <para>The <literal>AuthenticationException</literal> has a number of
  835. subclasses. The most important are
  836. <literal>BadCredentialsException</literal> (an incorrect principal or
  837. credentials), <literal>DisabledException</literal> and
  838. <literal>LockedException</literal>. The latter two exceptions indicate
  839. the principal was found, but the credentials were not checked and
  840. authentication is denied. An
  841. <literal>AuthenticationServiceException</literal> is also provided,
  842. which indicates the authentication system could not process the
  843. request (eg a database was unavailable).</para>
  844. </sect2>
  845. <sect2 id="security-authentication-provider">
  846. <title>Provider-Based Authentication</title>
  847. <para>Whilst the basic <literal>Authentication</literal> and
  848. <literal>AuthenticationManager</literal> interfaces enable users to
  849. develop their own authentication systems, users should consider using
  850. the provider-based authentication packages provided by the Acegi
  851. Security System for Spring. The key class,
  852. <literal>ProviderManager</literal>, is configured via the bean context
  853. with a list of <literal>AuthenticationProvider</literal>s:</para>
  854. <para><programlisting>&lt;bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager"&gt;
  855. &lt;property name="providers"&gt;
  856. &lt;list&gt;
  857. &lt;ref bean="daoAuthenticationProvider"/&gt;
  858. &lt;ref bean="someOtherAuthenticationProvider"/&gt;
  859. &lt;/list&gt;
  860. &lt;/property&gt;
  861. &lt;/bean&gt;</programlisting></para>
  862. <para><literal>ProviderManager</literal> calls a series of registered
  863. <literal>AuthenticationProvider</literal> implementations, until one
  864. is found that indicates it is able to authenticate a given
  865. <literal>Authentication</literal> class. When the first compatible
  866. <literal>AuthenticationProvider</literal> is located, it is passed the
  867. authentication request. The <literal>AuthenticationProvider</literal>
  868. will then either throw an <literal>AuthenticationException</literal>
  869. or return a fully populated <literal>Authentication</literal>
  870. object.</para>
  871. <para>Note the <literal>ProviderManager</literal> may throw a
  872. <literal>ProviderNotFoundException</literal> (a subclass of
  873. <literal>AuthenticationException</literal>) if it none of the
  874. registered <literal>AuthenticationProviders</literal> can validate the
  875. <literal>Authentication</literal> object.</para>
  876. <para>Several <literal>AuthenticationProvider</literal>
  877. implementations are provided with the Acegi Security System for
  878. Spring:</para>
  879. <para><itemizedlist spacing="compact">
  880. <listitem>
  881. <para><literal>TestingAuthenticationProvider</literal> is able
  882. to authenticate a <literal>TestingAuthenticationToken</literal>.
  883. The limit of its authentication is simply to treat whatever is
  884. contained in the <literal>TestingAuthenticationToken</literal>
  885. as valid. This makes it ideal for use during unit testing, as
  886. you can create an <literal>Authentication</literal> object with
  887. precisely the <literal>GrantedAuthority</literal> objects
  888. required for calling a given method. You definitely would not
  889. register this <literal>AuthenticationProvider</literal> on a
  890. production system.</para>
  891. </listitem>
  892. <listitem>
  893. <para><literal>DaoAuthenticationProvider</literal> is able to
  894. authenticate a
  895. <literal>UsernamePasswordAuthenticationToken</literal> by
  896. accessing an authentication respository via a data access
  897. object. This is discussed further below, as it is the main way
  898. authentication is initially handled.</para>
  899. </listitem>
  900. <listitem>
  901. <para><literal>RunAsImplAuthenticationToken</literal> is able to
  902. authenticate a <literal>RunAsUserToken</literal>. This is
  903. discussed further in the Run-As Authentication Replacement
  904. section. You would not register this
  905. <literal>AuthenticationProvider</literal> if you were not using
  906. run-as replacement.</para>
  907. </listitem>
  908. <listitem>
  909. <para><literal>AuthByAdapterProvider</literal> is able to
  910. authenticate any <literal>AuthByAdapter</literal> (a subclass of
  911. <literal>Authentication</literal> used with container adapters).
  912. This is discussed further in the Container Adapters section. You
  913. would not register this
  914. <literal>AuthenticationProvider</literal> if you were not using
  915. container adapters.</para>
  916. </listitem>
  917. <listitem>
  918. <para><literal>CasAuthenticationProvider</literal> is able to
  919. authenticate Yale Central Authentication Service (CAS) tickets.
  920. This is discussed further in the CAS Single Sign On
  921. section.</para>
  922. </listitem>
  923. <listitem>
  924. <para><literal>JaasAuthenticationProvider</literal> is able to
  925. delegate authentication requests to a JAAS
  926. <literal>LoginModule</literal>. This is discussed further
  927. below.</para>
  928. </listitem>
  929. </itemizedlist></para>
  930. </sect2>
  931. <sect2 id="security-authentication-provider-dao">
  932. <title>Data Access Object Authentication Provider</title>
  933. <para>The Acegi Security System for Spring includes a
  934. production-quality <literal>AuthenticationProvider</literal>
  935. implementation called <literal>DaoAuthenticationProvider</literal>.
  936. This authentication provider is able to authenticate a
  937. <literal>UsernamePasswordAuthenticationToken</literal> by obtaining
  938. authentication details from a data access object configured at bean
  939. creation time:</para>
  940. <para><programlisting>&lt;bean id="daoAuthenticationProvider" class="net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider"&gt;
  941. &lt;property name="authenticationDao"&gt;&lt;ref bean="inMemoryDaoImpl"/&gt;&lt;/property&gt;
  942. &lt;property name="saltSource"&gt;&lt;ref bean="saltSource"/&gt;&lt;/property&gt;
  943. &lt;property name="passwordEncoder"&gt;&lt;ref bean="passwordEncoder"/&gt;&lt;/property&gt;
  944. &lt;/bean&gt;</programlisting></para>
  945. <para>The <literal>PasswordEncoder</literal> and
  946. <literal>SaltSource</literal> are optional. A
  947. <literal>PasswordEncoder</literal> provides encoding and decoding of
  948. passwords obtained from the authentication repository. A
  949. <literal>SaltSource</literal> enables the passwords to be populated
  950. with a "salt", which enhances the security of the passwords in the
  951. authentication repository. <literal>PasswordEncoder</literal>
  952. implementations are provided with the Acegi Security System for Spring
  953. covering MD5, SHA and cleartext encodings. Two
  954. <literal>SaltSource</literal> implementations are also provided:
  955. <literal>SystemWideSaltSource</literal> which encodes all passwords
  956. with the same salt, and <literal>ReflectionSaltSource</literal>, which
  957. inspects a given property of the returned
  958. <literal>UserDetails</literal> object to obtain the salt. Please refer
  959. to the JavaDocs for further details on these optional features.</para>
  960. <para>In addition to the properties above, the
  961. <literal>DaoAuthenticationProvider</literal> supports optional caching
  962. of <literal>UserDetails</literal> objects. The
  963. <literal>UserCache</literal> interface enables the
  964. <literal>DaoAuthenticationProvider</literal> to place a
  965. <literal>UserDetails</literal> object into the cache, and retrieve it
  966. from the cache upon subsequent authentication attempts for the same
  967. username. By default the <literal>DaoAuthenticationProvider</literal>
  968. uses the <literal>NullUserCache</literal>, which performs no caching.
  969. A usable caching implementation is also provided,
  970. <literal>EhCacheBasedUserCache</literal>, which is configured as
  971. follows:</para>
  972. <para><programlisting>&lt;bean id="daoAuthenticationProvider" class="net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider"&gt;
  973. &lt;property name="authenticationDao"&gt;&lt;ref bean="authenticationDao"/&gt;&lt;/property&gt;
  974. &lt;property name="userCache"&gt;&lt;ref bean="userCache"/&gt;&lt;/property&gt;
  975. &lt;/bean&gt;
  976. &lt;bean id="userCache" class="net.sf.acegisecurity.providers.dao.cache.EhCacheBasedUserCache"&gt;
  977. &lt;property name="minutesToIdle"&gt;&lt;value&gt;5&lt;/value&gt;&lt;/property&gt;
  978. &lt;/bean&gt;</programlisting></para>
  979. <para>For a class to be able to provide the
  980. <literal>DaoAuthenticationProvider</literal> with access to an
  981. authentication repository, it must implement the
  982. <literal>AuthenticationDao</literal> interface:</para>
  983. <para><programlisting>public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException;</programlisting></para>
  984. <para>The <literal>UserDetails</literal> is an interface that provides
  985. getters that guarantee non-null provision of basic authentication
  986. information such as the username, password, granted authorities and
  987. whether the user is enabled or disabled. A concrete implementation,
  988. <literal>User</literal>, is also provided. Acegi Security users will
  989. need to decide when writing their <literal>AuthenticationDao</literal>
  990. what type of <literal>UserDetails</literal> to return. In most cases
  991. <literal>User</literal> will be used directly or subclassed, although
  992. special circumstances (such as object relational mappers) may require
  993. users to write their own <literal>UserDetails</literal> implementation
  994. from scratch.</para>
  995. <para>Given <literal>AuthenticationDao</literal> is so simple to
  996. implement, it should be easy for users to retrieve authentication
  997. information using a persistence strategy of their choice.</para>
  998. <para>A design decision was made not to support account locking in the
  999. <literal>DaoAuthenticationProvider</literal>, as doing so would have
  1000. increased the complexity of the <literal>AuthenticationDao</literal>
  1001. interface. For instance, a method would be required to increase the
  1002. count of unsuccessful authentication attempts. Such functionality
  1003. could be easily provided by leveraging the application event
  1004. publishing features discussed below.</para>
  1005. <para><literal>DaoAuthenticationProvider</literal> returns an
  1006. <literal>Authentication</literal> object which in turn has its
  1007. <literal>principal</literal> property set. The principal will be
  1008. either a <literal>String</literal> (which is essentially the username)
  1009. or a <literal>UserDetails</literal> object (which was looked up from
  1010. the <literal>AuthenticationDao</literal>). By default the
  1011. <literal>UserDetails</literal> is returned, as this enables
  1012. applications to add extra properties potentially of use in
  1013. applications, such as the user's full name, email address etc. If
  1014. using container adapters, or if your applications were written to
  1015. operate with <literal>String</literal>s (as was the case for releases
  1016. prior to Acegi Security 0.6), you should set the
  1017. <literal>DaoAuthenticationProvider.forcePrincipalAsString</literal>
  1018. property to <literal>true</literal> in your application
  1019. context.</para>
  1020. </sect2>
  1021. <sect2 id="security-authentication-provider-events">
  1022. <title>Event Publishing</title>
  1023. <para>The <literal>DaoAuthenticationProvider</literal> automatically
  1024. obtains the <literal>ApplicationContext</literal> it is running in at
  1025. startup time. This allows the provider to publish events through the
  1026. standard Spring event framework. Three types of event messages are
  1027. published:</para>
  1028. <itemizedlist spacing="compact">
  1029. <listitem>
  1030. <para><literal>AuthenticationSuccessEvent</literal> is published
  1031. when an authentication request is successful.</para>
  1032. </listitem>
  1033. <listitem>
  1034. <para><literal>AuthenticationFailureDisabledEvent</literal> is
  1035. published when an authentication request is unsuccessful because
  1036. the returned <literal>UserDetails</literal> is disabled. This is
  1037. normally the case when an account is locked.</para>
  1038. </listitem>
  1039. <listitem>
  1040. <para><literal>AuthenticationFailureUsernameNotFoundEvent</literal>
  1041. is published when an authentication request is unsuccessful
  1042. because the <literal>AuthenticationDao</literal> could not locate
  1043. the <literal>UserDetails</literal>.</para>
  1044. </listitem>
  1045. <listitem>
  1046. <para><literal>AuthenticationFailurePasswordEvent</literal> is
  1047. published when an authentication request is unsuccessful because
  1048. the presented password did not match that in the
  1049. <literal>UserDetails</literal>.</para>
  1050. </listitem>
  1051. </itemizedlist>
  1052. <para>Each event contains two objects: the
  1053. <literal>Authentication</literal> object that represented the
  1054. authentication request, and the <literal>UserDetails</literal> object
  1055. that was found in response to the authentication request (clearly the
  1056. latter will be a dummy object in the case of
  1057. <literal>AuthenticationFailureUsernameNotFoundEvent</literal>). The
  1058. <literal>Authentication</literal> interface provides a
  1059. <literal>getDetails()</literal> method which often includes
  1060. information that event consumers may find useful (eg the TCP/IP
  1061. address that the authentication request originated from).</para>
  1062. <para>As per standard Spring event handling, you can receive these
  1063. events by adding a bean to the application context which implements
  1064. the <literal>ApplicationListener</literal> interface. Included with
  1065. Acegi Security is a <literal>LoggerListener</literal> class which
  1066. receives these events and publishes their details to Commons Logging.
  1067. Refer to the JavaDocs for <literal>LoggerListener</literal> for
  1068. details on the logging priorities used for different message
  1069. types.</para>
  1070. <para>This event publishing system enables you to implement account
  1071. locking and record authentication event history. This might be of
  1072. interest to application users, who can be advised of the times and
  1073. source IP address of all unsuccessful password attempts (and account
  1074. lockouts) since their last successful login. Such capabilities are
  1075. simple to implement and greatly improve the security of your
  1076. application.</para>
  1077. </sect2>
  1078. <sect2 id="security-authentication-provider-in-memory">
  1079. <title>In-Memory Authentication</title>
  1080. <para>Whilst it is easy to use the
  1081. <literal>DaoAuthenticationProvider</literal> and create a custom
  1082. <literal>AuthenticationDao</literal> implementation that extracts
  1083. information from a persistence engine of choice, many applications do
  1084. not require such complexity. One alternative is to configure an
  1085. authentication repository in the application context itself using the
  1086. <literal>InMemoryDaoImpl</literal>:</para>
  1087. <para><programlisting>&lt;bean id="inMemoryDaoImpl" class="net.sf.acegisecurity.providers.dao.memory.InMemoryDaoImpl"&gt;
  1088. &lt;property name="userMap"&gt;
  1089. &lt;value&gt;
  1090. marissa=koala,ROLE_TELLER,ROLE_SUPERVISOR
  1091. dianne=emu,ROLE_TELLER
  1092. scott=wombat,ROLE_TELLER
  1093. peter=opal,disabled,ROLE_TELLER
  1094. &lt;/value&gt;
  1095. &lt;/property&gt;
  1096. &lt;/bean&gt;</programlisting></para>
  1097. <para>The <literal>userMap</literal> property contains each of the
  1098. usernames, passwords, a list of granted authorities and an optional
  1099. enabled/disabled keyword. Commas delimit each token. The username must
  1100. appear to the left of the equals sign, and the password must be the
  1101. first token to the right of the equals sign. The
  1102. <literal>enabled</literal> and <literal>disabled</literal> keywords
  1103. (case insensitive) may appear in the second or any subsequent token.
  1104. Any remaining tokens are treated as granted authorities, which are
  1105. created as <literal>GrantedAuthorityImpl</literal> objects (refer to
  1106. the Authorization section for further discussion on granted
  1107. authorities). Note that if a user has no password and/or no granted
  1108. authorities, the user will not be created in the in-memory
  1109. authentication repository.</para>
  1110. </sect2>
  1111. <sect2 id="security-authentication-provider-jdbc">
  1112. <title>JDBC Authentication</title>
  1113. <para>The Acegi Security System for Spring also includes an
  1114. authentication provider that can obtain authentication information
  1115. from a JDBC data source. The typical configuration for the
  1116. <literal>JdbcDaoImpl</literal> is shown below:</para>
  1117. <para><programlisting>&lt;bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"&gt;
  1118. &lt;property name="driverClassName"&gt;&lt;value&gt;org.hsqldb.jdbcDriver&lt;/value&gt;&lt;/property&gt;
  1119. &lt;property name="url"&gt;&lt;value&gt;jdbc:hsqldb:hsql://localhost:9001&lt;/value&gt;&lt;/property&gt;
  1120. &lt;property name="username"&gt;&lt;value&gt;sa&lt;/value&gt;&lt;/property&gt;
  1121. &lt;property name="password"&gt;&lt;value&gt;&lt;/value&gt;&lt;/property&gt;
  1122. &lt;/bean&gt;
  1123. &lt;bean id="jdbcDaoImpl" class="net.sf.acegisecurity.providers.dao.jdbc.JdbcDaoImpl"&gt;
  1124. &lt;property name="dataSource"&gt;&lt;ref bean="dataSource"/&gt;&lt;/property&gt;
  1125. &lt;/bean&gt;</programlisting></para>
  1126. <para>You can use different relational database management systems by
  1127. modifying the <literal>DriverManagerDataSource</literal> shown above.
  1128. Irrespective of the database used, a standard schema must be used as
  1129. indicated in <literal>dbinit.txt</literal>.</para>
  1130. <para>If you default schema is unsuitable for your needs,
  1131. <literal>JdbcDaoImpl</literal> provides two properties that allow
  1132. customisation of the SQL statements. You may also subclass the
  1133. <literal>JdbcDaoImpl</literal> if further customisation is necessary.
  1134. Please refer to the JavaDocs for details.</para>
  1135. <para>The Acegi Security System for Spring ships with a Hypersonic SQL
  1136. instance that has the required authentication information and sample
  1137. data already populated. To use this server, simply execute the
  1138. <literal>server.bat</literal> or <literal>server.sh</literal> script
  1139. included in the distribution. This will load a new database server
  1140. instance that will service requests made to the URL indicated in the
  1141. bean context configuration shown above.</para>
  1142. </sect2>
  1143. <sect2 id="security-authentication-provider-jaas">
  1144. <title>JAAS Authentication</title>
  1145. <para>Acegi Security provides a package able to delegate
  1146. authentication requests to the Java Authentication and Authorization
  1147. Service (JAAS). This package is discussed in detail below.</para>
  1148. <para>Central to JAAS operation are login configuration files. To
  1149. learn more about JAAS login configuration files, consult the JAAS
  1150. reference documentation available from Sun Microsystems. We expect you
  1151. to have a basic understanding of JAAS and its login configuration file
  1152. syntax in order to understand this section.</para>
  1153. <sect3>
  1154. <title>JaasAuthenticationProvider</title>
  1155. <para>The <literal>JaasAuthenticationProvider</literal> attempts to
  1156. authenticate a user’s principal and credentials through JAAS.</para>
  1157. <para>Let’s assume we have a JAAS login configuration file,
  1158. <literal>/WEB-INF/login.conf</literal>, with the following
  1159. contents:</para>
  1160. <para><programlisting>JAASTest {
  1161. sample.SampleLoginModule required;
  1162. };</programlisting></para>
  1163. <para>Like all Acegi Security beans, the
  1164. <literal>JaasAuthenticationProvider</literal> is configured via the
  1165. application context. The following definitions would correspond to
  1166. the above JAAS login configuration file:</para>
  1167. <para><programlisting>&lt;bean id="jaasAuthenticationProvider" class="net.sf.acegisecurity.providers.jaas.JaasAuthenticationProvider"&gt;
  1168. &lt;property name="loginConfig"&gt;
  1169. &lt;value&gt;/WEB-INF/login.conf&lt;/value&gt;
  1170. &lt;/property&gt;
  1171. &lt;property name="loginContextName"&gt;
  1172. &lt;value&gt;JAASTest&lt;/value&gt;
  1173. &lt;/property&gt;
  1174. &lt;property name="callbackHandlers"&gt;
  1175. &lt;list&gt;
  1176. &lt;bean class="net.sf.acegisecurity.providers.jaas.JaasNameCallbackHandler"/&gt;
  1177. &lt;bean class="net.sf.acegisecurity.providers.jaas.JaasPasswordCallbackHandler"/&gt;
  1178. &lt;/list&gt;
  1179. &lt;/property&gt;
  1180. &lt;property name="authorityGranters"&gt;
  1181. &lt;list&gt;
  1182. &lt;bean class="net.sf.acegisecurity.providers.jaas.TestAuthorityGranter"/&gt;
  1183. &lt;/list&gt;
  1184. &lt;/property&gt;
  1185. &lt;/bean&gt;</programlisting></para>
  1186. <para>The <literal>CallbackHandler</literal>s and
  1187. <literal>AuthorityGranter</literal>s are discussed below.</para>
  1188. </sect3>
  1189. <sect3>
  1190. <title>Callbacks</title>
  1191. <para>Most JAAS <literal>LoginModule</literal>s require a callback
  1192. of some sort. These callbacks are usually used to obtain the
  1193. username and password from the user. In an Acegi Security
  1194. deployment, Acegi Security is responsible for this user interaction
  1195. (typically via a reference to a
  1196. <literal>ContextHolder</literal>-managed
  1197. <literal>Authentication</literal> object). The JAAS package for
  1198. Acegi Security provides two default callback handlers,
  1199. <literal>JaasNameCallbackHandler</literal> and
  1200. <literal>JaasPasswordCallbackHandler</literal>. Each of these
  1201. callback handlers implement
  1202. <literal>JaasAuthenticationCallbackHandler</literal>. In most cases
  1203. these callback handlers can simply be used without understanding the
  1204. internal mechanics. For those needing full control over the callback
  1205. behavior, internally <literal>JaasAutheticationProvider</literal>
  1206. wraps these <literal>JaasAuthenticationCallbackHandler</literal>s
  1207. with an <literal>InternalCallbackHandler</literal>. The
  1208. <literal>InternalCallbackHandler</literal> is the class that
  1209. actually implements JAAS’ normal <literal>CallbackHandler</literal>
  1210. interface. Any time that the JAAS <literal>LoginModule</literal> is
  1211. used, it is passed a list of application context configured
  1212. <literal>InternalCallbackHandler</literal>s. If the
  1213. <literal>LoginModule</literal> requests a callback against the
  1214. <literal>InternalCallbackHandler</literal>s, the callback is in-turn
  1215. passed to the <literal>JaasAuthenticationCallbackHandler</literal>s
  1216. being wrapped.</para>
  1217. </sect3>
  1218. <sect3>
  1219. <title>AuthorityGranters</title>
  1220. <para>JAAS works with principals. Even “roles” are represented as
  1221. principals in JAAS. Acegi Security, on the other hand, works with
  1222. <literal>Authentication</literal> objects. Each
  1223. <literal>Authentication</literal> object contains a single
  1224. principal, and multiple <literal>GrantedAuthority</literal>[]s. To
  1225. facilitate mapping between these different concepts, the Acegi
  1226. Security JAAS package includes an
  1227. <literal>AuthorityGranter</literal> interface. An
  1228. <literal>AuthorityGranter</literal> is responsible for inspecting a
  1229. JAAS principal and returning a <literal>String</literal>. The
  1230. <literal>JaasAuthenticationProvider</literal> then creates a
  1231. <literal>JaasGrantedAuthority</literal> (which implements Acegi
  1232. Security’s <literal>GrantedAuthority</literal> interface) containing
  1233. both the <literal>AuthorityGranter</literal>-returned
  1234. <literal>String</literal> and the JAAS principal that the
  1235. <literal>AuthorityGranter</literal> was passed. The
  1236. <literal>JaasAuthenticationProvider</literal> obtains the JAAS
  1237. principals by firstly successfully authenticating the user’s
  1238. credentials using the JAAS <literal>LoginModule</literal>, and then
  1239. accessing the <literal>LoginContext</literal> it returns. A call to
  1240. <literal>LoginContext.getSubject().getPrincipals()</literal> is
  1241. made, with each resulting principal passed to each
  1242. <literal>AuthorityGranter</literal> defined against the
  1243. <literal>JaasAuthenticationProvider.setAuthorityGranters(List)</literal>
  1244. property. Acegi Security does not include any production
  1245. <literal>AuthorityGranter</literal>s given every JAAS principal has
  1246. an implementation-specific meaning. However, there is a
  1247. <literal>TestAuthorityGranter</literal> in the unit tests that
  1248. demonstrates a simple <literal>AuthorityGranter</literal>
  1249. implementation.</para>
  1250. </sect3>
  1251. </sect2>
  1252. <sect2 id="security-authentication-recommendations">
  1253. <title>Authentication Recommendations</title>
  1254. <para>With the heavy use of interfaces throughout the authentication
  1255. system (<literal>Authentication</literal>,
  1256. <literal>AuthenticationManager</literal>,
  1257. <literal>AuthenticationProvider</literal> and
  1258. <literal>AuthenticationDao</literal>) it might be confusing to a new
  1259. user to know which part of the authentication system to customize. In
  1260. general, the following is recommended:</para>
  1261. <itemizedlist>
  1262. <listitem>
  1263. <para>Use the
  1264. <literal>UsernamePasswordAuthenticationToken</literal>
  1265. implementation where possible.</para>
  1266. </listitem>
  1267. <listitem>
  1268. <para>If you simply need to implement a new authentication
  1269. repository (eg to obtain user details from your application’s
  1270. existing database), use the
  1271. <literal>DaoAuthenticationProvider</literal> along with the
  1272. <literal>AuthenticationDao</literal>. It is the fastest and safest
  1273. way to integrate an external database.</para>
  1274. </listitem>
  1275. <listitem>
  1276. <para>If you're using Container Adapters or a
  1277. <literal>RunAsManager</literal> that replaces the
  1278. <literal>Authentication</literal> object, ensure you have
  1279. registered the <literal>AuthByAdapterProvider</literal> and
  1280. <literal>RunAsManagerImplProvider</literal> respectively with your
  1281. <literal>ProviderManager</literal>.</para>
  1282. </listitem>
  1283. <listitem>
  1284. <para>Never enable the
  1285. <literal>TestingAuthenticationProvider</literal> on a production
  1286. system. Doing so will allow any client to simply present a
  1287. <literal>TestingAuthenticationToken</literal> and obtain whatever
  1288. access they request.</para>
  1289. </listitem>
  1290. <listitem>
  1291. <para>Adding a new <literal>AuthenticationProvider</literal> is
  1292. sufficient to support most custom authentication requirements.
  1293. Only unusual requirements would require the
  1294. <literal>ProviderManager</literal> to be replaced with a different
  1295. <literal>AuthenticationManager</literal>.</para>
  1296. </listitem>
  1297. </itemizedlist>
  1298. </sect2>
  1299. </sect1>
  1300. <sect1 id="security-authorization">
  1301. <title>Authorization</title>
  1302. <sect2 id="security-authorization-granted-authorities">
  1303. <title>Granted Authorities</title>
  1304. <para>As briefly mentioned in the Authentication section, all
  1305. <literal>Authentication</literal> implementations are required to
  1306. store an array of <literal>GrantedAuthority</literal> objects. These
  1307. represent the authorities that have been granted to the principal. The
  1308. <literal>GrantedAuthority</literal> objects are inserted into the
  1309. <literal>Authentication</literal> object by the
  1310. <literal>AuthenticationManager</literal> and are later read by
  1311. <literal>AccessDecisionManager</literal>s when making authorization
  1312. decisions.</para>
  1313. <para><literal>GrantedAuthority</literal> is an interface with only
  1314. one method:</para>
  1315. <para><programlisting>public String getAuthority();</programlisting></para>
  1316. <para>This method allows <literal>AccessDecisionManager</literal>s to
  1317. obtain a precise <literal>String</literal> representation of the
  1318. <literal>GrantedAuthority</literal>. By returning a representation as
  1319. a <literal>String</literal>, a <literal>GrantedAuthority</literal> can
  1320. be easily "read" by most <literal>AccessDecisionManager</literal>s. If
  1321. a <literal>GrantedAuthority</literal> cannot be precisely represented
  1322. as a <literal>String</literal>, the
  1323. <literal>GrantedAuthority</literal> is considered "complex" and
  1324. <literal>getAuthority()</literal> must return
  1325. <literal>null</literal>.</para>
  1326. <para>An example of a "complex" <literal>GrantedAuthority</literal>
  1327. would be an implementation that stores a list of operations and
  1328. authority thresholds that apply to different customer account numbers.
  1329. Representing this complex <literal>GrantedAuthority</literal> as a
  1330. <literal>String</literal> would be quite complex, and as a result the
  1331. <literal>getAuthority()</literal> method should return
  1332. <literal>null</literal>. This will indicate to any
  1333. <literal>AccessDecisionManager</literal> that it will need to
  1334. specifically support the <literal>GrantedAuthority</literal>
  1335. implementation in order to understand its contents.</para>
  1336. <para>The Acegi Security System for Spring includes one concrete
  1337. <literal>GrantedAuthority</literal> implementation,
  1338. <literal>GrantedAuthorityImpl</literal>. This allows any
  1339. user-specified <literal>String</literal> to be converted into a
  1340. <literal>GrantedAuthority</literal>. All
  1341. <literal>AuthenticationProvider</literal>s included with the security
  1342. architecture use <literal>GrantedAuthorityImpl</literal> to populate
  1343. the <literal>Authentication</literal> object.</para>
  1344. </sect2>
  1345. <sect2 id="security-authorization-access-decision-managers">
  1346. <title>Access Decision Managers</title>
  1347. <para>The <literal>AccessDecisionManager</literal> is called by the
  1348. <literal>AbstractSecurityInterceptor</literal> and is responsible for
  1349. making final access control decisions. The
  1350. <literal>AccessDecisionManager</literal> interface contains three
  1351. methods:</para>
  1352. <para><programlisting>public void decide(Authentication authentication, Object object, ConfigAttributeDefinition config) throws AccessDeniedException;
  1353. public boolean supports(ConfigAttribute attribute);
  1354. public boolean supports(Class clazz);</programlisting></para>
  1355. <para>As can be seen from the first method, the
  1356. <literal>AccessDecisionManager</literal> is passed via method
  1357. parameters all information that is likely to be of value in assessing
  1358. an authorization decision. In particular, passing the secure
  1359. <literal>Object</literal> enables those arguments contained in the
  1360. actual secure object invocation to be inspected. For example, let's
  1361. assume the secure object was a <literal>MethodInvocation</literal>. It
  1362. would be easy to query the <literal>MethodInvocation</literal> for any
  1363. <literal>Customer</literal> argument, and then implement some sort of
  1364. security logic in the <literal>AccessDecisionManager</literal> to
  1365. ensure the principal is permitted to operate on that customer.
  1366. Implementations are expected to throw an
  1367. <literal>AccessDeniedException</literal> if access is denied.</para>
  1368. <para>The <literal>supports(ConfigAttribute)</literal> method is
  1369. called by the <literal>AbstractSecurityInterceptor</literal> at
  1370. startup time to determine if the
  1371. <literal>AccessDecisionManager</literal> can process the passed
  1372. <literal>ConfigAttribute</literal>. The
  1373. <literal>supports(Class)</literal> method is called by a security
  1374. interceptor implementation to ensure the configured
  1375. <literal>AccessDecisionManager</literal> supports the type of secure
  1376. object that the security interceptor will present.</para>
  1377. </sect2>
  1378. <sect2 id="security-authorization-voting-decision-manager">
  1379. <title>Voting Decision Manager</title>
  1380. <para>Whilst users can implement their own
  1381. <literal>AccessDecisionManager</literal> to control all aspects of
  1382. authorization, the Acegi Security System for Spring includes several
  1383. <literal>AccessDecisionManager</literal> implementations that are
  1384. based on voting. Using this approach, a series of
  1385. <literal>AccessDecisionVoter</literal> implementations are polled on
  1386. an authorization decision. The
  1387. <literal>AccessDecisionManager</literal> then decides whether or not
  1388. to throw an <literal>AccessDeniedException</literal> based on its
  1389. assessment of the votes.</para>
  1390. <para>The <literal>AccessDecisionVoter</literal> interface has three
  1391. methods:</para>
  1392. <para><programlisting>public int vote(Authentication authentication, Object object, ConfigAttributeDefinition config);
  1393. public boolean supports(ConfigAttribute attribute);
  1394. public boolean supports(Class clazz);</programlisting></para>
  1395. <para>Concrete implementations return an <literal>int</literal>, with
  1396. possible values being reflected in the
  1397. <literal>AccessDecisionVoter</literal> static fields
  1398. <literal>ACCESS_ABSTAIN</literal>, <literal>ACCESS_DENIED</literal>
  1399. and <literal>ACCESS_GRANTED</literal>. A voting implementation will
  1400. return <literal>ACCESS_ABSTAIN</literal> if it has no opinion on an
  1401. authorization decision. If it does have an opinion, it must return
  1402. either <literal>ACCESS_DENIED</literal> or
  1403. <literal>ACCESS_GRANTED</literal>.</para>
  1404. <para>There are three concrete
  1405. <literal>AccessDecisionManager</literal>s provided with the Acegi
  1406. Security System for Spring that tally the votes. The
  1407. <literal>ConsensusBased</literal> implementation will grant or deny
  1408. access based on the consensus of non-abstain votes. Properties are
  1409. provided to control behavior in the event of an equality of votes or
  1410. if all votes are abstain. The <literal>AffirmativeBased</literal>
  1411. implementation will grant access if one or more
  1412. <literal>ACCESS_GRANTED</literal> votes were received (ie a deny vote
  1413. will be ignored, provided there was at least one grant vote). Like the
  1414. <literal>ConsensusBased</literal> implementation, there is a parameter
  1415. that controls the behavior if all voters abstain. The
  1416. <literal>UnanimousBased</literal> provider expects unanimous
  1417. <literal>ACCESS_GRANTED</literal> votes in order to grant access,
  1418. ignoring abstains. It will deny access if there is any
  1419. <literal>ACCESS_DENIED</literal> vote. Like the other implementations,
  1420. there is a parameter that controls the behaviour if all voters
  1421. abstain.</para>
  1422. <para>It is possible to implement a custom
  1423. <literal>AccessDecisionManager</literal> that tallies votes
  1424. differently. For example, votes from a particular
  1425. <literal>AccessDecisionVoter</literal> might receive additional
  1426. weighting, whilst a deny vote from a particular voter may have a veto
  1427. effect.</para>
  1428. <para>There is one concrete <literal>AccessDecisionVoter</literal>
  1429. implementation provided with the Acegi Security System for Spring. The
  1430. <literal>RoleVoter</literal> class will vote if any ConfigAttribute
  1431. begins with <literal>ROLE_</literal>. It will vote to grant access if
  1432. there is a <literal>GrantedAuthority</literal> which returns a
  1433. <literal>String</literal> representation (via the
  1434. <literal>getAuthority()</literal> method) exactly equal to one or more
  1435. <literal>ConfigAttributes</literal> starting with
  1436. <literal>ROLE_</literal>. If there is no exact match of any
  1437. <literal>ConfigAttribute</literal> starting with
  1438. <literal>ROLE_</literal>, the <literal>RoleVoter</literal> will vote
  1439. to deny access. If no <literal>ConfigAttribute</literal> begins with
  1440. <literal>ROLE_</literal>, the voter will abstain.
  1441. <literal>RoleVoter</literal> is case sensitive on comparisons as well
  1442. as the <literal>ROLE_</literal> prefix.</para>
  1443. <para>It is possible to implement a custom
  1444. <literal>AccessDecisionVoter</literal>. Several examples are provided
  1445. in the Acegi Security System for Spring unit tests, including
  1446. <literal>ContactSecurityVoter</literal> and
  1447. <literal>DenyVoter</literal>. The
  1448. <literal>ContactSecurityVoter</literal> abstains from voting decisions
  1449. where a <literal>CONTACT_OWNED_BY_CURRENT_USER</literal>
  1450. <literal>ConfigAttribute</literal> is not found. If voting, it queries
  1451. the <literal>MethodInvocation</literal> to extract the owner of the
  1452. <literal>Contact</literal> object that is subject of the method call.
  1453. It votes to grant access if the <literal>Contact</literal> owner
  1454. matches the principal presented in the
  1455. <literal>Authentication</literal> object. It could have just as easily
  1456. compared the <literal>Contact</literal> owner with some
  1457. <literal>GrantedAuthority</literal> the
  1458. <literal>Authentication</literal> object presented. All of this is
  1459. achieved with relatively few lines of code and demonstrates the
  1460. flexibility of the authorization model.</para>
  1461. </sect2>
  1462. <sect2 id="security-authorization-taglib">
  1463. <title>Authorization Tag Library</title>
  1464. <para>The Acegi Security System for Spring comes bundled with a JSP
  1465. tag library that eases JSP writing. The tag library is known as
  1466. <literal>authz</literal>.</para>
  1467. <para>This library allows you to easy develop JSP pages which
  1468. reference the security environment. For example,
  1469. <literal>authz</literal> allows you to determine if a principal holds
  1470. a particular granted authority, holds a group of granted authorities,
  1471. or does not hold a given granted authority.</para>
  1472. <sect3>
  1473. <title>Usage</title>
  1474. <para>The following JSP fragment illustrates how to use the
  1475. <literal>authz</literal> taglib:</para>
  1476. <para><programlisting>&lt;authz:authorize ifAllGranted="ROLE_SUPERVISOR"&gt;
  1477. &lt;td&gt;
  1478. &lt;A HREF="del.htm?id=&lt;c:out value="${contact.id}"/&gt;"&gt;Del&lt;/A&gt;
  1479. &lt;/td&gt;
  1480. &lt;/authz:authorize&gt;</programlisting></para>
  1481. <para>This code was copied from the Contacts sample
  1482. application.</para>
  1483. <para>What this code says is: if the principal has been granted
  1484. ROLE_SUPERVISOR, allow the tag's body to be output.</para>
  1485. </sect3>
  1486. <sect3>
  1487. <title>Installation</title>
  1488. <para>Installation is a simple matter. Simply copy the
  1489. <literal>acegi-security-taglib.jar</literal> file into your
  1490. application's <literal>WEB-INF/lib</literal> folder. The tag library
  1491. includes it's TLD, which makes it easier to work with JSP 1.2+
  1492. containers.</para>
  1493. <para>If you are using a JSP 1.1 container, you will need to declare
  1494. the JSP tag library in your application's <literal>web.xml</literal>
  1495. file, with code such as this:</para>
  1496. <para><programlisting>&lt;taglib&gt;
  1497. &lt;taglib-uri&gt;http://acegisecurity.sf.net/authz&lt;/taglib-uri&gt;
  1498. &lt;taglib-location&gt;/WEB-INF/authz.tld&lt;/taglib-location&gt;
  1499. &lt;/taglib&gt;</programlisting></para>
  1500. <para>For JSP 1.1 containers you will also need to extract the
  1501. <literal>authz.tld</literal> file from the
  1502. <literal>acegi-security-taglib.jar</literal> file and put it into
  1503. your application's <literal>WEB-INF/lib</literal> folder. Use a
  1504. regular Zip tool, or Java's JAR utility.</para>
  1505. </sect3>
  1506. <sect3>
  1507. <title>Reference</title>
  1508. <para>The <literal>authz:authorize</literal> tag declares the
  1509. following attributes:</para>
  1510. <para><itemizedlist spacing="compact">
  1511. <listitem>
  1512. <para><literal>ifAllGranted</literal>: All the listed roles
  1513. must be granted for the tag to output its body.</para>
  1514. </listitem>
  1515. <listitem>
  1516. <para><literal>ifAnyGranted</literal>: Any of the listed roles
  1517. must be granted for the tag to output its body.</para>
  1518. </listitem>
  1519. <listitem>
  1520. <para><literal>ifNotGranted</literal>: None of the listed
  1521. roles must be granted for the tag to output its body.</para>
  1522. </listitem>
  1523. </itemizedlist></para>
  1524. <para>You'll note that in each attribute you can list multiple
  1525. roles. Simply separate the roles using a comma. The
  1526. <literal>authorize</literal> tag ignores whitespace in
  1527. attributes.</para>
  1528. <para>The tag library logically ANDs all of it's parameters
  1529. together. This means that if you combine two or more attributes, all
  1530. attributes must be true for the tag to output it's body. Don't add
  1531. an <literal>ifAllGranted="ROLE_SUPERVISOR"</literal>, followed by an
  1532. <literal>ifNotGranted="ROLE_SUPERVISOR"</literal>, or you'll be
  1533. surprised to never see the tag's body.</para>
  1534. <para>By requiring all attributes to return true, the authorize tag
  1535. allows you to create more complex authorization scenarios. For
  1536. example, you could declare an
  1537. <literal>ifAllGranted="ROLE_SUPERVISOR"</literal> and an
  1538. <literal>ifNotGranted="ROLE_NEWBIE_SUPERVISOR"</literal> in the same
  1539. tag, in order to prevent new supervisors from seeing the tag body.
  1540. However it would no doubt be simpler to use
  1541. <literal>ifAllGranted="ROLE_EXPERIENCED_SUPERVISOR"</literal> rather
  1542. than inserting NOT conditions into your design.</para>
  1543. <para>One last item: the tag verifies the authorizations in a
  1544. specific order: first <literal>ifNotGranted</literal>, then
  1545. <literal>ifAllGranted</literal>, and finally,
  1546. <literal>ifAnyGranted</literal>.</para>
  1547. </sect3>
  1548. </sect2>
  1549. <sect2 id="security-authorization-recommendations">
  1550. <title>Authorization Recommendations</title>
  1551. <para>Given there are several ways to achieve similar authorization
  1552. outcomes in the Acegi Security System for Spring, the following
  1553. general recommendations are made:</para>
  1554. <itemizedlist>
  1555. <listitem>
  1556. <para>Grant authorities using
  1557. <literal>GrantedAuthorityImpl</literal> where possible. Because it
  1558. is already supported by the Acegi Security System for Spring, you
  1559. avoid the need to create custom
  1560. <literal>AuthenticationManager</literal> or
  1561. <literal>AuthenticationProvider</literal> implementations simply
  1562. to populate the <literal>Authentication</literal> object with a
  1563. custom <literal>GrantedAuthority</literal>.</para>
  1564. </listitem>
  1565. <listitem>
  1566. <para>Writing an <literal>AccessDecisionVoter</literal>
  1567. implementation and using either <literal>ConsensusBased</literal>,
  1568. <literal>AffirmativeBased</literal> or
  1569. <literal>UnanimousBased</literal> as the
  1570. <literal>AccessDecisionManager</literal> may be the best approach
  1571. to implementing your custom access decision rules.</para>
  1572. </listitem>
  1573. </itemizedlist>
  1574. </sect2>
  1575. </sect1>
  1576. <sect1 id="security-run-as">
  1577. <title>Run-As Authentication Replacement</title>
  1578. <sect2 id="security-run-as-purpose">
  1579. <title>Purpose</title>
  1580. <para>The <literal>AbstractSecurityInterceptor</literal> is able to
  1581. temporarily replace the <literal>Authentication</literal> object in
  1582. the <literal>SecureContext</literal> and
  1583. <literal>ContextHolder</literal> during the
  1584. <literal>SecurityInterceptorCallback</literal>. This only occurs if
  1585. the original <literal>Authentication</literal> object was successfully
  1586. processed by the <literal>AuthenticationManager</literal> and
  1587. <literal>AccessDecisionManager</literal>. The
  1588. <literal>RunAsManager</literal> will indicate the replacement
  1589. <literal>Authentication</literal> object, if any, that should be used
  1590. during the <literal>SecurityInterceptorCallback</literal>.</para>
  1591. <para>By temporarily replacing the <literal>Authentication</literal>
  1592. object during a <literal>SecurityInterceptorCallback</literal>, the
  1593. secured invocation will be able to call other objects which require
  1594. different authentication and authorization credentials. It will also
  1595. be able to perform any internal security checks for specific
  1596. <literal>GrantedAuthority</literal> objects.</para>
  1597. </sect2>
  1598. <sect2 id="security-run-as-usage">
  1599. <title>Usage</title>
  1600. <para>A <literal>RunAsManager</literal> interface is provided by the
  1601. Acegi Security System for Spring:</para>
  1602. <para><programlisting>public Authentication buildRunAs(Authentication authentication, Object object, ConfigAttributeDefinition config);
  1603. public boolean supports(ConfigAttribute attribute);
  1604. public boolean supports(Class clazz);</programlisting></para>
  1605. <para>The first method returns the <literal>Authentication</literal>
  1606. object that should replace the existing
  1607. <literal>Authentication</literal> object for the duration of the
  1608. method invocation. If the method returns <literal>null</literal>, it
  1609. indicates no replacement should be made. The second method is used by
  1610. the <literal>AbstractSecurityInterceptor</literal> as part of its
  1611. startup validation of configuration attributes. The
  1612. <literal>supports(Class)</literal> method is called by a security
  1613. interceptor implementation to ensure the configured
  1614. <literal>RunAsManager</literal> supports the type of secure object
  1615. that the security interceptor will present.</para>
  1616. <para>One concrete implementation of a <literal>RunAsManager</literal>
  1617. is provided with the Acegi Security System for Spring. The
  1618. <literal>RunAsManagerImpl</literal> class returns a replacement
  1619. <literal>RunAsUserToken</literal> if any
  1620. <literal>ConfigAttribute</literal> starts with
  1621. <literal>RUN_AS_</literal>. If any such
  1622. <literal>ConfigAttribute</literal> is found, the replacement
  1623. <literal>RunAsUserToken</literal> will contain the same principal,
  1624. credentials and granted authorities as the original
  1625. <literal>Authentication</literal> object, along with a new
  1626. <literal>GrantedAuthorityImpl</literal> for each
  1627. <literal>RUN_AS_</literal> <literal>ConfigAttribute</literal>. Each
  1628. new <literal>GrantedAuthorityImpl</literal> will be prefixed with
  1629. <literal>ROLE_</literal>, followed by the <literal>RUN_AS</literal>
  1630. <literal>ConfigAttribute</literal>. For example, a
  1631. <literal>RUN_AS_SERVER</literal> will result in the replacement
  1632. <literal>RunAsUserToken</literal> containing a
  1633. <literal>ROLE_RUN_AS_SERVER</literal> granted authority.</para>
  1634. <para>The replacement <literal>RunAsUserToken</literal> is just like
  1635. any other <literal>Authentication</literal> object. It needs to be
  1636. authenticated by the <literal>AuthenticationManager</literal>,
  1637. probably via delegation to a suitable
  1638. <literal>AuthenticationProvider</literal>. The
  1639. <literal>RunAsImplAuthenticationProvider</literal> performs such
  1640. authentication. It simply accepts as valid any
  1641. <literal>RunAsUserToken</literal> presented.</para>
  1642. <para>To ensure malicious code does not create a
  1643. <literal>RunAsUserToken</literal> and present it for guaranteed
  1644. acceptance by the <literal>RunAsImplAuthenticationProvider</literal>,
  1645. the hash of a key is stored in all generated tokens. The
  1646. <literal>RunAsManagerImpl</literal> and
  1647. <literal>RunAsImplAuthenticationProvider</literal> is created in the
  1648. bean context with the same key:</para>
  1649. <para><programlisting>&lt;bean id="runAsManager" class="net.sf.acegisecurity.runas.RunAsManagerImpl"&gt;
  1650. &lt;property name="key"&gt;&lt;value&gt;my_run_as_password&lt;/value&gt;&lt;/property&gt;
  1651. &lt;/bean&gt;</programlisting><programlisting>&lt;bean id="runAsAuthenticationProvider" class="net.sf.acegisecurity.runas.RunAsImplAuthenticationProvider"&gt;
  1652. &lt;property name="key"&gt;&lt;value&gt;my_run_as_password&lt;/value&gt;&lt;/property&gt;
  1653. &lt;/bean&gt;</programlisting></para>
  1654. <para>By using the same key, each <literal>RunAsUserToken</literal>
  1655. can be validated it was created by an approved
  1656. <literal>RunAsManagerImpl</literal>. The
  1657. <literal>RunAsUserToken</literal> is immutable after creation for
  1658. security reasons.</para>
  1659. </sect2>
  1660. </sect1>
  1661. <sect1 id="security-ui">
  1662. <title>User Interfacing with the ContextHolder</title>
  1663. <sect2 id="security-ui-purpose">
  1664. <title>Purpose</title>
  1665. <para>Everything presented so far assumes one thing: the
  1666. <literal>ContextHolder</literal> is populated with a valid
  1667. <literal>SecureContext</literal>, which in turn contains a valid
  1668. <literal>Authentication</literal> object. Developers are free to do
  1669. this in whichever way they like, such as directly calling the relevant
  1670. objects at runtime. However, several classes have been provided to
  1671. make this process transparent in many situations.</para>
  1672. <para>The <literal>net.sf.acegisecurity.ui</literal> package is
  1673. designed to make interfacing web application user interfaces with the
  1674. <literal>ContextHolder</literal> as simple as possible. There are two
  1675. major steps in doing this:</para>
  1676. <para><itemizedlist spacing="compact">
  1677. <listitem>
  1678. <para>Actually authenticate the user and place the resulting
  1679. <literal>Authentication</literal> object in a "well-known
  1680. location".</para>
  1681. </listitem>
  1682. <listitem>
  1683. <para>Extract the <literal>Authentication</literal> object from
  1684. the "well-known location" and place in into the
  1685. <literal>ContextHolder</literal> for the duration of the secure
  1686. object invocation.</para>
  1687. </listitem>
  1688. </itemizedlist></para>
  1689. <para>There are several alternatives are available for the first step,
  1690. which will be briefly discussed in this chapter. The most popular
  1691. approach is HTTP Session Authentication, which uses the
  1692. <literal>HttpSession</literal> object and filters to authenticate the
  1693. user. Another approach is HTTP Basic Authentication, which allows
  1694. clients to use HTTP headers to present authentication information to
  1695. the Acegi Security System for Spring. Alternatively, you can also use
  1696. Yale Central Authentication Service (CAS) for enterprise-wide single
  1697. sign on. The final approach is via Container Adapters, which allow
  1698. supported web containers to perform the authentication themselves.
  1699. HTTP Session and Basic Authentication is discussed below, whilst CAS
  1700. and Container Adapters are discussed in separate sections of this
  1701. document.</para>
  1702. </sect2>
  1703. <sect2 id="security-ui-http-session">
  1704. <title>HTTP Session Authentication</title>
  1705. <para>HTTP Session Authentication involves using the
  1706. <literal>AuthenticationProcessingFilter</literal> to process a login
  1707. form. The login form simply contains <literal>j_username</literal> and
  1708. <literal>j_password</literal> input fields, and posts to a URL that is
  1709. monitored by the filter (by default
  1710. <literal>j_acegi_security_check</literal>). The filter is defined in
  1711. <literal>web.xml</literal> behind a
  1712. <literal>FilterToBeanProxy</literal> as follows:</para>
  1713. <para><programlisting>&lt;filter&gt;
  1714. &lt;filter-name&gt;Acegi Authentication Processing Filter&lt;/filter-name&gt;
  1715. &lt;filter-class&gt;net.sf.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
  1716. &lt;init-param&gt;
  1717. &lt;param-name&gt;targetClass&lt;/param-name&gt;
  1718. &lt;param-value&gt;net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter&lt;/param-value&gt;
  1719. &lt;/init-param&gt;
  1720. &lt;/filter&gt;
  1721. &lt;filter-mapping&gt;
  1722. &lt;filter-name&gt;Acegi Authentication Processing Filter&lt;/filter-name&gt;
  1723. &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
  1724. &lt;/filter-mapping&gt;</programlisting></para>
  1725. <para>For a discussion of <literal>FilterToBeanProxy</literal>, please
  1726. refer to the Filters section. The application context will need to
  1727. define the <literal>AuthenticationProcessingFilter</literal>:</para>
  1728. <para><programlisting>&lt;bean id="authenticationProcessingFilter" class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter"&gt;
  1729. &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
  1730. &lt;property name="authenticationFailureUrl"&gt;&lt;value&gt;/acegilogin.jsp?login_error=1&lt;/value&gt;&lt;/property&gt;
  1731. &lt;property name="defaultTargetUrl"&gt;&lt;value&gt;/&lt;/value&gt;&lt;/property&gt;
  1732. &lt;property name="filterProcessesUrl"&gt;&lt;value&gt;/j_acegi_security_check&lt;/value&gt;&lt;/property&gt;
  1733. &lt;/bean&gt;</programlisting></para>
  1734. <para>The configured <literal>AuthenticationManager</literal>
  1735. processes each authentication request. If authentication fails, the
  1736. browser will be redirected to the
  1737. <literal>authenticationFailureUrl</literal>. The
  1738. <literal>AuthenticationException</literal> will be placed into the
  1739. <literal>HttpSession</literal> attribute indicated by
  1740. <literal>AbstractProcessingFilter.ACEGI_SECURITY_LAST_EXCEPTION_KEY</literal>,
  1741. enabling a reason to be provided to the user on the error page.</para>
  1742. <para>If authentication is successful, the resulting
  1743. <literal>Authentication</literal> object will be placed into the
  1744. <literal>HttpSession</literal> attribute indicated by
  1745. <literal>HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY</literal>.
  1746. This becomes the "well-known location" from which the
  1747. <literal>Authentication</literal> object is later extracted.</para>
  1748. <para>Once the <literal>HttpSession</literal> has been updated, the
  1749. browser will need to be redirected to the target URL. The target URL
  1750. is usually indicated by the <literal>HttpSession</literal> attribute
  1751. specified by
  1752. <literal>AbstractProcessingFilter.ACEGI_SECURITY_TARGET_URL_KEY</literal>.
  1753. This attribute is automatically set by the
  1754. <literal>SecurityEnforcementFilter</literal> when an
  1755. <literal>AuthenticationException</literal> occurs, so that after login
  1756. is completed the user can return to what they were trying to access.
  1757. If for some reason the <literal>HttpSession</literal> does not
  1758. indicate the target URL, the browser will be redirected to the
  1759. <literal>defaultTargetUrl</literal> property.</para>
  1760. <para>Because this authentication approach is fully contained within a
  1761. single web application, HTTP Session Authentication is recommended to
  1762. be used instead of Container Adapters.</para>
  1763. </sect2>
  1764. <sect2 id="security-ui-http-basic">
  1765. <title>HTTP Basic Authentication</title>
  1766. <para>The Acegi Security System for Spring provides a
  1767. <literal>BasicProcessingFilter</literal> which is capable of
  1768. processing authentication credentials presented in HTTP headers. This
  1769. can be used for authenticating calls made by Spring remoting protocols
  1770. (such as Hessian and Burlap), as well as normal user agents (such as
  1771. Internet Explorer and Navigator). The standard governing HTTP Basic
  1772. Authentication is defined by RFC 1945, Section 11, and the
  1773. <literal>BasicProcessingFilter</literal> conforms with this
  1774. RFC.</para>
  1775. <para>To implement HTTP Basic Authentication, it is necessary to add
  1776. the following filter to <literal>web.xml</literal>:</para>
  1777. <para><programlisting>&lt;filter&gt;
  1778. &lt;filter-name&gt;Acegi HTTP BASIC Authorization Filter&lt;/filter-name&gt;
  1779. &lt;filter-class&gt;net.sf.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
  1780. &lt;init-param&gt;
  1781. &lt;param-name&gt;targetClass&lt;/param-name&gt;
  1782. &lt;param-value&gt;net.sf.acegisecurity.ui.basicauth.BasicProcessingFilter&lt;/param-value&gt;
  1783. &lt;/init-param&gt;
  1784. &lt;/filter&gt;
  1785. &lt;filter-mapping&gt;
  1786. &lt;filter-name&gt;Acegi HTTP BASIC Authorization Filter&lt;/filter-name&gt;
  1787. &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
  1788. &lt;/filter-mapping&gt;</programlisting></para>
  1789. <para>For a discussion of <literal>FilterToBeanProxy</literal>, please
  1790. refer to the Filters section. The application context will need to
  1791. define the <literal>BasicProcessingFilter</literal> and its required
  1792. collaborator:</para>
  1793. <para><programlisting>&lt;bean id="basicProcessingFilter" class="net.sf.acegisecurity.ui.basicauth.BasicProcessingFilter"&gt;
  1794. &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
  1795. &lt;property name="authenticationEntryPoint"&gt;&lt;ref bean="authenticationEntryPoint"/&gt;&lt;/property&gt;
  1796. &lt;/bean&gt;
  1797. &lt;bean id="authenticationEntryPoint" class="net.sf.acegisecurity.ui.basicauth.BasicProcessingFilterEntryPoint"&gt;
  1798. &lt;property name="realmName"&gt;&lt;value&gt;Name Of Your Realm&lt;/value&gt;&lt;/property&gt;
  1799. &lt;/bean&gt;</programlisting></para>
  1800. <para>The configured <literal>AuthenticationManager</literal>
  1801. processes each authentication request. If authentication fails, the
  1802. configured <literal>AuthenticationEntryPoint</literal> will be used to
  1803. retry the authentication process. Usually you will use the
  1804. <literal>BasicProcessingFilterEntryPoint</literal>, which returns a
  1805. 401 response with a suitable header to retry HTTP Basic
  1806. authentication. If authentication is successful, the resulting
  1807. <literal>Authentication</literal> object will be placed into the
  1808. <literal>HttpSession</literal> attribute indicated by
  1809. <literal>HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY</literal>.
  1810. This becomes the "well-known location" from which the
  1811. <literal>Authentication</literal> object is later extracted.</para>
  1812. <para>If the authentication event was successful, or authentication
  1813. was not attempted because the HTTP header did not contain a supported
  1814. authentication request, the filter chain will continue as normal. The
  1815. only time the filter chain will be interrupted is if authentication
  1816. fails and the <literal>AuthenticationEntryPoint</literal> is called,
  1817. as discussed in the previous paragraph.</para>
  1818. <para>HTTP Basic Authentication is recommended to be used instead of
  1819. Container Adapters. It can be used in conjunction with HTTP Session
  1820. Authentication, as demonstrated in the Contacts sample application.
  1821. You can also use it instead of HTTP Session Authentication if you
  1822. wish.</para>
  1823. </sect2>
  1824. <sect2 id="security-ui-well-known">
  1825. <title>Well-Known Location Integration</title>
  1826. <para>Once a web application has used either HTTP Session
  1827. Authentication, HTTP Basic Authentication, or a Container Adapter, an
  1828. <literal>Authentication</literal> object will exist in a well-known
  1829. location. The final step in automatically integrating the user
  1830. interface with the backend security interceptor is to extract this
  1831. <literal>Authentication</literal> object from the well-known location
  1832. and place it into a <literal>SecureContext</literal> in the
  1833. <literal>ContextHolder</literal>.</para>
  1834. <para>The <literal>AbstractIntegrationFilter</literal> and its
  1835. subclasses provide this well-known location integration. These classes
  1836. are standard filters, and at the start of each request they will
  1837. attempt to extract the <literal>Authentication</literal> object from a
  1838. well-known location. The <literal>Authentication</literal> object will
  1839. then be added to a <literal>SecureContext</literal>, the
  1840. <literal>SecureContext</literal> associated with the
  1841. <literal>ContextHolder</literal> for the duration of the request, and
  1842. the <literal>ContextHolder</literal> be cleared when the request is
  1843. finished. Four concrete subclasses of
  1844. <literal>AbstractIntegrationFilter</literal> are provided with the
  1845. Acegi Security System for Spring:</para>
  1846. <para><itemizedlist>
  1847. <listitem>
  1848. <para><literal>HttpSessionIntegrationFilter</literal> is used
  1849. with HTTP Session Authentication, HTTP Basic Authentication, or
  1850. any other approach that populates the
  1851. <literal>HttpSession</literal> accordingly. It extracts the
  1852. <literal>Authentication</literal> object from the
  1853. <literal>HttpSession</literal> attribute indicated by
  1854. <literal>HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY</literal>.</para>
  1855. </listitem>
  1856. <listitem>
  1857. <para><literal>HttpRequestIntegrationFilter</literal> is used
  1858. with Catalina, Jetty and Resin Container Adapters. It extracts
  1859. the authentication information from
  1860. <literal>HttpServletRequest.getUserPrincipal()</literal>.</para>
  1861. </listitem>
  1862. <listitem>
  1863. <para><literal>JbossIntegrationFilter</literal> is used with the
  1864. JBoss Container Adapter. It extracts the authentication from
  1865. <literal>java:comp/env/security/subject</literal>.</para>
  1866. </listitem>
  1867. <listitem>
  1868. <para><literal>AutoIntegrationFilter</literal> automatically
  1869. determines which filter to use. This makes a web application WAR
  1870. file more portable, as the <literal>web.xml</literal> is not
  1871. hard-coded to a specific
  1872. <literal>AbstractIntegrationFilter</literal>.</para>
  1873. </listitem>
  1874. </itemizedlist></para>
  1875. <para>To define the <literal>AutoIntegrationFilter</literal>
  1876. (recommended), simply add the following to your web.xml:</para>
  1877. <para><programlisting>&lt;filter&gt;
  1878. &lt;filter-name&gt;Acegi Security System for Spring Auto Integration Filter&lt;/filter-name&gt;
  1879. &lt;filter-class&gt;net.sf.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
  1880. &lt;init-param&gt;
  1881. &lt;param-name&gt;targetClass&lt;/param-name&gt;
  1882. &lt;param-value&gt;net.sf.acegisecurity.ui.AutoIntegrationFilter&lt;/param-value&gt;
  1883. &lt;/init-param&gt;
  1884. &lt;/filter&gt;
  1885. &lt;filter-mapping&gt;
  1886. &lt;filter-name&gt;Acegi Security System for Spring Auto Integration Filter&lt;/filter-name&gt;
  1887. &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
  1888. &lt;/filter-mapping&gt;</programlisting></para>
  1889. <para>You will also need to add the following line to your application
  1890. context:</para>
  1891. <para><programlisting>&lt;bean id="autoIntegrationFilter" class="net.sf.acegisecurity.ui.AutoIntegrationFilter" /&gt;</programlisting></para>
  1892. <para>Once in the <literal>ContextHolder</literal>, the standard Acegi
  1893. Security System for Spring classes can be used. Because
  1894. <literal>ContextHolder</literal> is a standard object which is
  1895. populated using a filter at the container level, JSPs and Servlets do
  1896. not need to use Spring's MVC packages. This enables those applications
  1897. that use other MVC frameworks to still leverage Spring's other
  1898. capabilities, with full authentication and authorization support. The
  1899. <literal>debug.jsp</literal> page provided with the sample application
  1900. demonstrates accessing the <literal>ContextHolder</literal>
  1901. independent of Spring's MVC packages.</para>
  1902. </sect2>
  1903. </sect1>
  1904. <sect1 id="security-container-adapters">
  1905. <title>Container Adapters</title>
  1906. <sect2 id="security-container-adapters-overview">
  1907. <title>Overview</title>
  1908. <para>Early versions of the Acegi Security System for Spring
  1909. exclusively used Container Adapters for interfacing authentication
  1910. with end users. Whilst this worked well, it required considerable time
  1911. to support multiple container versions and the configuration itself
  1912. was relatively time-consuming for developers. For this reason the HTTP
  1913. Session Authentication and HTTP Basic Authentication approaches were
  1914. developed, and are today recommended for most applications.</para>
  1915. <para>Container Adapters enable the Acegi Security System for Spring
  1916. to integrate directly with the containers used to host end user
  1917. applications. This integration means that applications can continue to
  1918. leverage the authentication and authorization capabilities built into
  1919. containers (such as <literal>isUserInRole()</literal> and form-based
  1920. or basic authentication), whilst benefiting from the enhanced security
  1921. interception capabilities provided by the Acegi Security System for
  1922. Spring.</para>
  1923. <para>The integration between a container and the Acegi Security
  1924. System for Spring is achieved through an adapter. The adapter provides
  1925. a container-compatible user authentication provider, and needs to
  1926. return a container-compatible user object.</para>
  1927. <para>The adapter is instantiated by the container and is defined in a
  1928. container-specific configuration file. The adapter then loads a Spring
  1929. application context which defines the normal authentication manager
  1930. settings, such as the authentication providers that can be used to
  1931. authenticate the request. The application context is usually named
  1932. <literal>acegisecurity.xml</literal> and is placed in a
  1933. container-specific location.</para>
  1934. <para>The Acegi Security System for Spring currently supports Jetty,
  1935. Catalina (Tomcat), JBoss and Resin. Additional container adapters can
  1936. easily be written.</para>
  1937. </sect2>
  1938. <sect2 id="security-container-adapters-adapter-provider">
  1939. <title>Adapter Authentication Provider</title>
  1940. <para>As is always the case, the container adapter generated
  1941. <literal>Authentication</literal> object still needs to be
  1942. authenticated by an <literal>AuthenticationManager</literal> when
  1943. requested to do so by the
  1944. <literal>AbstractSecurityInterceptor</literal>. The
  1945. <literal>AuthenticationManager</literal> needs to be certain the
  1946. adapter-provided <literal>Authentication</literal> object is valid and
  1947. was actually authenticated by a trusted adapter.</para>
  1948. <para>Adapters create <literal>Authentication</literal> objects which
  1949. are immutable and implement the <literal>AuthByAdapter</literal>
  1950. interface. These objects store the hash of a key that is defined by
  1951. the adapter. This allows the <literal>Authentication</literal> object
  1952. to be validated by the <literal>AuthByAdapterProvider</literal>. This
  1953. authentication provider is defined as follows:</para>
  1954. <para><programlisting>&lt;bean id="authByAdapterProvider" class="net.sf.acegisecurity.adapters.AuthByAdapterProvider"&gt;
  1955. &lt;property name="key"&gt;&lt;value&gt;my_password&lt;/value&gt;&lt;/property&gt;
  1956. &lt;/bean&gt;</programlisting></para>
  1957. <para>The key must match the key that is defined in the
  1958. container-specific configuration file that starts the adapter. The
  1959. <literal>AuthByAdapterProvider</literal> automatically accepts as
  1960. valid any <literal>AuthByAdapter</literal> implementation that returns
  1961. the expected hash of the key.</para>
  1962. <para>To reiterate, this means the adapter will perform the initial
  1963. authentication using providers such as
  1964. <literal>DaoAuthenticationProvider</literal>, returning an
  1965. <literal>AuthByAdapter</literal> instance that contains a hash code of
  1966. the key. Later, when an application calls a security interceptor
  1967. managed resource, the <literal>AuthByAdapter</literal> instance in the
  1968. <literal>SecureContext</literal> in the
  1969. <literal>ContextHolder</literal> will be tested by the application's
  1970. <literal>AuthByAdapterProvider</literal>. There is no requirement for
  1971. additional authentication providers such as
  1972. <literal>DaoAuthenticationProvider</literal> within the
  1973. application-specific application context, as the only type of
  1974. <literal>Authentication</literal> instance that will be presented by
  1975. the application is from the container adapter.</para>
  1976. <para>Classloader issues are frequent with containers and the use of
  1977. container adapters illustrates this further. Each container requires a
  1978. very specific configuration. The installation instructions are
  1979. provided below. Once installed, please take the time to try the sample
  1980. application to ensure your container adapter is properly
  1981. configured.</para>
  1982. <para>When using container adapters with the
  1983. <literal>DaoAuthenticationProvider</literal>, ensure you set its
  1984. <literal>forcePrincipalAsString</literal> property to
  1985. <literal>true</literal>.</para>
  1986. </sect2>
  1987. <sect2 id="security-container-adapters-catalina">
  1988. <title>Catalina (Tomcat) Installation</title>
  1989. <para>The following was tested with Jakarta Tomcat 4.1.30 and 5.0.19.
  1990. We automatically test the following directions using our container
  1991. integration test system and these versions of Catalina
  1992. (Tomcat).</para>
  1993. <para><literal>$CATALINA_HOME</literal> refers to the root of your
  1994. Catalina (Tomcat) installation.</para>
  1995. <para>Edit your <literal>$CATALINA_HOME/conf/server.xml</literal> file
  1996. so the <literal>&lt;Engine&gt;</literal> section contains only one
  1997. active <literal>&lt;Realm&gt;</literal> entry. An example realm
  1998. entry:</para>
  1999. <para><programlisting> &lt;Realm className="net.sf.acegisecurity.adapters.catalina.CatalinaAcegiUserRealm"
  2000. appContextLocation="conf/acegisecurity.xml"
  2001. key="my_password" /&gt;</programlisting></para>
  2002. <para>Be sure to remove any other <literal>&lt;Realm&gt;</literal>
  2003. entry from your <literal>&lt;Engine&gt;</literal> section.</para>
  2004. <para>Copy <literal>acegisecurity.xml</literal> into
  2005. <literal>$CATALINA_HOME/conf</literal>.</para>
  2006. <para>Copy <literal>acegi-security-catalina-server.jar</literal> into
  2007. <literal>$CATALINA_HOME/server/lib</literal>.</para>
  2008. <para>Copy the following files into
  2009. <literal>$CATALINA_HOME/common/lib</literal>:</para>
  2010. <itemizedlist>
  2011. <listitem>
  2012. <para><literal>aopalliance.jar</literal></para>
  2013. </listitem>
  2014. <listitem>
  2015. <para><literal>spring.jar</literal></para>
  2016. </listitem>
  2017. <listitem>
  2018. <para><literal>acegi-security-catalina-common.jar</literal></para>
  2019. </listitem>
  2020. <listitem>
  2021. <para><literal>commons-codec.jar</literal></para>
  2022. </listitem>
  2023. <listitem>
  2024. <para><literal>burlap.jar</literal></para>
  2025. </listitem>
  2026. <listitem>
  2027. <para><literal>hessian.jar</literal></para>
  2028. </listitem>
  2029. </itemizedlist>
  2030. <para>None of the above JAR files (or
  2031. <literal>acegi-security.jar</literal>) should be in your application's
  2032. <literal>WEB-INF/lib</literal>. The realm name indicated in your
  2033. <literal>web.xml</literal> does not matter with Catalina.</para>
  2034. <para>We have received reports of problems using this Container
  2035. Adapter with Mac OS X. A work-around is to use a script such as
  2036. follows:</para>
  2037. <para><programlisting>#!/bin/sh
  2038. export CATALINA_HOME="/Library/Tomcat"
  2039. export JAVA_HOME="/Library/Java/Home"
  2040. cd /
  2041. $CATALINA_HOME/bin/startup.sh</programlisting></para>
  2042. </sect2>
  2043. <sect2 id="security-container-adapters-jetty">
  2044. <title>Jetty Installation</title>
  2045. <para>The following was tested with Jetty 4.2.18. We automatically
  2046. test the following directions using our container integration test
  2047. system and this version of Jetty.</para>
  2048. <para><literal>$JETTY_HOME</literal> refers to the root of your Jetty
  2049. installation.</para>
  2050. <para>Edit your <literal>$JETTY_HOME/etc/jetty.xml</literal> file so
  2051. the <literal>&lt;Configure class&gt;</literal> section has a new
  2052. addRealm call:</para>
  2053. <para><programlisting> &lt;Call name="addRealm"&gt;
  2054. &lt;Arg&gt;
  2055. &lt;New class="net.sf.acegisecurity.adapters.jetty.JettyAcegiUserRealm"&gt;
  2056. &lt;Arg&gt;Spring Powered Realm&lt;/Arg&gt;
  2057. &lt;Arg&gt;my_password&lt;/Arg&gt;
  2058. &lt;Arg&gt;etc/acegisecurity.xml&lt;/Arg&gt;
  2059. &lt;/New&gt;
  2060. &lt;/Arg&gt;
  2061. &lt;/Call&gt;</programlisting></para>
  2062. <para>Copy <literal>acegisecurity.xml</literal> into
  2063. <literal>$JETTY_HOME/etc</literal>.</para>
  2064. <para>Copy the following files into
  2065. <literal>$JETTY_HOME/ext</literal>:<itemizedlist>
  2066. <listitem>
  2067. <para><literal>aopalliance.jar</literal></para>
  2068. </listitem>
  2069. <listitem>
  2070. <para><literal>commons-logging.jar</literal></para>
  2071. </listitem>
  2072. <listitem>
  2073. <para><literal>spring.jar</literal></para>
  2074. </listitem>
  2075. <listitem>
  2076. <para><literal>acegi-security-jetty-ext.jar</literal></para>
  2077. </listitem>
  2078. <listitem>
  2079. <para><literal>commons-codec.jar</literal></para>
  2080. </listitem>
  2081. <listitem>
  2082. <para><literal>burlap.jar</literal></para>
  2083. </listitem>
  2084. <listitem>
  2085. <para><literal>hessian.jar</literal></para>
  2086. </listitem>
  2087. </itemizedlist></para>
  2088. <para>None of the above JAR files (or
  2089. <literal>acegi-security.jar</literal>) should be in your application's
  2090. <literal>WEB-INF/lib</literal>. The realm name indicated in your
  2091. <literal>web.xml</literal> does matter with Jetty. The
  2092. <literal>web.xml</literal> must express the same
  2093. <literal>&lt;realm-name&gt;</literal> as your
  2094. <literal>jetty.xml</literal> (in the example above, "Spring Powered
  2095. Realm").</para>
  2096. </sect2>
  2097. <sect2 id="security-container-adapters-joss">
  2098. <title>JBoss Installation</title>
  2099. <para>The following was tested with JBoss 3.2.3. We automatically test
  2100. the following directions using our container integration test system
  2101. and this version of JBoss.</para>
  2102. <para><literal>$JBOSS_HOME</literal> refers to the root of your JBoss
  2103. installation.</para>
  2104. <para>Edit your
  2105. <literal>$JBOSS_HOME/server/your_config/conf/login-config.xml</literal>
  2106. file so that it contains a new entry under the
  2107. <literal>&lt;Policy&gt;</literal> section:</para>
  2108. <para><programlisting> &lt;application-policy name = "SpringPoweredRealm"&gt;
  2109. &lt;authentication&gt;
  2110. &lt;login-module code = "net.sf.acegisecurity.adapters.jboss.JbossSpringLoginModule"
  2111. flag = "required"&gt;
  2112. &lt;module-option name = "appContextLocation"&gt;acegisecurity.xml&lt;/module-option&gt;
  2113. &lt;module-option name = "key"&gt;my_password&lt;/module-option&gt;
  2114. &lt;/login-module&gt;
  2115. &lt;/authentication&gt;
  2116. &lt;/application-policy&gt;</programlisting></para>
  2117. <para>Copy <literal>acegisecurity.xml</literal> into
  2118. <literal>$JBOSS_HOME/server/your_config/conf</literal>.</para>
  2119. <para>Copy the following files into
  2120. <literal>$JBOSS_HOME/server/your_config/lib</literal>:<itemizedlist>
  2121. <listitem>
  2122. <para><literal>aopalliance.jar</literal></para>
  2123. </listitem>
  2124. <listitem>
  2125. <para><literal>spring.jar</literal></para>
  2126. </listitem>
  2127. <listitem>
  2128. <para><literal>acegi-security-jboss-lib.jar</literal></para>
  2129. </listitem>
  2130. <listitem>
  2131. <para><literal>commons-codec.jar</literal></para>
  2132. </listitem>
  2133. <listitem>
  2134. <para><literal>burlap.jar</literal></para>
  2135. </listitem>
  2136. <listitem>
  2137. <para><literal>hessian.jar</literal></para>
  2138. </listitem>
  2139. </itemizedlist></para>
  2140. <para>None of the above JAR files (or
  2141. <literal>acegi-security.jar</literal>) should be in your application's
  2142. <literal>WEB-INF/lib</literal>. The realm name indicated in your
  2143. <literal>web.xml</literal> does not matter with JBoss. However, your
  2144. web application's <literal>WEB-INF/jboss-web.xml</literal> must
  2145. express the same <literal>&lt;security-domain&gt;</literal> as your
  2146. <literal>login-config.xml</literal>. For example, to match the above
  2147. example, your <literal>jboss-web.xml</literal> would look like
  2148. this:</para>
  2149. <para><programlisting>&lt;jboss-web&gt;
  2150. &lt;security-domain&gt;java:/jaas/SpringPoweredRealm&lt;/security-domain&gt;
  2151. &lt;/jboss-web&gt;</programlisting></para>
  2152. </sect2>
  2153. <sect2 id="security-container-adapters-resin">
  2154. <title>Resin Installation</title>
  2155. <para>The following was tested with Resin 3.0.6.</para>
  2156. <para><literal>$RESIN_HOME</literal> refers to the root of your Resin
  2157. installation.</para>
  2158. <para>Resin provides several ways to support the container adapter. In
  2159. the instructions below we have elected to maximise consistency with
  2160. other container adapter configurations. This will allow Resin users to
  2161. simply deploy the sample application and confirm correct
  2162. configuration. Developers comfortable with Resin are naturally able to
  2163. use its capabilities to package the JARs with the web application
  2164. itself, and/or support single sign-on.</para>
  2165. <para>Copy the following files into
  2166. <literal>$RESIN_HOME/lib</literal>:<itemizedlist>
  2167. <listitem>
  2168. <para><literal>aopalliance.jar</literal></para>
  2169. </listitem>
  2170. <listitem>
  2171. <para><literal>commons-logging.jar</literal></para>
  2172. </listitem>
  2173. <listitem>
  2174. <para><literal>spring.jar</literal></para>
  2175. </listitem>
  2176. <listitem>
  2177. <para><literal>acegi-security-resin-lib.jar</literal></para>
  2178. </listitem>
  2179. <listitem>
  2180. <para><literal>commons-codec.jar</literal></para>
  2181. </listitem>
  2182. <listitem>
  2183. <para><literal>burlap.jar</literal></para>
  2184. </listitem>
  2185. <listitem>
  2186. <para><literal>hessian.jar</literal></para>
  2187. </listitem>
  2188. </itemizedlist></para>
  2189. <para>Unlike the container-wide <literal>acegisecurity.xml</literal>
  2190. files used by other container adapters, each Resin web application
  2191. will contain its own
  2192. <literal>WEB-INF/resin-acegisecurity.xml</literal> file. Each web
  2193. application will also contain a <literal>resin-web.xml</literal> file
  2194. which Resin uses to start the container adapter:</para>
  2195. <para><programlisting>&lt;web-app&gt;
  2196. &lt;authenticator&gt;
  2197. &lt;type&gt;net.sf.acegisecurity.adapters.resin.ResinAcegiAuthenticator&lt;/type&gt;
  2198. &lt;init&gt;
  2199. &lt;app-context-location&gt;WEB-INF/resin-acegisecurity.xml&lt;/app-context-location&gt;
  2200. &lt;key&gt;my_password&lt;/key&gt;
  2201. &lt;/init&gt;
  2202. &lt;/authenticator&gt;
  2203. &lt;/web-app&gt;</programlisting></para>
  2204. <para>With the basic configuration provided above, none of the JAR
  2205. files listed (or <literal>acegi-security.jar</literal>) should be in
  2206. your application's <literal>WEB-INF/lib</literal>. The realm name
  2207. indicated in your <literal>web.xml</literal> does not matter with
  2208. Resin, as the relevant authentication class is indicated by the
  2209. <literal>&lt;authenticator&gt;</literal> setting.</para>
  2210. </sect2>
  2211. </sect1>
  2212. <sect1 id="security-cas">
  2213. <title>Yale Central Authentication Service (CAS) Single Sign On</title>
  2214. <sect2 id="security-cas-overview">
  2215. <title>Overview</title>
  2216. <para>Yale University produces an enterprise-wide single sign on
  2217. system known as CAS. Unlike other initiatives, Yale's Central
  2218. Authentication Service is open source, widely used, simple to
  2219. understand, platform independent, and supports proxy capabilities. The
  2220. Acegi Security System for Spring fully supports CAS, and provides an
  2221. easy migration path from single-application deployments of Acegi
  2222. Security through to multiple-application deployments secured by an
  2223. enterprise-wide CAS server.</para>
  2224. <para>You can learn more about CAS at
  2225. <literal>http://www.yale.edu/tp/auth/</literal>. You will need to
  2226. visit this URL to download the CAS Server files. Whilst the Acegi
  2227. Security System for Spring includes two CAS libraries in the
  2228. "-with-dependencies" ZIP file, you will still need the CAS Java Server
  2229. Pages and <literal>web.xml</literal> to customise and deploy your CAS
  2230. server.</para>
  2231. </sect2>
  2232. <sect2 id="security-cas-how-cas-works">
  2233. <title>How CAS Works</title>
  2234. <para>Whilst the CAS web site above contains two documents that detail
  2235. the architecture of CAS, we present the general overview again here
  2236. within the context of the Acegi Security System for Spring. The
  2237. following refers to CAS 2.0, being the version of CAS that Acegi
  2238. Security System for Spring supports.</para>
  2239. <para>Somewhere in your enterprise you will need to setup a CAS
  2240. server. The CAS server is simply a standard WAR file, so there isn't
  2241. anything difficult about setting up your server. Inside the WAR file
  2242. you will customise the login and other single sign on pages displayed
  2243. to users. You will also need to specify in the web.xml a
  2244. <literal>PasswordHandler</literal>. The
  2245. <literal>PasswordHandler</literal> has a simple method that returns a
  2246. boolean as to whether a given username and password is valid. Your
  2247. <literal>PasswordHandler</literal> implementation will need to link
  2248. into some type of backend authentication repository, such as an LDAP
  2249. server or database.</para>
  2250. <para>If you are already running an existing CAS server instance, you
  2251. will have already established a <literal>PasswordHandler</literal>. If
  2252. you do not already have a <literal>PasswordHandler</literal>, you
  2253. might prefer to use the Acegi Security System for Spring
  2254. <literal>CasPasswordHandler</literal> class. This class delegates
  2255. through to the standard Acegi Security
  2256. <literal>AuthenticationManager</literal>, enabling you to use a
  2257. security configuration you might already have in place. You do not
  2258. need to use the <literal>CasPasswordHandler</literal> class on your
  2259. CAS server if you do not wish. The Acegi Security System for Spring
  2260. will function as a CAS client successfully irrespective of the
  2261. <literal>PasswordHandler</literal> you've chosen for your CAS
  2262. server.</para>
  2263. <para>Apart from the CAS server itself, the other key player is of
  2264. course the secure web applications deployed throughout your
  2265. enterprise. These web applications are known as "services". There are
  2266. two types of services: standard services and proxy services. A proxy
  2267. service is able to request resources from other services on behalf of
  2268. the user. This will be explained more fully later.</para>
  2269. <para>Services can be developed in a large variety of languages, due
  2270. to CAS 2.0's very light XML-based protocol. The Yale CAS home page
  2271. contains a clients archive which demonstrates CAS clients in Java,
  2272. Active Server Pages, Perl, Python and others. Naturally, Java support
  2273. is very strong given the CAS server is written in Java. You do not
  2274. need to use any of CAS' client classes in applications secured by the
  2275. Acegi Security System for Spring. This is handled transparently for
  2276. you.</para>
  2277. <para>The basic interaction between a web browser, CAS server and an
  2278. Acegi Security for System Spring secured service is as follows:</para>
  2279. <orderedlist>
  2280. <listitem>
  2281. <para>The web user is browsing the service's public pages. CAS or
  2282. Acegi Security is not involved.</para>
  2283. </listitem>
  2284. <listitem>
  2285. <para>The user eventually requests a page that is either secure or
  2286. one of the beans it uses is secure. Acegi Security's
  2287. <literal>SecurityEnforcementFilter</literal> will detect the
  2288. <literal>AuthenticationException</literal>.</para>
  2289. </listitem>
  2290. <listitem>
  2291. <para>Because the user's <literal>Authentication</literal> object
  2292. (or lack thereof) caused an
  2293. <literal>AuthenticationException</literal>, the
  2294. <literal>SecurityEnforcementFilter</literal> will call the
  2295. configured <literal>AuthenticationEntryPoint</literal>. If using
  2296. CAS, this will be the
  2297. <literal>CasProcessingFilterEntryPoint</literal> class.</para>
  2298. </listitem>
  2299. <listitem>
  2300. <para>The <literal>CasProcessingFilterEntry</literal> point will
  2301. redirect the user's browser to the CAS server. It will also
  2302. indicate a <literal>service</literal> parameter, which is the
  2303. callback URL for the Acegi Security service. For example, the URL
  2304. to which the browser is redirected might be
  2305. <literal>https://my.company.com/cas/login?service=https%3A%2F%2Fserver3.company.com%2Fwebapp%2Fj_acegi_cas_security_check</literal>.</para>
  2306. </listitem>
  2307. <listitem>
  2308. <para>After the user's browser redirects to CAS, they will be
  2309. prompted for their username and password. If the user presents a
  2310. session cookie which indicates they've previously logged on, they
  2311. will not be prompted to login again (there is an exception to this
  2312. procedure, which we'll cover later). CAS will use the
  2313. <literal>PasswordHandler</literal> discussed above to decide
  2314. whether the username and password is valid.</para>
  2315. </listitem>
  2316. <listitem>
  2317. <para>Upon successful login, CAS will redirect the user's browser
  2318. back to the original service. It will also include a
  2319. <literal>ticket</literal> parameter, which is an opaque string
  2320. representing the "service ticket". Continuing our earlier example,
  2321. the URL the browser is redirected to might be
  2322. <literal>https://server3.company.com/webapp/j_acegi_cas_security_check?ticket=ST-0-ER94xMJmn6pha35CQRoZ</literal>.</para>
  2323. </listitem>
  2324. <listitem>
  2325. <para>Back in the service web application, the
  2326. <literal>CasProcessingFilter</literal> is always listening for
  2327. requests to <literal>/j_acegi_cas_security_check</literal> (this
  2328. is configurable, but we'll use the defaults in this introduction).
  2329. The processing filter will construct a
  2330. <literal>UsernamePasswordAuthenticationToken</literal>
  2331. representing the service ticket. The principal will be equal to
  2332. <literal>CasProcessingFilter.CAS_STATEFUL_IDENTIFIER</literal>,
  2333. whilst the credentials will be the service ticket opaque value.
  2334. This authentication request will then be handed to the configured
  2335. <literal>AuthenticationManager</literal>.</para>
  2336. </listitem>
  2337. <listitem>
  2338. <para>The <literal>AuthenticationManager</literal> implementation
  2339. will be the <literal>ProviderManager</literal>, which is in turn
  2340. configured with the <literal>CasAuthenticationProvider</literal>.
  2341. The <literal>CasAuthenticationProvider</literal> only responds to
  2342. <literal>UsernamePasswordAuthenticationToken</literal>s containing
  2343. the CAS-specific principal (such as
  2344. <literal>CasProcessingFilter.CAS_STATEFUL_IDENTIFIER</literal>)
  2345. and <literal>CasAuthenticationToken</literal>s (discussed
  2346. later).</para>
  2347. </listitem>
  2348. <listitem>
  2349. <para><literal>CasAuthenticationProvider</literal> will validate
  2350. the service ticket using a <literal>TicketValidator</literal>
  2351. implementation. Acegi Security includes one implementation, the
  2352. <literal>CasProxyTicketValidator</literal>. This implementation a
  2353. ticket validation class included in the CAS client library. The
  2354. <literal>CasProxyTicketValidator</literal> makes a HTTPS request
  2355. to the CAS server in order to validate the service ticket. The
  2356. <literal>CasProxyTicketValidator</literal> may also include a
  2357. proxy callback URL, which is included in this example:
  2358. <literal>https://my.company.com/cas/proxyValidate?service=https%3A%2F%2Fserver3.company.com%2Fwebapp%2Fj_acegi_cas_security_check&amp;ticket=ST-0-ER94xMJmn6pha35CQRoZ&amp;pgtUrl=https://server3.company.com/webapp/casProxy/receptor</literal>.</para>
  2359. </listitem>
  2360. <listitem>
  2361. <para>Back on the CAS server, the proxy validation request will be
  2362. received. If the presented service ticket matches the service URL
  2363. the ticket was issued to, CAS will provide an affirmative response
  2364. in XML indicating the username. If any proxy was involved in the
  2365. authentication (discussed below), the list of proxies is also
  2366. included in the XML response.</para>
  2367. </listitem>
  2368. <listitem>
  2369. <para>[OPTIONAL] If the request to the CAS validation service
  2370. included the proxy callback URL (in the <literal>pgtUrl</literal>
  2371. parameter), CAS will include a <literal>pgtIou</literal> string in
  2372. the XML response. This <literal>pgtIou</literal> represents a
  2373. proxy-granting ticket IOU. The CAS server will then create its own
  2374. HTTPS connection back to the <literal>pgtUrl</literal>. This is to
  2375. mutually authenticate the CAS server and the claimed service URL.
  2376. The HTTPS connection will be used to send a proxy granting ticket
  2377. to the original web application. For example,
  2378. <literal>https://server3.company.com/webapp/casProxy/receptor?pgtIou=PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt&amp;pgtId=PGT-1-si9YkkHLrtACBo64rmsi3v2nf7cpCResXg5MpESZFArbaZiOKH</literal>.
  2379. We suggest you use CAS' <literal>ProxyTicketReceptor</literal>
  2380. servlet to receive these proxy-granting tickets, if they are
  2381. required.</para>
  2382. </listitem>
  2383. <listitem>
  2384. <para>The <literal>CasProxyTicketValidator</literal> will parse
  2385. the XML received from the CAS server. It will return to the
  2386. <literal>CasAuthenticationProvider</literal> a
  2387. <literal>TicketResponse</literal>, which includes the username
  2388. (mandatory), proxy list (if any were involved), and proxy-granting
  2389. ticket IOU (if the proxy callback was requested).</para>
  2390. </listitem>
  2391. <listitem>
  2392. <para>Next <literal>CasAuthenticationProvider</literal> will call
  2393. a configured <literal>CasProxyDecider</literal>. The
  2394. <literal>CasProxyDecider</literal> indicates whether the proxy
  2395. list in the <literal>TicketResponse</literal> is acceptable to the
  2396. service. Several implementations are provided with the Acegi
  2397. Security System: <literal>RejectProxyTickets</literal>,
  2398. <literal>AcceptAnyCasProxy</literal> and
  2399. <literal>NamedCasProxyDecider</literal>. These names are largely
  2400. self-explanatory, except <literal>NamedCasProxyDecider</literal>
  2401. which allows a <literal>List</literal> of trusted proxies to be
  2402. provided.</para>
  2403. </listitem>
  2404. <listitem>
  2405. <para><literal>CasAuthenticationProvider</literal> will next
  2406. request a <literal>CasAuthoritiesPopulator</literal> to advise the
  2407. <literal>GrantedAuthority</literal> objects that apply to the user
  2408. contained in the <literal>TicketResponse</literal>. Acegi Security
  2409. includes a <literal>DaoCasAuthoritiesPopulator</literal> which
  2410. simply uses the <literal>AuthenticationDao</literal>
  2411. infrastructure to find the <literal>UserDetails</literal> and
  2412. their associated <literal>GrantedAuthority</literal>s. Note that
  2413. the password and enabled/disabled status of
  2414. <literal>UserDetails</literal> returned by the
  2415. <literal>AuthenticationDao</literal> are ignored, as the CAS
  2416. server is responsible for authentication decisions.
  2417. <literal>DaoCasAuthoritiesPopulator</literal> is only concerned
  2418. with retrieving the <literal>GrantedAuthority</literal>s.</para>
  2419. </listitem>
  2420. <listitem>
  2421. <para>If there were no problems,
  2422. <literal>CasAuthenticationProvider</literal> constructs a
  2423. <literal>CasAuthenticationToken</literal> including the details
  2424. contained in the <literal>TicketResponse</literal> and the
  2425. <literal>GrantedAuthority</literal>s. The
  2426. <literal>CasAuthenticationToken</literal> contains the hash of a
  2427. key, so that the <literal>CasAuthenticationProvider</literal>
  2428. knows it created it.</para>
  2429. </listitem>
  2430. <listitem>
  2431. <para>Control then returns to
  2432. <literal>CasProcessingFilter</literal>, which places the created
  2433. <literal>CasAuthenticationToken</literal> into the
  2434. <literal>HttpSession</literal> attribute named
  2435. <literal>HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY</literal>.</para>
  2436. </listitem>
  2437. <listitem>
  2438. <para>The user's browser is redirected to the original page that
  2439. caused the <literal>AuthenticationException</literal>.</para>
  2440. </listitem>
  2441. <listitem>
  2442. <para>As the <literal>Authentication</literal> object is now in
  2443. the well-known location, it is handled like any other
  2444. authentication approach. Usually the
  2445. <literal>AutoIntegrationFilter</literal> will be used to associate
  2446. the <literal>Authentication</literal> object with the
  2447. <literal>ContextHolder</literal> for the duration of each
  2448. request.</para>
  2449. </listitem>
  2450. </orderedlist>
  2451. <para>It's good that you're still here! It might sound involved, but
  2452. you can relax as the Acegi Security System for Spring classes hide
  2453. much of the complexity. Let's now look at how this is
  2454. configured.</para>
  2455. </sect2>
  2456. <sect2 id="security-cas-install-server">
  2457. <title>CAS Server Installation (Optional)</title>
  2458. <para>As mentioned above, the Acegi Security System for Spring
  2459. includes a <literal>PasswordHandler</literal> that bridges your
  2460. existing <literal>AuthenticationManager</literal> into CAS. You do not
  2461. need to use this <literal>PasswordHandler</literal> to use Acegi
  2462. Security on the client side (any CAS
  2463. <literal>PasswordHandler</literal> will do).</para>
  2464. <para>To install, you will need to download and extract the CAS server
  2465. archive. We used version 2.0.12. There will be a
  2466. <literal>/web</literal> directory in the root of the deployment. Copy
  2467. an <literal>applicationContext.xml</literal> containing your
  2468. <literal>AuthenticationManager</literal> as well as the
  2469. <literal>CasPasswordHandler</literal> into the
  2470. <literal>/web/WEB-INF</literal> directory. A sample
  2471. <literal>applicationContext.xml</literal> is included below:</para>
  2472. <programlisting>&lt;bean id="inMemoryDaoImpl" class="net.sf.acegisecurity.providers.dao.memory.InMemoryDaoImpl"&gt;
  2473. &lt;property name="userMap"&gt;
  2474. &lt;value&gt;
  2475. marissa=koala,ROLES_IGNORED_BY_CAS
  2476. dianne=emu,ROLES_IGNORED_BY_CAS
  2477. scott=wombat,ROLES_IGNORED_BY_CAS
  2478. peter=opal,disabled,ROLES_IGNORED_BY_CAS
  2479. &lt;/value&gt;
  2480. &lt;/property&gt;
  2481. &lt;/bean&gt;
  2482. &lt;bean id="daoAuthenticationProvider" class="net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider"&gt;
  2483. &lt;property name="authenticationDao"&gt;&lt;ref bean="inMemoryDaoImpl"/&gt;&lt;/property&gt;
  2484. &lt;/bean&gt;
  2485. &lt;bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager"&gt;
  2486. &lt;property name="providers"&gt;
  2487. &lt;list&gt;
  2488. &lt;ref bean="daoAuthenticationProvider"/&gt;
  2489. &lt;/list&gt;
  2490. &lt;/property&gt;
  2491. &lt;/bean&gt;
  2492. &lt;bean id="casPasswordHandler" class="net.sf.acegisecurity.adapters.cas.CasPasswordHandler"&gt;
  2493. &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
  2494. &lt;/bean&gt;</programlisting>
  2495. <para>Note the granted authorities are ignored by CAS because it has
  2496. no way of communicating the granted authorities to calling
  2497. applications. CAS is only concerned with username and passwords (and
  2498. the enabled/disabled status).</para>
  2499. <para>Next you will need to edit the existing
  2500. <literal>/web/WEB-INF/web.xml</literal> file. Add (or edit in the case
  2501. of the <literal>authHandler</literal> property) the following
  2502. lines:</para>
  2503. <para><programlisting>&lt;context-param&gt;
  2504. &lt;param-name&gt;edu.yale.its.tp.cas.authHandler&lt;/param-name&gt;
  2505. &lt;param-value&gt;net.sf.acegisecurity.adapters.cas.CasPasswordHandlerProxy&lt;/param-value&gt;
  2506. &lt;/context-param&gt;
  2507. &lt;context-param&gt;
  2508. &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
  2509. &lt;param-value&gt;/WEB-INF/applicationContext.xml&lt;/param-value&gt;
  2510. &lt;/context-param&gt;
  2511. &lt;listener&gt;
  2512. &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;
  2513. &lt;/listener&gt;</programlisting></para>
  2514. <para>Copy the <literal>spring.jar</literal> and
  2515. <literal>acegi-security.jar</literal> files into
  2516. <literal>/web/WEB-INF/lib</literal>. Now use the <literal>ant
  2517. dist</literal> task in the <literal>build.xml</literal> in the root of
  2518. the directory structure. This will create
  2519. <literal>/lib/cas.war</literal>, which is ready for deployment to your
  2520. servlet container.</para>
  2521. <para>Note CAS heavily relies on HTTPS. You can't even test the system
  2522. without a HTTPS certificate. Whilst you should refer to your web
  2523. container's documentation on setting up HTTPS, if you need some
  2524. additional help or a test certificate you might like to check the
  2525. <literal>samples/contacts/etc/ssl</literal> directory.</para>
  2526. </sect2>
  2527. <sect2 id="security-cas-install-client">
  2528. <title>CAS Acegi Security System Client Installation</title>
  2529. <para>The web application side of CAS is made easy due to the Acegi
  2530. Security System for Spring. It is assumed you already know the basics
  2531. of using the Acegi Security System for Spring, so these are not
  2532. covered again below. Only the CAS-specific beans are mentioned.</para>
  2533. <para>You will need to add a <literal>ServiceProperties</literal> bean
  2534. to your application context. This represents your service:</para>
  2535. <para><programlisting>&lt;bean id="serviceProperties" class="net.sf.acegisecurity.ui.cas.ServiceProperties"&gt;
  2536. &lt;property name="service"&gt;&lt;value&gt;https://localhost:8443/contacts-cas/j_acegi_cas_security_check&lt;/value&gt;&lt;/property&gt;
  2537. &lt;property name="sendRenew"&gt;&lt;value&gt;false&lt;/value&gt;&lt;/property&gt;
  2538. &lt;/bean&gt;</programlisting></para>
  2539. <para>The <literal>service</literal> must equal a URL that will be
  2540. monitored by the <literal>CasProcessingFilter</literal>. The
  2541. <literal>sendRenew</literal> defaults to false, but should be set to
  2542. true if your application is particularly sensitive. What this
  2543. parameter does is tell the CAS login service that a single sign on
  2544. login is unacceptable. Instead, the user will need to re-enter their
  2545. username and password in order to gain access to the service.</para>
  2546. <para>The following beans should be configured to commence the CAS
  2547. authentication process:</para>
  2548. <para><programlisting>&lt;bean id="casProcessingFilter" class="net.sf.acegisecurity.ui.cas.CasProcessingFilter"&gt;
  2549. &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
  2550. &lt;property name="authenticationFailureUrl"&gt;&lt;value&gt;/casfailed.jsp&lt;/value&gt;&lt;/property&gt;
  2551. &lt;property name="defaultTargetUrl"&gt;&lt;value&gt;/&lt;/value&gt;&lt;/property&gt;
  2552. &lt;property name="filterProcessesUrl"&gt;&lt;value&gt;/j_acegi_cas_security_check&lt;/value&gt;&lt;/property&gt;
  2553. &lt;/bean&gt;
  2554. &lt;bean id="securityEnforcementFilter" class="net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter"&gt;
  2555. &lt;property name="filterSecurityInterceptor"&gt;&lt;ref bean="filterInvocationInterceptor"/&gt;&lt;/property&gt;
  2556. &lt;property name="authenticationEntryPoint"&gt;&lt;ref bean="casProcessingFilterEntryPoint"/&gt;&lt;/property&gt;
  2557. &lt;/bean&gt;
  2558. &lt;bean id="casProcessingFilterEntryPoint" class="net.sf.acegisecurity.ui.cas.CasProcessingFilterEntryPoint"&gt;
  2559. &lt;property name="loginUrl"&gt;&lt;value&gt;https://localhost:8443/cas/login&lt;/value&gt;&lt;/property&gt;
  2560. &lt;property name="serviceProperties"&gt;&lt;ref bean="serviceProperties"/&gt;&lt;/property&gt;
  2561. &lt;/bean&gt;</programlisting></para>
  2562. <para>You will also need to add the
  2563. <literal>CasProcessingFilter</literal> to web.xml:</para>
  2564. <para><programlisting>&lt;filter&gt;
  2565. &lt;filter-name&gt;Acegi CAS Processing Filter&lt;/filter-name&gt;
  2566. &lt;filter-class&gt;net.sf.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
  2567. &lt;init-param&gt;
  2568. &lt;param-name&gt;targetClass&lt;/param-name&gt;
  2569. &lt;param-value&gt;net.sf.acegisecurity.ui.cas.CasProcessingFilter&lt;/param-value&gt;
  2570. &lt;/init-param&gt;
  2571. &lt;/filter&gt;
  2572. &lt;filter-mapping&gt;
  2573. &lt;filter-name&gt;Acegi CAS Processing Filter&lt;/filter-name&gt;
  2574. &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
  2575. &lt;/filter-mapping&gt;</programlisting></para>
  2576. <para>The <literal>CasProcessingFilter</literal> has very similar
  2577. properties to the <literal>AuthenticationProcessingFilter</literal>
  2578. (used for form-based logins). Each property is
  2579. self-explanatory.</para>
  2580. <para>For CAS to operate, the
  2581. <literal>SecurityEnforcementFilter</literal> must have its
  2582. <literal>authenticationEntryPoint</literal> property set to the
  2583. <literal>CasProcessingFilterEntryPoint</literal> bean.</para>
  2584. <para>The <literal>CasProcessingFilterEntryPoint</literal> must refer
  2585. to the <literal>ServiceProperties</literal> bean (discussed above),
  2586. which provides the URL to the enterprise's CAS login server. This is
  2587. where the user's browser will be redirected.</para>
  2588. <para>Next you need to add an <literal>AuthenticationManager</literal>
  2589. that uses <literal>CasAuthenticationProvider</literal> and its
  2590. collaborators:</para>
  2591. <para><programlisting>&lt;bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager"&gt;
  2592. &lt;property name="providers"&gt;
  2593. &lt;list&gt;
  2594. &lt;ref bean="casAuthenticationProvider"/&gt;
  2595. &lt;/list&gt;
  2596. &lt;/property&gt;
  2597. &lt;/bean&gt;
  2598. &lt;bean id="casAuthenticationProvider" class="net.sf.acegisecurity.providers.cas.CasAuthenticationProvider"&gt;
  2599. &lt;property name="casAuthoritiesPopulator"&gt;&lt;ref bean="casAuthoritiesPopulator"/&gt;&lt;/property&gt;
  2600. &lt;property name="casProxyDecider"&gt;&lt;ref bean="casProxyDecider"/&gt;&lt;/property&gt;
  2601. &lt;property name="ticketValidator"&gt;&lt;ref bean="casProxyTicketValidator"/&gt;&lt;/property&gt;
  2602. &lt;property name="statelessTicketCache"&gt;&lt;ref bean="statelessTicketCache"/&gt;&lt;/property&gt;
  2603. &lt;property name="key"&gt;&lt;value&gt;my_password_for_this_auth_provider_only&lt;/value&gt;&lt;/property&gt;
  2604. &lt;/bean&gt;
  2605. &lt;bean id="casProxyTicketValidator" class="net.sf.acegisecurity.providers.cas.ticketvalidator.CasProxyTicketValidator"&gt;
  2606. &lt;property name="casValidate"&gt;&lt;value&gt;https://localhost:8443/cas/proxyValidate&lt;/value&gt;&lt;/property&gt;
  2607. &lt;property name="proxyCallbackUrl"&gt;&lt;value&gt;https://localhost:8443/contacts-cas/casProxy/receptor&lt;/value&gt;&lt;/property&gt;
  2608. &lt;property name="serviceProperties"&gt;&lt;ref bean="serviceProperties"/&gt;&lt;/property&gt;
  2609. &lt;!-- &lt;property name="trustStore"&gt;&lt;value&gt;/some/path/to/your/lib/security/cacerts&lt;/value&gt;&lt;/property&gt; --&gt;
  2610. &lt;/bean&gt;
  2611. &lt;bean id="statelessTicketCache" class="net.sf.acegisecurity.providers.cas.cache.EhCacheBasedTicketCache"&gt;
  2612. &lt;property name="minutesToIdle"&gt;&lt;value&gt;20&lt;/value&gt;&lt;/property&gt;
  2613. &lt;/bean&gt;
  2614. &lt;bean id="casAuthoritiesPopulator" class="net.sf.acegisecurity.providers.cas.populator.DaoCasAuthoritiesPopulator"&gt;
  2615. &lt;property name="authenticationDao"&gt;&lt;ref bean="inMemoryDaoImpl"/&gt;&lt;/property&gt;
  2616. &lt;/bean&gt;
  2617. &lt;bean id="casProxyDecider" class="net.sf.acegisecurity.providers.cas.proxy.RejectProxyTickets"/&gt;</programlisting></para>
  2618. <para>The beans are all reasonable self-explanatory if you refer back
  2619. to the "How CAS Works" section. Careful readers might notice one
  2620. surprise: the <literal>statelessTicketCache</literal> property of the
  2621. <literal>CasAuthenticationProvider</literal>. This is discussed in
  2622. detail in the "Advanced CAS Usage" section.</para>
  2623. <para>Note the <literal>CasProxyTicketValidator</literal> has a
  2624. remarked out <literal>trustStore</literal> property. This property
  2625. might be helpful if you experience HTTPS certificate issues. Also note
  2626. the <literal>proxyCallbackUrl</literal> is set so the service can
  2627. receive a proxy-granting ticket. As mentioned above, this is optional
  2628. and unnecessary if you do not require proxy-granting tickets. If you
  2629. do use this feature, you will need to configure a suitable servlet to
  2630. receive the proxy-granting tickets. We suggest you use CAS'
  2631. <literal>ProxyTicketReceptor</literal> by adding the following to your
  2632. web application's <literal>web.xml</literal>:</para>
  2633. <para><programlisting>&lt;servlet&gt;
  2634. &lt;servlet-name&gt;casproxy&lt;/servlet-name&gt;
  2635. &lt;servlet-class&gt;edu.yale.its.tp.cas.proxy.ProxyTicketReceptor&lt;/servlet-class&gt;
  2636. &lt;/servlet&gt;
  2637. &lt;servlet-mapping&gt;
  2638. &lt;servlet-name&gt;casproxy&lt;/servlet-name&gt;
  2639. &lt;url-pattern&gt;/casProxy/*&lt;/url-pattern&gt;
  2640. &lt;/servlet-mapping&gt;</programlisting></para>
  2641. <para>This completes the configuration of CAS. If you haven't made any
  2642. mistakes, your web application should happily work within the
  2643. framework of CAS single sign on. No other parts of the Acegi Security
  2644. System for Spring need to be concerned about the fact CAS handled
  2645. authentication.</para>
  2646. <para>There is also a <literal>contacts-cas.war</literal> file in the
  2647. sample applications directory. This sample application uses the above
  2648. settings and can be deployed to see CAS in operation.</para>
  2649. </sect2>
  2650. <sect2 id="security-cas-advanced-usage">
  2651. <title>Advanced CAS Usage</title>
  2652. <para>The <literal>CasAuthenticationProvider</literal> distinguishes
  2653. between stateful and stateless clients. A stateful client is
  2654. considered any that originates via the
  2655. <literal>CasProcessingFilter</literal>. A stateless client is any that
  2656. presents an authentication request via the
  2657. <literal>UsernamePasswordAuthenticationToken</literal> with a
  2658. principal equal to
  2659. <literal>CasProcessingFilter.CAS_STATELESS_IDENTIFIER</literal>.</para>
  2660. <para>Stateless clients are likely to be via remoting protocols such
  2661. as Hessian and Burlap. The <literal>BasicProcessingFilter</literal> is
  2662. still used in this case, but the remoting protocol client is expected
  2663. to present a username equal to the static string above, and a password
  2664. equal to a CAS service ticket. Clients should acquire a CAS service
  2665. ticket directly from the CAS server.</para>
  2666. <para>Because remoting protocols have no way of presenting themselves
  2667. within the context of a <literal>HttpSession</literal>, it isn't
  2668. possible to rely on the <literal>HttpSession</literal>'s
  2669. <literal>HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY</literal>
  2670. attribute to locate the <literal>CasAuthenticationToken</literal>.
  2671. Furthermore, because the CAS server invalidates a service ticket after
  2672. it has been validated by the <literal>TicketValidator</literal>,
  2673. presenting the same service ticket on subsequent requests will not
  2674. work. It is similarly very difficult to obtain a proxy-granting ticket
  2675. for a remoting protocol client, as they are often deployed on client
  2676. machines which rarely have HTTPS URLs that would be accessible to the
  2677. CAS server.</para>
  2678. <para>One obvious option is to not use CAS at all for remoting
  2679. protocol clients. However, this would eliminate many of the desirable
  2680. features of CAS.</para>
  2681. <para>As a middle-ground, the
  2682. <literal>CasAuthenticationProvider</literal> uses a
  2683. <literal>StatelessTicketCache</literal>. This is used solely for
  2684. requests with a principal equal to
  2685. <literal>CasProcessingFilter.CAS_STATELESS_IDENTIFIER</literal>. What
  2686. happens is the <literal>CasAuthenticationProvider</literal> will store
  2687. the resulting <literal>CasAuthenticationToken</literal> in the
  2688. <literal>StatelessTicketCache</literal>, keyed on the service ticket.
  2689. Accordingly, remoting protocol clients can present the same service
  2690. ticket and the <literal>CasAuthenticationProvider</literal> will not
  2691. need to contact the CAS server for validation (aside from the first
  2692. request).</para>
  2693. <para>The other aspect of advanced CAS usage involves creating proxy
  2694. tickets from the proxy-granting ticket. As indicated above, we
  2695. recommend you use CAS' <literal>ProxyTicketReceptor</literal> to
  2696. receive these tickets. The <literal>ProxyTicketReceptor</literal>
  2697. provides a static method that enables you to obtain a proxy ticket by
  2698. presenting the proxy-granting IOU ticket. You can obtain the
  2699. proxy-granting IOU ticket by calling
  2700. <literal>CasAuthenticationToken.getProxyGrantingTicketIou()</literal>.</para>
  2701. <para>It is hoped you find CAS integration easy and useful with the
  2702. Acegi Security System for Spring classes. Welcome to enterprise-wide
  2703. single sign on!</para>
  2704. </sect2>
  2705. </sect1>
  2706. <sect1 id="security-channels">
  2707. <title>Channel Security</title>
  2708. <sect2 id="security-channels-overview">
  2709. <title>Overview</title>
  2710. <para>In addition to coordinating the authentication and authorization
  2711. requirements of your application, the Acegi Security System for Spring
  2712. is also able to ensure unauthenticated web requests have certain
  2713. properties. These properties may include being of a particular
  2714. transport type, having a particular <literal>HttpSession</literal>
  2715. attribute set and so on. The most common requirement is for your web
  2716. requests to be received using a particular transport protocol, such as
  2717. HTTPS.</para>
  2718. <para>An important issue in considering transport security is that of
  2719. session hijacking. Your web container manages a
  2720. <literal>HttpSession</literal> by reference to a
  2721. <literal>jsessionid</literal> that is sent to user agents either via a
  2722. cookie or URL rewriting. If the <literal>jsessionid</literal> is ever
  2723. sent over HTTP, there is a possibility that session identifier can be
  2724. intercepted and used to impersonate the user after they complete the
  2725. authentication process. This is because most web containers maintain
  2726. the same session identifier for a given user, even after they switch
  2727. from HTTP to HTTPS pages.</para>
  2728. <para>If session hijacking is considered too significant a risk for
  2729. your particular application, the only option is to use HTTPS for every
  2730. request. This means the <literal>jsessionid</literal> is never sent
  2731. across an insecure channel. You will need to ensure your
  2732. <literal>web.xml</literal>-defined
  2733. <literal>&lt;welcome-file&gt;</literal> points to a HTTPS location,
  2734. and the application never directs the user to a HTTP location. The
  2735. Acegi Security System for Spring provides a solution to assist with
  2736. the latter.</para>
  2737. </sect2>
  2738. <sect2 id="security-channels-installation">
  2739. <title>Configuration</title>
  2740. <para>To utilise Acegi Security's channel security services, add the
  2741. following lines to <literal>web.xml</literal>:</para>
  2742. <para><programlisting>&lt;filter&gt;
  2743. &lt;filter-name&gt;Acegi Channel Processing Filter&lt;/filter-name&gt;
  2744. &lt;filter-class&gt;net.sf.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
  2745. &lt;init-param&gt;
  2746. &lt;param-name&gt;targetClass&lt;/param-name&gt;
  2747. &lt;param-value&gt;net.sf.acegisecurity.securechannel.ChannelProcessingFilter&lt;/param-value&gt;
  2748. &lt;/init-param&gt;
  2749. &lt;/filter&gt;
  2750. &lt;filter-mapping&gt;
  2751. &lt;filter-name&gt;Acegi Channel Processing Filter&lt;/filter-name&gt;
  2752. &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
  2753. &lt;/filter-mapping&gt;</programlisting></para>
  2754. <para>As usual when running <literal>FilterToBeanProxy</literal>, you
  2755. will also need to configure the filter in your application
  2756. context:</para>
  2757. <para><programlisting>&lt;bean id="channelProcessingFilter" class="net.sf.acegisecurity.securechannel.ChannelProcessingFilter"&gt;
  2758. &lt;property name="channelDecisionManager"&gt;&lt;ref bean="channelDecisionManager"/&gt;&lt;/property&gt;
  2759. &lt;property name="filterInvocationDefinitionSource"&gt;
  2760. &lt;value&gt;
  2761. CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
  2762. \A/secure/.*\Z=REQUIRES_SECURE_CHANNEL
  2763. \A/acegilogin.jsp.*\Z=REQUIRES_SECURE_CHANNEL
  2764. \A/j_acegi_security_check.*\Z=REQUIRES_SECURE_CHANNEL
  2765. \A.*\Z=REQUIRES_INSECURE_CHANNEL
  2766. &lt;/value&gt;
  2767. &lt;/property&gt;
  2768. &lt;/bean&gt;
  2769. &lt;bean id="channelDecisionManager" class="net.sf.acegisecurity.securechannel.ChannelDecisionManagerImpl"&gt;
  2770. &lt;property name="channelProcessors"&gt;
  2771. &lt;list&gt;
  2772. &lt;ref bean="secureChannelProcessor"/&gt;
  2773. &lt;ref bean="insecureChannelProcessor"/&gt;
  2774. &lt;/list&gt;
  2775. &lt;/property&gt;
  2776. &lt;/bean&gt;
  2777. &lt;bean id="secureChannelProcessor" class="net.sf.acegisecurity.securechannel.SecureChannelProcessor"/&gt;
  2778. &lt;bean id="insecureChannelProcessor" class="net.sf.acegisecurity.securechannel.InsecureChannelProcessor"/&gt;</programlisting></para>
  2779. <para>Like <literal>FilterSecurityInterceptor</literal>, Apache Ant
  2780. style paths are also supported by the
  2781. <literal>ChannelProcessingFilter</literal>.</para>
  2782. <para>The <literal>ChannelProcessingFilter</literal> operates by
  2783. filtering all web requests and determining the configuration
  2784. attributes that apply. It then delegates to the
  2785. <literal>ChannelDecisionManager</literal>. The default implementation,
  2786. <literal>ChannelDecisionManagerImpl</literal>, should suffice in most
  2787. cases. It simply delegates through the list of configured
  2788. <literal>ChannelProcessor</literal> instances. A
  2789. <literal>ChannelProcessor</literal> will review the request, and if it
  2790. is unhappy with the request (eg it was received across the incorrect
  2791. transport protocol), it will perform a redirect, throw an exception or
  2792. take whatever other action is appropriate.</para>
  2793. <para>Included with the Acegi Security System for Spring are two
  2794. concrete <literal>ChannelProcessor</literal> implementations:
  2795. <literal>SecureChannelProcessor</literal> ensures requests with a
  2796. configuration attribute of <literal>REQUIRES_SECURE_CHANNEL</literal>
  2797. are received over HTTPS, whilst
  2798. <literal>InsecureChannelProcessor</literal> ensures requests with a
  2799. configuration attribute of
  2800. <literal>REQUIRES_INSECURE_CHANNEL</literal> are received over HTTP.
  2801. Both implementations delegate to a
  2802. <literal>ChannelEntryPoint</literal> if the required transport
  2803. protocol is not used. The two <literal>ChannelEntryPoint</literal>
  2804. implementations included with Acegi Security simply redirect the
  2805. request to HTTP and HTTPS as appropriate. Appropriate defaults are
  2806. assigned to the <literal>ChannelProcessor</literal> implementations
  2807. for the configuration attribute keywords they respond to and the
  2808. <literal>ChannelEntryPoint</literal> they delegate to, although you
  2809. have the ability to override these using the application
  2810. context.</para>
  2811. <para>Note that the redirections are absolute (eg
  2812. http://www.company.com:8080/app/page), not relative (eg /app/page).
  2813. During testing it was discovered that Internet Explorer 6 Service Pack
  2814. 1 has a bug whereby it does not respond correctly to a redirection
  2815. instruction which also changes the port to use. Accordingly, absolute
  2816. URLs are used in conjunction with bug detection logic in the
  2817. <literal>PortResolverImpl</literal> that is wired up by default to
  2818. many Acegi Security beans. Please refer to the JavaDocs for
  2819. <literal>PortResolverImpl</literal> for further details.</para>
  2820. </sect2>
  2821. <sect2 id="security-channels-usage">
  2822. <title>Usage</title>
  2823. <para>Once configured, using the channel security filter is very easy.
  2824. Simply request pages without regard to the protocol (ie HTTP or HTTPS)
  2825. or port (eg 80, 8080, 443, 8443 etc). Obviously you'll still need a
  2826. way of making the initial request (probably via the
  2827. <literal>web.xml</literal> <literal>&lt;welcome-file&gt;</literal> or
  2828. a well-known home page URL), but once this is done the filter will
  2829. perform redirects as defined by your application context.</para>
  2830. <para>You can also add your own <literal>ChannelProcessor</literal>
  2831. implementations to the <literal>ChannelDecisionManagerImpl</literal>.
  2832. For example, you might set a <literal>HttpSession</literal> attribute
  2833. when a human user is detected via a "enter the contents of this
  2834. graphic" procedure. Your <literal>ChannelProcessor</literal> would
  2835. respond to say <literal>REQUIRES_HUMAN_USER</literal> configuration
  2836. attributes and redirect to an appropriate entry point to start the
  2837. human user validation process if the <literal>HttpSession</literal>
  2838. attribute is not currently set.</para>
  2839. <para>To decide whether a security check belongs in a
  2840. <literal>ChannelProcessor</literal> or an
  2841. <literal>AccessDecisionVoter</literal>, remember that the former is
  2842. designed to handle unauthenticated requests, whilst the latter is
  2843. designed to handle authenticated requests. The latter therefore has
  2844. access to the granted authorities of the authenticated principal. In
  2845. addition, problems detected by a <literal>ChannelProcessor</literal>
  2846. will generally cause a HTTP/HTTPS redirection so its requirements can
  2847. be met, whilst problems detected by an
  2848. <literal>AccessDecisionVoter</literal> will ultimately result in an
  2849. <literal>AccessDeniedException</literal> (depending on the governing
  2850. <literal>AccessDecisionManager</literal>).</para>
  2851. </sect2>
  2852. </sect1>
  2853. <sect1 id="acls">
  2854. <title>Instance-Based Access Control List (ACL) Security</title>
  2855. <sect2 id="acls-overview">
  2856. <title>Overview</title>
  2857. <para>THIS FEATURE WAS ADDED IN VERSION 0.6. WE WELCOME YOUR COMMENTS
  2858. AND IMPROVEMENTS.</para>
  2859. <para>Complex applications often will find the need to define access
  2860. permissions not simply at a web request or method invocation level.
  2861. Instead, security decisions need to comprise both who
  2862. (<literal>Authentication</literal>), where
  2863. (<literal>MethodInvocation</literal>) and what
  2864. (<literal>SomeDomainObject</literal>). In other words, authorization
  2865. decisions also need to consider the actual domain object instance
  2866. subject of a method invocation.</para>
  2867. <para>Imagine you're designing an application for a pet clinic. There
  2868. will be two main groups of users of your Spring-based application:
  2869. staff of the pet clinic, as well as the pet clinic's customers. The
  2870. staff will have access to all of the data, whilst your customers will
  2871. only be able to see their own customer records. To make it a little
  2872. more interesting, your customers can allow other users to see their
  2873. customer records, such as their "puppy preschool "mentor or president
  2874. of their local "Pony Club". Using Acegi Security System for Spring as
  2875. the foundation, you have several approaches that can be
  2876. used:<orderedlist>
  2877. <listitem>
  2878. <para>Write your business methods to enforce the security. You
  2879. could consult a collection within the
  2880. <literal>Customer</literal> domain object instance to determine
  2881. which users have access. By using the
  2882. <literal>ContextHolder.getContext()</literal> and casting it to
  2883. <literal>SecureContext</literal>, you'll be able to access the
  2884. <literal>Authentication</literal> object.</para>
  2885. </listitem>
  2886. <listitem>
  2887. <para>Write an <literal>AccessDecisionVoter</literal> to enforce
  2888. the security from the <literal>GrantedAuthority[]</literal>s
  2889. stored in the <literal>Authentication</literal> object. This
  2890. would mean your <literal>AuthenticationManager</literal> would
  2891. need to populate the <literal>Authentication</literal> with
  2892. custom <literal>GrantedAuthority</literal>[]s representing each
  2893. of the <literal>Customer</literal> domain object instances the
  2894. principal has access to.</para>
  2895. </listitem>
  2896. <listitem>
  2897. <para>Write an <literal>AccessDecisionVoter</literal> to enforce
  2898. the security and open the target <literal>Customer</literal>
  2899. domain object directly. This would mean your voter needs access
  2900. to a DAO that allows it to retrieve the
  2901. <literal>Customer</literal> object. It would then access the
  2902. <literal>Customer</literal> object's collection of approved
  2903. users and make the appropriate decision.</para>
  2904. </listitem>
  2905. </orderedlist></para>
  2906. <para>Each one of these approaches is perfectly legitimate. However,
  2907. the first couples your authorization checking to your business code.
  2908. The main problems with this include the enhanced difficulty of unit
  2909. testing and the fact it would be more difficult to reuse the
  2910. <literal>Customer</literal> authorization logic elsewhere. Obtaining
  2911. the <literal>GrantedAuthority[]</literal>s from the
  2912. <literal>Authentication</literal> object is also fine, but will not
  2913. scale to large numbers of <literal>Customer</literal>s. If a user
  2914. might be able to access 5,000 <literal>Customer</literal>s (unlikely
  2915. in this case, but imagine if it were a popular vet for a large Pony
  2916. Club!) the amount of memory consumed and time required to construct
  2917. the <literal>Authentication</literal> object would be undesirable. The
  2918. final method, opening the <literal>Customer</literal> directly from
  2919. external code, is probably the best of the three. It achieves
  2920. separation of concerns, and doesn't misuse memory or CPU cycles, but
  2921. it is still inefficient in that both the
  2922. <literal>AccessDecisionVoter</literal> and the eventual business
  2923. method itself will perform a call to the DAO responsible for
  2924. retrieving the <literal>Customer</literal> object. Two accesses per
  2925. method invocation is clearly undesirable. In addition, with every
  2926. approach listed you'll need to write your own access control list
  2927. (ACL) persistence and business logic from scratch.</para>
  2928. <para>Fortunately, there is another alternative, which we'll talk
  2929. about below.</para>
  2930. </sect2>
  2931. <sect2 id="acls-acl-package">
  2932. <title>The net.sf.acegisecurity.acl Package</title>
  2933. <para>The <literal>net.sf.acegisecurity.acl</literal> package is very
  2934. simple, comprising only a handful of interfaces and a single class. It
  2935. provides the basic foundation for access control list (ACL) lookups.
  2936. The central interface is <literal>AclManager</literal>, which is
  2937. defined by two methods:</para>
  2938. <para><programlisting>public AclEntry[] getAcls(java.lang.Object domainInstance);
  2939. public AclEntry[] getAcls(java.lang.Object domainInstance, Authentication authentication);</programlisting></para>
  2940. <para><literal>AclManager</literal> is intended to be used as a
  2941. collaborator against your business objects, or, more desirably,
  2942. <literal>AccessDecisionVoter</literal>s. This means you use Spring's
  2943. normal <literal>ApplicationContext</literal> features to wire up your
  2944. <literal>AccessDecisionVoter</literal> (or business method) with an
  2945. <literal>AclManager</literal>. Consideration was given to placing the
  2946. ACL information in the <literal>ContextHolder</literal>, but it was
  2947. felt this would be inefficient both in terms of memory usage as well
  2948. as the time spent loading potentially unused ACL information. The
  2949. trade-off of needing to wire up a collaborator for those objects
  2950. requiring ACL information is rather minor, particularly in a
  2951. Spring-managed application.</para>
  2952. <para>The first method of the <literal>AclManager</literal> will
  2953. return all ACLs applying to the domain object instance passed to it.
  2954. The second method does the same, but only returns those ACLs which
  2955. apply to the passed <literal>Authentication</literal> object.</para>
  2956. <para>The <literal>AclEntry</literal> interface returned by
  2957. <literal>AclManager</literal> is merely a marker interface. You will
  2958. need to provide an implementation that reflects that ACL permissions
  2959. for your application.</para>
  2960. <para>Rounding out the <literal>net.sf.acegisecurity.acl</literal>
  2961. package is an <literal>AclProviderManager</literal> class, with a
  2962. corresponding <literal>AclProvider</literal> interface.
  2963. <literal>AclProviderManager</literal> is a concrete implementation of
  2964. <literal>AclManager</literal>, which iterates through registered
  2965. <literal>AclProvider</literal>s. The first
  2966. <literal>AclProvider</literal> that indicates it can authoritatively
  2967. provide ACL information for the presented domain object instance will
  2968. be used. This is very similar to the
  2969. <literal>AuthenticationProvider</literal> interface used for
  2970. authentication.</para>
  2971. <para>With this background, let's now look at a usable ACL
  2972. implementation.</para>
  2973. </sect2>
  2974. <sect2 id="acls-masking">
  2975. <title>Integer Masked ACLs</title>
  2976. <para>Acegi Security System for Spring includes a production-quality
  2977. ACL provider implementation. The implementation is based on integer
  2978. masking, which is commonly used for ACL permissions given its
  2979. flexibility and speed. Anyone who has used Unix's
  2980. <literal>chmod</literal> command will know all about this type of
  2981. permission masking (eg <literal>chmod 777</literal>). You'll find the
  2982. classes and interfaces for the integer masking ACL package under
  2983. <literal>net.sf.acegisecurity.acl.basic</literal>.</para>
  2984. <para>Extending the <literal>AclEntry</literal> interface is a
  2985. <literal>BasicAclEntry</literal> interface, with the main methods
  2986. shown below:</para>
  2987. <para><programlisting>public AclObjectIdentity getAclObjectIdentity();
  2988. public AclObjectIdentity getAclObjectParentIdentity();
  2989. public int getMask();
  2990. public java.lang.Object getRecipient();</programlisting></para>
  2991. <para>As shown, each <literal>BasicAclEntry</literal> has four main
  2992. properties. The <literal>mask</literal> is the integer that represents
  2993. the permissions granted to the <literal>recipient</literal>. The
  2994. <literal>aclObjectIdentity</literal> is able to identify the domain
  2995. object instance for which the ACL applies, and the
  2996. <literal>aclObjectParentIdentity</literal> optionally specifies the
  2997. parent of the domain object instance. Multiple
  2998. <literal>BasicAclEntry</literal>s usually exist against a single
  2999. domain object instance, and as suggested by the parent identity
  3000. property, permissions granted higher in the object hierarchy will
  3001. trickle down and be inherited (unless blocked by integer zero).</para>
  3002. <para><literal>BasicAclEntry</literal> implementations typically
  3003. provide convenience methods, such as
  3004. <literal>isReadAllowed()</literal>, to avoid application classes
  3005. needing to perform bit masking themselves. The
  3006. <literal>SimpleAclEntry</literal> and
  3007. <literal>AbstractBasicAclEntry</literal> demonstrate and provide much
  3008. of this bit masking logic.</para>
  3009. <para>The <literal>AclObjectIdentity</literal> itself is merely a
  3010. marker interface, so you need to provide implementations for your
  3011. domain objects. However, the package does include a
  3012. <literal>NamedEntityObjectIdentity</literal> implementation which will
  3013. suit many needs. The <literal>NamedEntityObjectIdentity</literal>
  3014. identifies a given domain object instance by the classname of the
  3015. instance and the identity of the instance. A
  3016. <literal>NamedEntityObjectIdentity</literal> can be constructed
  3017. manually (by calling the constructor and providing the classname and
  3018. identity <literal>String</literal>s), or by passing in any domain
  3019. object that contains a <literal>getId()</literal> method.</para>
  3020. <para>The actual <literal>AclProvider</literal> implementation is
  3021. named <literal>BasicAclProvider</literal>. It has adopted a similar
  3022. design to that used by the authentication-related
  3023. <literal>DaoAuthenticationProvder</literal>. Specifically, you define
  3024. a <literal>BasicAclDao</literal> against the provider, so different
  3025. ACL repository types can be accessed in a pluggable manner. The
  3026. <literal>BasicAclProvider</literal> also supports pluggable cache
  3027. providers (with Acegi Security System for Spring including an
  3028. implementation that fronts EH-CACHE).</para>
  3029. <para>The <literal>BasicAclDao</literal> interface is very simple to
  3030. implement:</para>
  3031. <para><programlisting>public BasicAclEntry[] getAcls(AclObjectIdentity aclObjectIdentity);</programlisting></para>
  3032. <para>A <literal>BasicAclDao</literal> implementation needs to
  3033. understand the presented <literal>AclObjectIdentity</literal> and how
  3034. it maps to a storage repository, find the relevant records, and create
  3035. appropriate <literal>BasicAclEntry</literal> objects and return
  3036. them.</para>
  3037. <para>Acegi Security includes a single <literal>BasicAclDao</literal>
  3038. implementation called <literal>JdbcDaoImpl</literal>. As implied by
  3039. the name, it accesses ACL information from a JDBC database. The
  3040. default database schema and some sample data will aid in understanding
  3041. its function:</para>
  3042. <para><programlisting>CREATE TABLE acl_object_identity (
  3043. id IDENTITY NOT NULL,
  3044. object_identity VARCHAR_IGNORECASE(250) NOT NULL,
  3045. parent_object INTEGER,
  3046. acl_class VARCHAR_IGNORECASE(250) NOT NULL,
  3047. CONSTRAINT unique_object_identity UNIQUE(object_identity),
  3048. FOREIGN KEY (parent_object) REFERENCES acl_object_identity(id)
  3049. );
  3050. CREATE TABLE acl_permission (
  3051. id IDENTITY NOT NULL,
  3052. acl_object_identity INTEGER NOT NULL,
  3053. recipient VARCHAR_IGNORECASE(100) NOT NULL,
  3054. mask INTEGER NOT NULL,
  3055. CONSTRAINT unique_recipient UNIQUE(acl_object_identity, recipient),
  3056. FOREIGN KEY (acl_object_identity) REFERENCES acl_object_identity(id)
  3057. );
  3058. INSERT INTO acl_object_identity VALUES (1, 'corp.DomainObject:1', null, 'net.sf.acegisecurity.acl.basic.SimpleAclEntry');
  3059. INSERT INTO acl_object_identity VALUES (2, 'corp.DomainObject:2', 1, 'net.sf.acegisecurity.acl.basic.SimpleAclEntry');
  3060. INSERT INTO acl_object_identity VALUES (3, 'corp.DomainObject:3', 1, 'net.sf.acegisecurity.acl.basic.SimpleAclEntry');
  3061. INSERT INTO acl_object_identity VALUES (4, 'corp.DomainObject:4', 1, 'net.sf.acegisecurity.acl.basic.SimpleAclEntry');
  3062. INSERT INTO acl_object_identity VALUES (5, 'corp.DomainObject:5', 3, 'net.sf.acegisecurity.acl.basic.SimpleAclEntry');
  3063. INSERT INTO acl_object_identity VALUES (6, 'corp.DomainObject:6', 3, 'net.sf.acegisecurity.acl.basic.SimpleAclEntry');
  3064. INSERT INTO acl_permission VALUES (null, 1, 'ROLE_SUPERVISOR', 1);
  3065. INSERT INTO acl_permission VALUES (null, 2, 'ROLE_SUPERVISOR', 0);
  3066. INSERT INTO acl_permission VALUES (null, 2, 'marissa', 2);
  3067. INSERT INTO acl_permission VALUES (null, 3, 'scott', 14);
  3068. INSERT INTO acl_permission VALUES (null, 6, 'scott', 1);</programlisting></para>
  3069. <para>As can be seen, database-specific constraints are used
  3070. extensively to ensure the integrity of the ACL information. If you
  3071. need to use a different database (Hypersonic SQL statements are shown
  3072. above), you should try to implement equivalent constraints.</para>
  3073. <para>The <literal>JdbcDaoImpl</literal> will only respond to requests
  3074. for <literal>NamedEntityObjectIdentity</literal>s. It converts such
  3075. identities into a single <literal>String</literal>, comprising
  3076. the<literal> NamedEntityObjectIdentity.getClassname()</literal> +
  3077. <literal>":"</literal> +
  3078. <literal>NamedEntityObjectIdentity.getId()</literal>. This yields the
  3079. type of <literal>object_identity</literal> values shown above. As
  3080. indicated by the sample data, each database row corresponds to a
  3081. single <literal>BasicAclEntry</literal>. As stated earlier and
  3082. demonstrated by <literal>corp.DomainObject:2</literal> in the above
  3083. sample data, each domain object instance will often have multiple
  3084. <literal>BasicAclEntry</literal>[]s.</para>
  3085. <para>As <literal>JdbcDaoImpl</literal> is required to return concrete
  3086. <literal>BasicAclEntry</literal> classes, it needs to know which
  3087. <literal>BasicAclEntry</literal> implementation it is to create and
  3088. populate. This is the role of the <literal>acl_class</literal> column.
  3089. <literal>JdbcDaoImpl</literal> will create the indicated class and set
  3090. its <literal>mask</literal>, <literal>recipient</literal>,
  3091. <literal>aclObjectIdentity</literal> and
  3092. <literal>aclObjectParentIdentity</literal> properties.</para>
  3093. <para>As you can probably tell from the sample data, the
  3094. <literal>parent_object_identity</literal> value can either be null or
  3095. in the same format as the <literal>object_identity</literal>. If
  3096. non-null, <literal>JdbcDaoImpl</literal> will create a
  3097. <literal>NamedEntityObjectIdentity</literal> to place inside the
  3098. returned <literal>BasicAclEntry</literal> class.</para>
  3099. <para>Returning to the <literal>BasicAclProvider</literal>, before it
  3100. can poll the <literal>BasicAclDao</literal> implementation it needs to
  3101. convert the domain object instance it was passed into an
  3102. <literal>AclObjectIdentity</literal>.
  3103. <literal>BasicAclProvider</literal> has a <literal>protected
  3104. AclObjectIdentity obtainIdentity(Object domainInstance)</literal>
  3105. method that is responsible for this. As a protected method, it enables
  3106. subclasses to easily override. The normal implementation checks
  3107. whether the passed domain object instance implements the
  3108. <literal>AclObjectIdentityAware</literal> interface, which is merely a
  3109. getter for an <literal>AclObjectIdentity</literal>. If the domain
  3110. object does implement this interface, that is the identity returned.
  3111. If the domain object does not implement this interface, the method
  3112. will attempt to create an <literal>AclObjectIdentity</literal> by
  3113. passing the domain object instance to the constructor of a class
  3114. defined by the
  3115. <literal>BasicAclProvider.getDefaultAclObjectIdentity()</literal>
  3116. method. By default the defined class is
  3117. <literal>NamedEntityObjectIdentity</literal>, which was described in
  3118. more detail above. Therefore, you will need to either (i) provide a
  3119. <literal>getId()</literal> method on your domain objects, (ii)
  3120. implement <literal>AclObjectIdentityAware</literal> on your domain
  3121. objects, (iii) provide an alternative
  3122. <literal>AclObjectIdentity</literal> implementation that will accept
  3123. your domain object in its constructor, or (iv) override the
  3124. <literal>obtainIdentity(Object)</literal> method.</para>
  3125. <para>Once the <literal>AclObjectIdentity</literal> of the domain
  3126. object instance is determined, the <literal>BasicAclProvider</literal>
  3127. will poll the DAO to obtain its <literal>BasicAclEntry</literal>[]s.
  3128. If any of the entries returned by the DAO indicate there is a parent,
  3129. that parent will be polled, and the process will repeat until there is
  3130. no further parent. The permissions assigned to a
  3131. <literal>recipient</literal> closest to the domain object instance
  3132. will always take priority and override any inherited permissions. From
  3133. the sample data above, the following inherited permissions would
  3134. apply:</para>
  3135. <para><programlisting>--- Mask integer 0 = no permissions
  3136. --- Mask integer 1 = administer
  3137. --- Mask integer 2 = read
  3138. --- Mask integer 6 = read and write permissions
  3139. --- Mask integer 14 = read and write and create permissions
  3140. ---------------------------------------------------------------------
  3141. --- *** INHERITED RIGHTS FOR DIFFERENT INSTANCES AND RECIPIENTS ***
  3142. --- INSTANCE RECIPIENT PERMISSION(S) (COMMENT #INSTANCE)
  3143. ---------------------------------------------------------------------
  3144. --- 1 ROLE_SUPERVISOR Administer
  3145. --- 2 ROLE_SUPERVISOR None (overrides parent #1)
  3146. --- marissa Read
  3147. --- 3 ROLE_SUPERVISOR Administer (from parent #1)
  3148. --- scott Read, Write, Create
  3149. --- 4 ROLE_SUPERVISOR Administer (from parent #1)
  3150. --- 5 ROLE_SUPERVISOR Administer (from parent #3)
  3151. --- scott Read, Write, Create (from parent #3)
  3152. --- 6 ROLE_SUPERVISOR Administer (from parent #3)
  3153. --- scott Administer (overrides parent #3)</programlisting></para>
  3154. <para>So the above explains how a domain object instance has its
  3155. <literal>AclObjectIdentity</literal> discovered, and the
  3156. <literal>BasicAclDao</literal> will be polled successively until an
  3157. array of inherited permissions is constructed for the domain object
  3158. instance. The final step is to determine the
  3159. <literal>BasicAclEntry</literal>[]s that are actually applicable to a
  3160. given <literal>Authentication</literal> object.</para>
  3161. <para>As you would recall, the <literal>AclManager</literal> (and all
  3162. delegates, up to and including <literal>BasicAclProvider</literal>)
  3163. provides a method which returns only those
  3164. <literal>BasicAclEntry</literal>[]s applying to a passed
  3165. <literal>Authentication</literal> object.
  3166. <literal>BasicAclProvider</literal> delivers this functionality by
  3167. delegating the filtering operation to an
  3168. <literal>EffectiveAclsResolver</literal> implementation. The default
  3169. implementation,
  3170. <literal>GrantedAuthorityEffectiveAclsResolver</literal>, will iterate
  3171. through the <literal>BasicAclEntry</literal>[]s and include only those
  3172. where the <literal>recipient</literal> is equal to either the
  3173. <literal>Authentication</literal>'s <literal>principal</literal> or
  3174. any of the <literal>Authentication</literal>'s
  3175. <literal>GrantedAuthority</literal>[]s. Please refer to the JavaDocs
  3176. for more information.</para>
  3177. </sect2>
  3178. <sect2 id="acls-conclusion">
  3179. <title>Conclusion</title>
  3180. <para>Acegi Security's instance-specific ACL packages shield you from
  3181. much of the complexity of developing your own ACL approach. The
  3182. interfaces and classes detailed above provide a scalable, customisable
  3183. ACL solution that is decoupled from your application code. Whilst the
  3184. reference documentation may suggest complexity, the basic
  3185. implementation is able to support most typical applications
  3186. out-of-the-box.</para>
  3187. </sect2>
  3188. </sect1>
  3189. <sect1 id="security-filters">
  3190. <title>Filters</title>
  3191. <sect2 id="security-filters-overview">
  3192. <title>Overview</title>
  3193. <para>The Acegi Security System for Spring uses filters extensively.
  3194. Each filter is covered in detail in a respective section of this
  3195. document. This section includes information that applies to all
  3196. filters.</para>
  3197. </sect2>
  3198. <sect2 id="security-filters-filtertobeanproxy">
  3199. <title>FilterToBeanProxy</title>
  3200. <para>Most filters are configured using the
  3201. <literal>FilterToBeanProxy</literal>. An example configuration from
  3202. <literal>web.xml</literal> follows:</para>
  3203. <para><programlisting>&lt;filter&gt;
  3204. &lt;filter-name&gt;Acegi HTTP Request Security Filter&lt;/filter-name&gt;
  3205. &lt;filter-class&gt;net.sf.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
  3206. &lt;init-param&gt;
  3207. &lt;param-name&gt;targetClass&lt;/param-name&gt;
  3208. &lt;param-value&gt;net.sf.acegisecurity.ClassThatImplementsFilter&lt;/param-value&gt;
  3209. &lt;/init-param&gt;
  3210. &lt;/filter&gt;</programlisting></para>
  3211. <para>Notice that the filter in <literal>web.xml</literal> is actually
  3212. a <literal>FilterToBeanProxy</literal>, and not the filter that will
  3213. actually implements the logic of the filter. What
  3214. <literal>FilterToBeanProxy</literal> does is delegate the
  3215. <literal>Filter</literal>'s methods through to a bean which is
  3216. obtained from the Spring application context. This enables the bean to
  3217. benefit from the Spring application context lifecycle support and
  3218. configuration flexibility. The bean must implement
  3219. <literal>javax.servlet.Filter</literal>.</para>
  3220. <para>The <literal>FilterToBeanProxy</literal> only requires a single
  3221. initialization parameter, <literal>targetClass</literal> or
  3222. <literal>targetBean</literal>. The <literal>targetClass</literal>
  3223. parameter locates the first object in the application context of the
  3224. specified class, whilst <literal>targetBean</literal> locates the
  3225. object by bean name. Like standard Spring web applications, the
  3226. <literal>FilterToBeanProxy</literal> accesses the application context
  3227. via<literal>
  3228. WebApplicationContextUtils.getWebApplicationContext(ServletContext)</literal>,
  3229. so you should configure a <literal>ContextLoaderListener</literal> in
  3230. <literal>web.xml</literal>.</para>
  3231. </sect2>
  3232. <sect2 id="security-filters-order">
  3233. <title>Filter Ordering</title>
  3234. <para>The order that filters are defined in <literal>web.xml</literal>
  3235. is important.</para>
  3236. <para>Irrespective of which filters you are actually using, the order
  3237. of the <literal>&lt;filter-mapping&gt;</literal>s should be as
  3238. follows:</para>
  3239. <orderedlist>
  3240. <listitem>
  3241. <para>Acegi Channel Processing Filter
  3242. (<literal>ChannelProcessingFilter</literal>)</para>
  3243. </listitem>
  3244. <listitem>
  3245. <para>Acegi Authentication Processing Filter
  3246. (<literal>AuthenticationProcessingFilter</literal>)</para>
  3247. </listitem>
  3248. <listitem>
  3249. <para>Acegi CAS Processing Filter
  3250. (<literal>CasProcessingFilter</literal>)</para>
  3251. </listitem>
  3252. <listitem>
  3253. <para>Acegi HTTP BASIC Authorization Filter
  3254. (<literal>BasicProcessingFilter</literal>)</para>
  3255. </listitem>
  3256. <listitem>
  3257. <para>Acegi Security System for Spring Auto Integration Filter
  3258. (<literal>AutoIntegrationFilter</literal>)</para>
  3259. </listitem>
  3260. <listitem>
  3261. <para>Acegi HTTP Request Security Filter
  3262. (<literal>SecurityEnforcementFilter</literal>)</para>
  3263. </listitem>
  3264. </orderedlist>
  3265. <para>All of the above filters use
  3266. <literal>FilterToBeanProxy</literal>, which is discussed in the
  3267. previous section.</para>
  3268. <para>If you're using SiteMesh, ensure the Acegi Security filters
  3269. execute before the SiteMesh filters are called. This enables the
  3270. <literal>ContextHolder</literal> to be populated in time for use by
  3271. SiteMesh decorators.</para>
  3272. </sect2>
  3273. </sect1>
  3274. <sect1 id="security-sample">
  3275. <title>Contacts Sample Application</title>
  3276. <para>Included with the Acegi Security System for Spring is a very
  3277. simple application that can demonstrate the basic security facilities
  3278. provided by the system (and confirm your Container Adapter is properly
  3279. configured if you're using one).</para>
  3280. <para>The Contacts sample application includes two deployable versions:
  3281. <literal>contacts.war</literal> is configured with the HTTP Session
  3282. Authentication approach, and does not use Container Adapters. The
  3283. <literal>contacts-container-adapter.war</literal> is configured to use a
  3284. Container Adapter. If you're just wanting to see how the sample
  3285. application works, please use <literal>contacts.war</literal> as it does
  3286. not require special configuration of your container.</para>
  3287. <para>If you are going to use the
  3288. <literal>contacts-container-adapter.war</literal> version, first
  3289. configure your container as described in the Container Adapters section
  3290. of this chapter. Do not modify <literal>acegisecurity.xml</literal>. It
  3291. contains a very basic in-memory authentication configuration that is
  3292. compatible with the sample application.</para>
  3293. <para>To deploy, simply copy the relevant
  3294. <literal>contacts.war</literal> or
  3295. <literal>contacts-container-adapter.war</literal> file from the Acegi
  3296. Security System for Spring distribution into your container’s
  3297. <literal>webapps</literal> directory.</para>
  3298. <para>After starting your container, check the application can load.
  3299. Visit <literal>http://localhost:8080/contacts</literal> (or whichever
  3300. URL is appropriate for your web container and the WAR you deployed). A
  3301. random contact should be displayed. Click "Refresh" several times and
  3302. you will see different contacts. The business method that provides this
  3303. random contact is not secured.</para>
  3304. <para>Next, click "Debug". You will be prompted to authenticate, and a
  3305. series of usernames and passwords are suggested on that page. Simply
  3306. authenticate with any of these and view the resulting page. It should
  3307. contain a success message similar to the following:</para>
  3308. <blockquote>
  3309. <para>Context on ContextHolder is of type:
  3310. net.sf.acegisecurity.context.SecureContextImpl</para>
  3311. <para>The Context implements SecureContext.</para>
  3312. <para>Authentication object is of type:
  3313. net.sf.acegisecurity.adapters.PrincipalAcegiUserToken</para>
  3314. <para>Authentication object as a String:
  3315. net.sf.acegisecurity.adapters.PrincipalAcegiUserToken@e9a7c2:
  3316. Username: marissa; Password: [PROTECTED]; Authenticated: true; Granted
  3317. Authorities: ROLE_TELLER, ROLE_SUPERVISOR</para>
  3318. <para>Authentication object holds the following granted
  3319. authorities:</para>
  3320. <para>ROLE_TELLER (getAuthority(): ROLE_TELLER)</para>
  3321. <para>ROLE_SUPERVISOR (getAuthority(): ROLE_SUPERVISOR)</para>
  3322. <para>SUCCESS! Your [container adapter|web filter] appears to be
  3323. properly configured!</para>
  3324. </blockquote>
  3325. <para>If you receive a different message, and deployed
  3326. <literal>contacts-container-adapter.war</literal>, check you have
  3327. properly configured your Container Adapter. Refer to the instructions
  3328. provided above.</para>
  3329. <para>Once you successfully receive the above message, return to the
  3330. sample application's home page and click "Manage". You can then try out
  3331. the application. Notice that only the contacts belonging to the
  3332. currently logged on user are displayed, and only users with
  3333. <literal>ROLE_SUPERVISOR</literal> are granted access to delete their
  3334. contacts. Behind the scenes, the
  3335. <literal>MethodSecurityInterceptor</literal> is securing the business
  3336. objects. If you're using <literal>contacts.war</literal>, the
  3337. <literal>FilterSecurityInterceptor</literal> is also securing the HTTP
  3338. requests. If using <literal>contacts.war</literal>, be sure to try
  3339. visiting <literal>http://localhost:8080/contacts/secure/super</literal>,
  3340. which will demonstrate access being denied by the
  3341. <literal>SecurityEnforcementFilter</literal>.</para>
  3342. <para>The Contacts sample application also include a
  3343. <literal>client</literal> directory. Inside you will find a small
  3344. application that queries the backend business objects using the Hessian
  3345. and Burlap protocols. This demonstrates how to use the Acegi Security
  3346. System for Spring for authentication with Spring remoting protocols. To
  3347. try this client, ensure your servlet container is still running the
  3348. Contacts sample application, and then execute <literal>client marissa
  3349. marissa koala</literal>. The command-line parameters respectively
  3350. represent the owner of the contacts to extract, the username to use, and
  3351. the password to use. Note that you may need to edit
  3352. <literal>client.properties</literal> to use a different target URL. To
  3353. see that security does indeed work, try running <literal>client scott
  3354. marissa koala</literal>, which will try to obtain
  3355. <literal>scott</literal>'s contacts when authenticating as
  3356. <literal>marissa</literal>. To see it work properly, use <literal>client
  3357. scott scott wombat</literal>.</para>
  3358. <para>Please note the sample application's <literal>client</literal>
  3359. does not currently support CAS. You can still give it a try, though, if
  3360. you're ambitious: try <literal>client scott _cas_stateless_
  3361. YOUR-SERVICE-TICKET-ID-FOR-SCOTT</literal>.</para>
  3362. </sect1>
  3363. <sect1 id="security-become-involved">
  3364. <title>Become Involved</title>
  3365. <para>We welcome you to become involved in the Acegi Security System for
  3366. Spring project. There are many ways of contributing, including reading
  3367. the mailing list and responding to questions from other people, writing
  3368. new code, improving existing code, assisting with documentation, or
  3369. simply making suggestions.</para>
  3370. <para>SourceForge provides CVS services for the project, allowing
  3371. anybody to access the latest code. If you wish to contribute new code,
  3372. please observe the following requirements. These exist to maintain the
  3373. quality and consistency of the project:</para>
  3374. <itemizedlist>
  3375. <listitem>
  3376. <para>Run the Ant <literal>format</literal> task (or use a suitable
  3377. IDE plug-in) to convert your code into the project's consistent
  3378. style</para>
  3379. </listitem>
  3380. <listitem>
  3381. <para>Ensure your code does not break any unit tests (run the Ant
  3382. <literal>tests</literal> target)</para>
  3383. </listitem>
  3384. <listitem>
  3385. <para>Please use the container integration test system to test your
  3386. code in the project's officially supported containers</para>
  3387. </listitem>
  3388. <listitem>
  3389. <para>When writing a new container adapter, expand the container
  3390. integration test system to properly test it</para>
  3391. </listitem>
  3392. <listitem>
  3393. <para>If you have added new code, please provide suitable unit tests
  3394. (use <literal>ant clover.html</literal> to view coverage)</para>
  3395. </listitem>
  3396. <listitem>
  3397. <para>Join the acegisecurity-developer and acegisecurity-cvs mailing
  3398. lists so you're in the loop</para>
  3399. </listitem>
  3400. <listitem>
  3401. <para>Use CamelCase</para>
  3402. </listitem>
  3403. <listitem>
  3404. <para>Add a CVS <literal>$Id: index.xml,v 1.3 2004/04/02 21:12:25
  3405. fbos Exp $</literal> tag to the JavaDocs for any new class you
  3406. create</para>
  3407. </listitem>
  3408. </itemizedlist>
  3409. <para>Mentioned above is our container integration test system, which
  3410. aims to test the Acegi Security System for Spring container adapters
  3411. with current, production versions of each container. Some containers
  3412. might not be supported due to difficulties with starting or stopping the
  3413. container within an Ant target. You will need to download the container
  3414. release files as specified in the integration test
  3415. <literal>readme.txt</literal> file. These files are intentionally
  3416. excluded from CVS due to their large size.</para>
  3417. </sect1>
  3418. <sect1 id="security-further">
  3419. <title>Further Information</title>
  3420. <para>Questions and comments on the Acegi Security System for Spring are
  3421. welcome. Please use the Spring Community Forum web site at
  3422. <literal>http://forum.springframework.org</literal>. You're also welcome
  3423. to join the acegisecurity-developer mailing list. Our project home page
  3424. (where you can obtain the latest release of the project and access to
  3425. CVS, mailing lists, forums etc) is at
  3426. <literal>http://acegisecurity.sourceforge.net</literal>.</para>
  3427. </sect1>
  3428. </chapter>
  3429. </book>