index.xml 223 KB

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