index.xml 222 KB

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