acegi.xml 291 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779
  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>1.0.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-release-numbering">
  83. <title>Release Numbering</title>
  84. <para>It is useful to understand how the Acegi Security release
  85. numbers work, as it will help you identify the effort (or lack
  86. thereof) involved in migrating to future releases of the project.
  87. Officially, we use the Apache Portable Runtime Project versioning
  88. guidelines, which can be viewed at
  89. <literal>http://apr.apache.org/versioning.html</literal>. We quote the
  90. introduction contained on that page for your convenience:</para>
  91. <para><quote>Versions are denoted using a standard triplet of
  92. integers: MAJOR.MINOR.PATCH. The basic intent is that MAJOR versions
  93. are incompatible, large-scale upgrades of the API. MINOR versions
  94. retain source and binary compatibility with older minor versions, and
  95. changes in the PATCH level are perfectly compatible, forwards and
  96. backwards.</quote></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>SecurityContextHolder</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"
  165. fileref="images/SecurityInterception.gif"
  166. format="GIF" />
  167. </imageobject>
  168. <caption>
  169. <para>Figure 1: The key "secure object" model</para>
  170. </caption>
  171. </mediaobject></para>
  172. <para>Each "secure object" interceptor (hereinafter called a "security
  173. interceptor") works with a particular type of "secure object". So,
  174. what is a secure object? Secure objects refer to any type of object
  175. that can have security applied to it. A secure object must provide
  176. some form of callback, so that the security interceptor can
  177. transparently do its work as required, and callback the object when it
  178. is time for it to proceed with the requested operation. If secure
  179. objects cannot provide a native callback approach, a wrapper needs to
  180. be written so this becomes possible.</para>
  181. <para>Each secure object has its own package under
  182. <literal>org.acegisecurity.intercept</literal>. Every other package in
  183. the security system is secure object independent, in that it can
  184. support any type of secure object presented.</para>
  185. <para>Only developers contemplating an entirely new way of
  186. intercepting and authorizing requests would need to use secure objects
  187. directly. For example, it would be possible to build a new secure
  188. object to secure calls to a messaging system that does not use
  189. <literal>MethodInvocation</literal>s. Most Spring applications will
  190. simply use the three currently supported secure object types (AOP
  191. Alliance <literal>MethodInvocation</literal>, AspectJ
  192. <literal>JoinPoint</literal> and web request
  193. <literal>FilterInterceptor</literal>) with complete
  194. transparency.</para>
  195. <para>Each of the eight key parts of Acegi Security are discussed in
  196. detail throughout this document.</para>
  197. </sect2>
  198. <sect2 id="security-high-level-design-supported-secure-objects">
  199. <title>Supported Secure Objects</title>
  200. <para>As shown in the base of Figure 1, the Acegi Security System for
  201. Spring currently supports three secure objects.</para>
  202. <para>The first handles an AOP Alliance
  203. <literal>MethodInvocation</literal>. This is the secure object type
  204. used to protect Spring beans. Developers will generally use this
  205. secure object type to secure their business objects. To make a
  206. standard Spring-hosted bean available as a
  207. <literal>MethodInvocation</literal>, the bean is simply published
  208. through a <literal>ProxyFactoryBean</literal> or
  209. <literal>BeanNameAutoProxyCreator</literal> or
  210. <literal>DefaultAdvisorAutoProxyCreator</literal>. Most Spring
  211. developers would already be familiar with these due to their use in
  212. transactions and other areas of Spring.</para>
  213. <para>The second type is an AspectJ <literal>JoinPoint</literal>.
  214. AspectJ has a particular use in securing domain object instances, as
  215. these are most often managed outside the Spring bean container. By
  216. using AspectJ, standard constructs such as <literal>new
  217. Person();</literal> can be used and full security will be applied to
  218. them by Acegi Security. The
  219. <literal>AspectJSecurityInterceptor</literal> is still managed by
  220. Spring, which creates the aspect singleton and wires it with the
  221. appropriate authentication managers, access decision managers and so
  222. on.</para>
  223. <para>The third type is a <literal>FilterInvocation</literal>. This is
  224. an object included with the Acegi Security System for Spring. It is
  225. created by an included filter and simply wraps the HTTP
  226. <literal>ServletRequest</literal>, <literal>ServletResponse</literal>
  227. and <literal>FilterChain</literal>. The
  228. <literal>FilterInvocation</literal> enables HTTP resources to be
  229. secured. Developers do not usually need to understand the mechanics of
  230. how this works, because they just add the filters to their
  231. <literal>web.xml</literal> and let the security system do its
  232. work.</para>
  233. </sect2>
  234. <sect2 id="security-high-level-design-configuration-attributes">
  235. <title>Configuration Attributes</title>
  236. <para>Every secure object can represent an infinite number of
  237. individual requests. For example, a
  238. <literal>MethodInvocation</literal> can represent the invocation of
  239. any method with any arguments, whilst a
  240. <literal>FilterInvocation</literal> can represent any HTTP URL.</para>
  241. <para>The Acegi Security System for Spring needs to record the
  242. configuration that applies to each of these possible requests. The
  243. security configuration of a request to
  244. <literal>BankManager.getBalance(int accountNumber)</literal> needs to
  245. be very different from the security configuration of a request to
  246. <literal>BankManager.approveLoan(int applicationNumber)</literal>.
  247. Similarly, the security configuration of a request to
  248. <literal>http://some.bank.com/index.htm</literal> needs to be very
  249. different from the security configuration of
  250. <literal>http://some.bank.com/manage/timesheet.jsp</literal>.</para>
  251. <para>To store the various security configurations associated with
  252. different requests, a configuration attribute is used. At an
  253. implementation level a configuration attribute is represented by the
  254. <literal>ConfigAttribute</literal> interface. One concrete
  255. implementation of <literal>ConfigAttribute</literal> is provided,
  256. <literal>SecurityConfig</literal>, which simply stores a configuration
  257. attribute as a <literal>String</literal>.</para>
  258. <para>The collection of <literal>ConfigAttribute</literal>s associated
  259. with a particular request is held in a
  260. <literal>ConfigAttributeDefinition</literal>. This concrete class is
  261. simply a holder of <literal>ConfigAttribute</literal>s and does
  262. nothing special.</para>
  263. <para>When a request is received by the security interceptor, it needs
  264. to determine which configuration attributes apply. In other words, it
  265. needs to find the <literal>ConfigAttributeDefinition</literal> which
  266. applies to the request. This decision is handled by the
  267. <literal>ObjectDefinitionSource</literal> interface. The main method
  268. provided by this interface is <literal>public
  269. ConfigAttributeDefinition getAttributes(Object object)</literal>, with
  270. the <literal>Object</literal> being the secure object. Recall the
  271. secure object contains details of the request, so the
  272. <literal>ObjectDefinitionSource</literal> implementation will be able
  273. to extract the details it requires to lookup the relevant
  274. <literal>ConfigAttributeDefinition</literal>.</para>
  275. </sect2>
  276. </sect1>
  277. <sect1 id="security-request-contexts">
  278. <title>Request Contexts</title>
  279. <sect2 id="security-contexts-history">
  280. <title>Historical Approach</title>
  281. <para>Prior to release 0.9.0, Acegi Security used a
  282. <literal>ContextHolder</literal> to store a <literal>Context</literal>
  283. between sessions. A particular subclass of <literal>Context</literal>,
  284. <literal>SecureContext</literal> defined an interface used for storage
  285. of the <literal>Authentication</literal> object. The
  286. <literal>ContextHolder</literal> was a <literal>ThreadLocal</literal>.
  287. A fuller discussion of the <literal>ThreadLocal</literal> usage with
  288. Acegi Security follows in this document.
  289. <literal>ContextHolder</literal> and <literal>SecureContext</literal>
  290. was removed from 0.9.0 after discussion with other Spring developers
  291. for the sake of consistency. See for example
  292. <literal>http://article.gmane.org/gmane.comp.java.springframework.devel/8290</literal>
  293. and JIRA task SEC-77. This history is mentioned as the long period
  294. <literal>ContextHolder</literal> was used will likely mean that
  295. certain documentation you encounter concerning Acegi Security might
  296. still refer to <literal>ContextHolder</literal>. Generally you can
  297. just substitute "<literal>SecurityContextHolder</literal>" for
  298. "<literal>ContextHolder</literal>", and
  299. "<literal>SecurityContext</literal>" for
  300. "<literal>SecureContext</literal>", and you'll have the primary
  301. meaning of such documentation.</para>
  302. </sect2>
  303. <sect2 id="security-contexts-security-context">
  304. <title>SecurityContext</title>
  305. <para>The Acegi Security System for Spring uses a
  306. <literal>SecurityContextHolder</literal> to store the
  307. <literal>SecurityContext</literal>. The
  308. <literal>SecurityContext</literal> contains a single getter/setter for
  309. <literal>Authentication</literal>. All Acegi Security classes query
  310. the <literal>SecurityContextHolder</literal> for obtaining the current
  311. <literal>SecurityContext</literal> (and in turn the principal).
  312. <literal>SecurityContextHolder</literal> is a
  313. <literal>ThreadLocal</literal>, meaning it is associated with the
  314. current thread of execution.</para>
  315. </sect2>
  316. <sect2 id="security-contexts-storage">
  317. <title>Context Storage</title>
  318. <para>Central to Acegi Security's design is that the contents of the
  319. <literal>SecurityContextHolder</literal> (which is simply a
  320. <literal>SecurityContext</literal> implementation) can be stored
  321. between web requests. This is so that a successfully authenticated
  322. principal can be identified on subsequent requests through the
  323. <literal>Authentication</literal> stored inside the
  324. <literal>SecurityContext</literal> obtained from the
  325. <literal>SecurityContextHolder</literal>. The
  326. <literal>HttpSessionContextIntegrationFilter</literal> exists to
  327. automatically copy the contents of a well-defined
  328. <literal>HttpSession</literal> attribute into the
  329. <literal>SecurityContextHolder</literal>, then at the end of each
  330. request, copy the <literal>SecurityContextHolder</literal> contents
  331. back into the <literal>HttpSession</literal> ready for next
  332. request.</para>
  333. <para>It is essential - and an extremely common error of end users -
  334. that <literal>HttpSessionContextIntegrationFilter</literal> appears
  335. before any other Acegi Security filter. Acegi Security filters expect
  336. to be able to modify the <literal>SecurityContextHolder</literal>
  337. contents as they see fit, and something else (namely
  338. <literal>HttpSessionContextIntegrationFilter</literal>) will store
  339. those between requests if necessary. This is why
  340. <literal>HttpSessionContextIntegrationFilter</literal> must be the
  341. first filter used.</para>
  342. <para>You can define a custom <literal>SecurityContext</literal>
  343. implementation be used in your application by setting the
  344. <literal>context</literal> property on the
  345. <literal>HttpSessionContextIntegrationFilter</literal> bean.</para>
  346. </sect2>
  347. <sect2 id="security-localization">
  348. <title>Localization</title>
  349. <para>From 1.0.0, Acegi Security supports localization of exception
  350. messages that end users are likely to see. Such exceptions include
  351. authentication failures and access being denied (authorization
  352. failures). Exceptions and logging that is focused on developers or
  353. system deployers (including incorrect attributes, interface contract
  354. violations, using incorrect constructors, startup time validation,
  355. debug-level logging) etc are not localized and instead are hard-coded
  356. in English within Acegi Security's code.</para>
  357. <para>Shipping in the <literal>acegi-security-xx.jar</literal> inside
  358. the <literal>org.acegisecurity</literal> package is a
  359. <literal>messages.properties</literal> file. This should be referred
  360. to by your <literal>ApplicationContext</literal>, as Acegi Security
  361. classes implement Spring's <literal>MessageSourceAware</literal>
  362. interface and expect the message resolver to be dependency injected at
  363. application context startup time. Usually all you need to do is
  364. register a bean inside your application context to refer to the
  365. messages. An example is shown below:</para>
  366. <para><programlisting>
  367. &lt;bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"&gt;
  368. &lt;property name="basename"&gt;&lt;value&gt;org/acegisecurity/messages&lt;/value&gt;&lt;/property&gt;
  369. &lt;/bean&gt;
  370. </programlisting></para>
  371. <para>The <literal>messages.properties</literal> is named in
  372. accordance with standard resource bundles and represents the default
  373. language supported by Acegi Securtiy messages. This default file is in
  374. English. If you do not register a message source, Acegi Security will
  375. still work correctly and fallback to hard-coded English versions of
  376. the messages.</para>
  377. <para>If you wish to customize the
  378. <literal>messages.properties</literal> file, or support other
  379. languages, you should copy the file, rename it accordingly, and
  380. register it inside the above bean definition. There are not a large
  381. number of message keys inside this file, so localization should not be
  382. considered a major initiative. If you do perform localization of this
  383. file, please consider sharing your work with the community by logging
  384. a JIRA task and attaching your appropriately-named localized version
  385. of <literal>messages.properties</literal>.</para>
  386. <para>Rounding out the discussion on localization is the Spring
  387. <literal>ThreadLocal</literal> known as
  388. <literal>org.springframework.context.i18n.LocaleContextHolder</literal>.
  389. You should set the <literal>LocaleContextHolder</literal> to represent
  390. the preferred <literal>Locale</literal> of each user. Acegi Security
  391. will attempt to locate a message from the message source using the
  392. <literal>Locale</literal> obtained from this
  393. <literal>ThreadLocal</literal>. Please refer to Spring documentation
  394. for further details on using <literal>LocaleContextHolder</literal>
  395. and the helper classes that can automatically set it for you (eg
  396. <literal>AcceptHeaderLocaleResolver</literal>,
  397. <literal>CookieLocaleResolver</literal>,
  398. <literal>FixedLocaleResolver</literal>,
  399. <literal>SessionLocaleResolver</literal> etc)</para>
  400. </sect2>
  401. </sect1>
  402. <sect1 id="security-interception">
  403. <title>Security Interception</title>
  404. <sect2 id="security-interception-all-secure-objects">
  405. <title>All Secure Objects</title>
  406. <para>As described in the High Level Design section, each secure
  407. object has its own security interceptor which is responsible for
  408. handling each request. Handling involves a number of
  409. operations:</para>
  410. <orderedlist>
  411. <listitem>
  412. <para>Store the configuration attributes that are associated with
  413. each secure request.</para>
  414. </listitem>
  415. <listitem>
  416. <para>Extract the <literal>ConfigAttributeDefinition</literal>
  417. that applies to the request from the relevant
  418. <literal>ObjectDefinitionSource</literal>.</para>
  419. </listitem>
  420. <listitem>
  421. <para>Obtain the <literal>Authentication</literal> object from the
  422. <literal>SecurityContext</literal>, which is held in the
  423. <literal>SecurityContextHolder</literal>.</para>
  424. </listitem>
  425. <listitem>
  426. <para>Pass the <literal>Authentication</literal> object to the
  427. <literal>AuthenticationManager</literal>, update the
  428. <literal>SecurityContextHolder</literal> with the response.</para>
  429. </listitem>
  430. <listitem>
  431. <para>Pass the <literal>Authentication</literal> object, the
  432. <literal>ConfigAttributeDefinition</literal>, and the secure
  433. object to the <literal>AccessDecisionManager</literal>.</para>
  434. </listitem>
  435. <listitem>
  436. <para>Pass the <literal>Authentication</literal> object, the
  437. <literal>ConfigAttributeDefinition</literal>, and the secure
  438. object to the <literal>RunAsManager</literal>.</para>
  439. </listitem>
  440. <listitem>
  441. <para>If the <literal>RunAsManager</literal> returns a new
  442. <literal>Authentication</literal> object, update the
  443. <literal>SecurityContextHolder</literal> with it.</para>
  444. </listitem>
  445. <listitem>
  446. <para>Proceed with the request execution of the secure
  447. object.</para>
  448. </listitem>
  449. <listitem>
  450. <para>If the <literal>RunAsManager</literal> earlier returned a
  451. new <literal>Authentication</literal> object, update the
  452. <literal>SecurityContextHolder</literal> with the
  453. <literal>Authentication</literal> object that was previously
  454. returned by the <literal>AuthenticationManager</literal>.</para>
  455. </listitem>
  456. <listitem>
  457. <para>If an <literal>AfterInvocationManager</literal> is defined,
  458. pass it the result of the secure object execution so that it may
  459. throw an <literal>AccessDeniedException</literal> or mutate the
  460. returned object if required.</para>
  461. </listitem>
  462. <listitem>
  463. <para>Return any result received from the
  464. <literal>AfterInvocationManager</literal>, or if no
  465. <literal>AfterInvocationManager</literal> is defined, simply
  466. return the result provided by the secure object execution.</para>
  467. </listitem>
  468. </orderedlist>
  469. <para>Whilst this may seem quite involved, don't worry. Developers
  470. interact with the security process by simply implementing basic
  471. interfaces (such as <literal>AccessDecisionManager</literal>), which
  472. are fully discussed below.</para>
  473. <para>The <literal>AbstractSecurityInterceptor</literal> handles the
  474. majority of the flow listed above. As shown in Figure 1, each secure
  475. object has its own security interceptor which subclasses
  476. <literal>AbstractSecurityInterceptor</literal>. Each of these secure
  477. object-specific security interceptors are discussed below.</para>
  478. </sect2>
  479. <sect2 id="security-interception-aopalliance">
  480. <title>AOP Alliance (MethodInvocation) Security Interceptor</title>
  481. <para>To secure <literal>MethodInvocation</literal>s, developers
  482. simply add a properly configured
  483. <literal>MethodSecurityInterceptor</literal> into the application
  484. context. Next the beans requiring security are chained into the
  485. interceptor. This chaining is accomplished using Spring’s
  486. <literal>ProxyFactoryBean</literal> or
  487. <literal>BeanNameAutoProxyCreator</literal>, as commonly used by many
  488. other parts of Spring (refer to the sample application for examples).
  489. Alternatively, Acegi Security provides a
  490. <literal>MethodDefinitionSourceAdvisor</literal> which may be used
  491. with Spring's <literal>DefaultAdvisorAutoProxyCreator</literal> to
  492. automatically chain the security interceptor in front of any beans
  493. defined against the <literal>MethodSecurityInterceptor</literal>. The
  494. <literal>MethodSecurityInterceptor</literal> itself is configured as
  495. follows:</para>
  496. <para><programlisting>
  497. &lt;bean id="bankManagerSecurity" class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor"&gt;
  498. &lt;property name="validateConfigAttributes"&gt;&lt;value&gt;true&lt;/value&gt;&lt;/property&gt;
  499. &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
  500. &lt;property name="accessDecisionManager"&gt;&lt;ref bean="accessDecisionManager"/&gt;&lt;/property&gt;
  501. &lt;property name="runAsManager"&gt;&lt;ref bean="runAsManager"/&gt;&lt;/property&gt;
  502. &lt;property name="afterInvocationManager"&gt;&lt;ref bean="afterInvocationManager"/&gt;&lt;/property&gt;
  503. &lt;property name="objectDefinitionSource"&gt;
  504. &lt;value&gt;
  505. org.acegisecurity.context.BankManager.delete*=ROLE_SUPERVISOR,RUN_AS_SERVER
  506. org.acegisecurity.context.BankManager.getBalance=ROLE_TELLER,ROLE_SUPERVISOR,BANKSECURITY_CUSTOMER,RUN_AS_SERVER
  507. &lt;/value&gt;
  508. &lt;/property&gt;
  509. &lt;/bean&gt;
  510. </programlisting></para>
  511. <para>As shown above, the <literal>MethodSecurityInterceptor</literal>
  512. is configured with a reference to an
  513. <literal>AuthenticationManager</literal>,
  514. <literal>AccessDecisionManager</literal> and
  515. <literal>RunAsManager</literal>, which are each discussed in separate
  516. sections below. In this case we've also defined an
  517. <literal>AfterInvocationManager</literal>, although this is entirely
  518. optional. The <literal>MethodSecurityInterceptor</literal> is also
  519. configured with configuration attributes that apply to different
  520. method signatures. A full discussion of configuration attributes is
  521. provided in the High Level Design section of this document.</para>
  522. <para>The <literal>MethodSecurityInterceptor</literal> can be
  523. configured with configuration attributes in three ways. The first is
  524. via a property editor and the application context, which is shown
  525. above. The second is via defining the configuration attributes in your
  526. source code using Jakarta Commons Attributes or Java 5 Annotations.
  527. The third is via writing your own
  528. <literal>ObjectDefinitionSource</literal>, although this is beyond the
  529. scope of this document. Irrespective of the approach used, the
  530. <literal>ObjectDefinitionSource</literal> is responsible for returning
  531. a <literal>ConfigAttributeDefinition</literal> object that contains
  532. all of the configuration attributes associated with a single secure
  533. method.</para>
  534. <para>It should be noted that the
  535. <literal>MethodSecurityInterceptor.setObjectDefinitionSource()</literal>
  536. method actually expects an instance of
  537. <literal>MethodDefinitionSource</literal>. This is a marker interface
  538. which subclasses <literal>ObjectDefinitionSource</literal>. It simply
  539. denotes the <literal>ObjectDefinitionSource</literal> understands
  540. <literal>MethodInvocation</literal>s. In the interests of simplicity
  541. we'll continue to refer to the
  542. <literal>MethodDefinitionSource</literal> as an
  543. <literal>ObjectDefinitionSource</literal>, as the distinction is of
  544. little relevance to most users of the
  545. <literal>MethodSecurityInterceptor</literal>.</para>
  546. <para>If using the application context property editor approach (as
  547. shown above), commas are used to delimit the different configuration
  548. attributes that apply to a given method pattern. Each configuration
  549. attribute is assigned into its own <literal>SecurityConfig</literal>
  550. object. The <literal>SecurityConfig</literal> object is discussed in
  551. the High Level Design section.</para>
  552. <para>If you are using the Jakarta Commons Attributes approach, your
  553. bean context will be configured differently:</para>
  554. <para><programlisting>
  555. &lt;bean id="attributes" class="org.springframework.metadata.commons.CommonsAttributes"/&gt;
  556. &lt;bean id="objectDefinitionSource" class="org.acegisecurity.intercept.method.MethodDefinitionAttributes"&gt;
  557. &lt;property name="attributes"&gt;&lt;ref local="attributes"/&gt;&lt;/property&gt;
  558. &lt;/bean&gt;
  559. &lt;bean id="bankManagerSecurity" class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor"&gt;
  560. &lt;property name="validateConfigAttributes"&gt;&lt;value&gt;false&lt;/value&gt;&lt;/property&gt;
  561. &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
  562. &lt;property name="accessDecisionManager"&gt;&lt;ref bean="accessDecisionManager"/&gt;&lt;/property&gt;
  563. &lt;property name="runAsManager"&gt;&lt;ref bean="runAsManager"/&gt;&lt;/property&gt;
  564. &lt;property name="objectDefinitionSource"&gt;&lt;ref bean="objectDefinitionSource"/&gt;&lt;/property&gt;
  565. &lt;/bean&gt;
  566. </programlisting></para>
  567. <para>In addition, your source code will contain Jakarta Commons
  568. Attributes tags that refer to a concrete implementation of
  569. <literal>ConfigAttribute</literal>. The following example uses the
  570. <literal>SecurityConfig</literal> implementation to represent the
  571. configuration attributes, and results in the same security
  572. configuration as provided by the property editor approach
  573. above:</para>
  574. <para><programlisting>public interface BankManager {
  575. /**
  576. * @@SecurityConfig("ROLE_SUPERVISOR")
  577. * @@SecurityConfig("RUN_AS_SERVER")
  578. */
  579. public void deleteSomething(int id);
  580. /**
  581. * @@SecurityConfig("ROLE_SUPERVISOR")
  582. * @@SecurityConfig("RUN_AS_SERVER")
  583. */
  584. public void deleteAnother(int id);
  585. /**
  586. * @@SecurityConfig("ROLE_TELLER")
  587. * @@SecurityConfig("ROLE_SUPERVISOR")
  588. * @@SecurityConfig("BANKSECURITY_CUSTOMER")
  589. * @@SecurityConfig("RUN_AS_SERVER")
  590. */
  591. public float getBalance(int id);
  592. }</programlisting></para>
  593. <para>If you are using the Spring Security Java 5 Annotations
  594. approach, your bean context will be configured as follows:</para>
  595. <para><programlisting>
  596. &lt;bean id="attributes" class="org.acegisecurity.annotation.SecurityAnnotationAttributes"/&gt;
  597. &lt;bean id="objectDefinitionSource" class="org.acegisecurity.intercept.method.MethodDefinitionAttributes"&gt;
  598. &lt;property name="attributes"&gt;&lt;ref local="attributes"/&gt;&lt;/property&gt;
  599. &lt;/bean&gt;
  600. &lt;bean id="bankManagerSecurity" class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor"&gt;
  601. &lt;property name="validateConfigAttributes"&gt;&lt;value&gt;false&lt;/value&gt;&lt;/property&gt;
  602. &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
  603. &lt;property name="accessDecisionManager"&gt;&lt;ref bean="accessDecisionManager"/&gt;&lt;/property&gt;
  604. &lt;property name="runAsManager"&gt;&lt;ref bean="runAsManager"/&gt;&lt;/property&gt;
  605. &lt;property name="objectDefinitionSource"&gt;&lt;ref bean="objectDefinitionSource"/&gt;&lt;/property&gt;
  606. &lt;/bean&gt;
  607. </programlisting></para>
  608. <para>In addition, your source code will contain the Acegi Java 5
  609. Security Annotations that represent the
  610. <literal>ConfigAttribute</literal>. The following example uses the
  611. <literal>@Secured</literal> annotations to represent the configuration
  612. attributes, and results in the same security configuration as provided
  613. by the property editor approach:</para>
  614. <para><programlisting>import org.acegisecurity.annotation.Secured;
  615. public interface BankManager {
  616. /**
  617. * Delete something
  618. */
  619. @Secured({"ROLE_SUPERVISOR","RUN_AS_SERVER" })
  620. public void deleteSomething(int id);
  621. /**
  622. * Delete another
  623. */
  624. @Secured({"ROLE_SUPERVISOR","RUN_AS_SERVER" })
  625. public void deleteAnother(int id);
  626. /**
  627. * Get balance
  628. */
  629. @Secured({"ROLE_TELLER","ROLE_SUPERVISOR","BANKSECURITY_CUSTOMER","RUN_AS_SERVER" })
  630. public float getBalance(int id);
  631. }</programlisting></para>
  632. <para>You might have noticed the
  633. <literal>validateConfigAttributes</literal> property in the above
  634. <literal>MethodSecurityInterceptor</literal> examples. When set to
  635. <literal>true</literal> (the default), at startup time the
  636. <literal>MethodSecurityInterceptor</literal> will evaluate if the
  637. provided configuration attributes are valid. It does this by checking
  638. each configuration attribute can be processed by either the
  639. <literal>AccessDecisionManager</literal> or the
  640. <literal>RunAsManager</literal>. If neither of these can process a
  641. given configuration attribute, an exception is thrown. If using the
  642. Jakarta Commons Attributes method of configuration, you should set
  643. <literal>validateConfigAttributes</literal> to
  644. <literal>false</literal>.</para>
  645. <para>Please note that when using
  646. <literal>BeanNameAutoProxyCreator</literal> to create the required
  647. proxy for security, the configuration must contain the property
  648. <literal>proxyTargetClass</literal> set to <literal>true</literal>.
  649. Otherwise, the method passed to
  650. <literal>MethodSecurityInterceptor.invoke</literal> is the proxy's
  651. caller, not the proxy's target. Note that this introduces a
  652. requirement on CGLIB. See an example of using
  653. <literal>BeanNameAutoProxyCreator</literal> below:</para>
  654. <para><programlisting>
  655. &lt;bean id="autoProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"&gt;
  656. &lt;property name="interceptorNames"&gt;
  657. &lt;list&gt;&lt;value&gt;methodSecurityInterceptor&lt;/value&gt;&lt;/list&gt;
  658. &lt;/property&gt;
  659. &lt;property name="beanNames"&gt;
  660. &lt;list&gt;&lt;value&gt;targetObjectName&lt;/value&gt;&lt;/list&gt;
  661. &lt;/property&gt;
  662. &lt;property name="proxyTargetClass" value="true"/&gt;
  663. &lt;/bean&gt;
  664. </programlisting></para>
  665. </sect2>
  666. <sect2 id="security-interception-aspectj">
  667. <title>AspectJ (JoinPoint) Security Interceptor</title>
  668. <para>The AspectJ security interceptor is very similar to the AOP
  669. Alliance security interceptor discussed in the previous section.
  670. Indeed we will only discuss the differences in this section.</para>
  671. <para>The AspectJ interceptor is named
  672. <literal>AspectJSecurityInterceptor</literal>. Unlike the AOP Alliance
  673. security interceptor, which relies on the Spring application context
  674. to weave in the security interceptor via proxying, the
  675. <literal>AspectJSecurityInterceptor</literal> is weaved in via the
  676. AspectJ compiler. It would not be uncommon to use both types of
  677. security interceptors in the same application, with
  678. <literal>AspectJSecurityInterceptor</literal> being used for domain
  679. object instance security and the AOP Alliance
  680. <literal>MethodSecurityInterceptor</literal> being used for services
  681. layer security.</para>
  682. <para>Let's first consider how the
  683. <literal>AspectJSecurityInterceptor</literal> is configured in the
  684. Spring application context:</para>
  685. <para><programlisting>
  686. &lt;bean id="bankManagerSecurity" class="org.acegisecurity.intercept.method.aspectj.AspectJSecurityInterceptor"&gt;
  687. &lt;property name="validateConfigAttributes"&gt;&lt;value&gt;true&lt;/value&gt;&lt;/property&gt;
  688. &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
  689. &lt;property name="accessDecisionManager"&gt;&lt;ref bean="accessDecisionManager"/&gt;&lt;/property&gt;
  690. &lt;property name="runAsManager"&gt;&lt;ref bean="runAsManager"/&gt;&lt;/property&gt;
  691. &lt;property name="afterInvocationManager"&gt;&lt;ref bean="afterInvocationManager"/&gt;&lt;/property&gt;
  692. &lt;property name="objectDefinitionSource"&gt;
  693. &lt;value&gt;
  694. org.acegisecurity.context.BankManager.delete*=ROLE_SUPERVISOR,RUN_AS_SERVER
  695. org.acegisecurity.context.BankManager.getBalance=ROLE_TELLER,ROLE_SUPERVISOR,BANKSECURITY_CUSTOMER,RUN_AS_SERVER
  696. &lt;/value&gt;
  697. &lt;/property&gt;
  698. &lt;/bean&gt;
  699. </programlisting></para>
  700. <para>As you can see, aside from the class name, the
  701. <literal>AspectJSecurityInterceptor</literal> is exactly the same as
  702. the AOP Alliance security interceptor. Indeed the two interceptors can
  703. share the same <literal>objectDefinitionSource</literal>, as the
  704. <literal>ObjectDefinitionSource</literal> works with
  705. <literal>java.lang.reflect.Method</literal>s rather than an AOP
  706. library-specific class. Of course, your access decisions have access
  707. to the relevant AOP library-specific invocation (ie
  708. <literal>MethodInvocation</literal> or <literal>JoinPoint</literal>)
  709. and as such can consider a range of addition criteria when making
  710. access decisions (such as method arguments).</para>
  711. <para>Next you'll need to define an AspectJ <literal>aspect</literal>.
  712. For example:</para>
  713. <para><programlisting>package org.acegisecurity.samples.aspectj;
  714. import org.acegisecurity.intercept.method.aspectj.AspectJSecurityInterceptor;
  715. import org.acegisecurity.intercept.method.aspectj.AspectJCallback;
  716. import org.springframework.beans.factory.InitializingBean;
  717. public aspect DomainObjectInstanceSecurityAspect implements InitializingBean {
  718. private AspectJSecurityInterceptor securityInterceptor;
  719. pointcut domainObjectInstanceExecution(): target(PersistableEntity)
  720. &amp;&amp; execution(public * *(..)) &amp;&amp; !within(DomainObjectInstanceSecurityAspect);
  721. Object around(): domainObjectInstanceExecution() {
  722. if (this.securityInterceptor != null) {
  723. AspectJCallback callback = new AspectJCallback() {
  724. public Object proceedWithObject() {
  725. return proceed();
  726. }
  727. };
  728. return this.securityInterceptor.invoke(thisJoinPoint, callback);
  729. } else {
  730. return proceed();
  731. }
  732. }
  733. public AspectJSecurityInterceptor getSecurityInterceptor() {
  734. return securityInterceptor;
  735. }
  736. public void setSecurityInterceptor(AspectJSecurityInterceptor securityInterceptor) {
  737. this.securityInterceptor = securityInterceptor;
  738. }
  739. public void afterPropertiesSet() throws Exception {
  740. if (this.securityInterceptor == null)
  741. throw new IllegalArgumentException("securityInterceptor required");
  742. }
  743. }</programlisting></para>
  744. <para>In the above example, the security interceptor will be applied
  745. to every instance of <literal>PersistableEntity</literal>, which is an
  746. abstract class not shown (you can use any other class or
  747. <literal>pointcut</literal> expression you like). For those curious,
  748. <literal>AspectJCallback</literal> is needed because the
  749. <literal>proceed();</literal> statement has special meaning only
  750. within an <literal>around()</literal> body. The
  751. <literal>AspectJSecurityInterceptor</literal> calls this anonymous
  752. <literal>AspectJCallback</literal> class when it wants the target
  753. object to continue.</para>
  754. <para>You will need to configure Spring to load the aspect and wire it
  755. with the <literal>AspectJSecurityInterceptor</literal>. A bean
  756. declaration which achieves this is shown below:</para>
  757. <para><programlisting>
  758. &lt;bean id="domainObjectInstanceSecurityAspect"
  759. class="org.acegisecurity.samples.aspectj.DomainObjectInstanceSecurityAspect"
  760. factory-method="aspectOf"&gt;
  761. &lt;property name="securityInterceptor"&gt;&lt;ref bean="aspectJSecurityInterceptor"/&gt;&lt;/property&gt;
  762. &lt;/bean&gt;
  763. </programlisting></para>
  764. <para>That's it! Now you can create your beans from anywhere within
  765. your application, using whatever means you think fit (eg <literal>new
  766. Person();</literal>) and they will have the security interceptor
  767. applied.</para>
  768. </sect2>
  769. <sect2 id="security-interception-filterinvocation">
  770. <title>FilterInvocation Security Interceptor</title>
  771. <para>To secure <literal>FilterInvocation</literal>s, developers need
  772. to add a filter to their <literal>web.xml</literal> that delegates to
  773. the <literal>FilterSecurityInterceptor</literal>. A typical
  774. configuration example is provided below: <programlisting>
  775. &lt;filter&gt;
  776. &lt;filter-name&gt;Acegi HTTP Request Security Filter&lt;/filter-name&gt;
  777. &lt;filter-class&gt;org.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
  778. &lt;init-param&gt;
  779. &lt;param-name&gt;targetClass&lt;/param-name&gt;
  780. &lt;param-value&gt;org.acegisecurity.intercept.web.FilterSecurityInterceptor&lt;/param-value&gt;
  781. &lt;/init-param&gt;
  782. &lt;/filter&gt;
  783. &lt;filter-mapping&gt;
  784. &lt;filter-name&gt;Acegi HTTP Request Security Filter&lt;/filter-name&gt;
  785. &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
  786. &lt;/filter-mapping&gt;
  787. </programlisting></para>
  788. <para>Notice that the filter is actually a
  789. <literal>FilterToBeanProxy</literal>. Most of the filters used by the
  790. Acegi Security System for Spring use this class. Refer to the Filters
  791. section to learn more about this bean.</para>
  792. <para>In the application context you will need to configure three
  793. beans:</para>
  794. <programlisting>
  795. &lt;bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter"&gt;
  796. &lt;property name="authenticationEntryPoint"&gt;&lt;ref local="authenticationEntryPoint"/&gt;&lt;/property&gt;
  797. &lt;/bean&gt;
  798. &lt;bean id="authenticationEntryPoint" class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint"&gt;
  799. &lt;property name="loginFormUrl"&gt;&lt;value&gt;/acegilogin.jsp&lt;/value&gt;&lt;/property&gt;
  800. &lt;property name="forceHttps"&gt;&lt;value&gt;false&lt;/value&gt;&lt;/property&gt;
  801. &lt;/bean&gt;
  802. &lt;bean id="filterSecurityInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor"&gt;
  803. &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
  804. &lt;property name="accessDecisionManager"&gt;&lt;ref bean="accessDecisionManager"/&gt;&lt;/property&gt;
  805. &lt;property name="objectDefinitionSource"&gt;
  806. &lt;value&gt;
  807. CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
  808. \A/secure/super/.*\Z=ROLE_WE_DONT_HAVE
  809. \A/secure/.*\Z=ROLE_SUPERVISOR,ROLE_TELLER
  810. &lt;/value&gt;
  811. &lt;/property&gt;
  812. &lt;/bean&gt;
  813. </programlisting>
  814. <!-- Not in listing above, so removed. L.T.
  815. <para>The <literal>PortMapper</literal> provides information on which
  816. HTTPS ports correspond to which HTTP ports. This is used by the
  817. <literal>AuthenticationProcessingFilterEntryPoint</literal> and
  818. several other beans. The default implementation,
  819. <literal>PortMapperImpl</literal>, knows the common HTTP ports 80 and
  820. 8080 map to HTTPS ports 443 and 8443 respectively. You can customise
  821. this mapping if desired.</para>
  822. -->
  823. <para>The <classname>ExceptionTranslationFilter</classname> provides
  824. the bridge between Java exceptions and HTTP responses. It is solely
  825. concerned with maintaining the user interface. This filter does not do
  826. any actual security enforcement. If an
  827. <exceptionname>AuthenticationException</exceptionname> is detected,
  828. the filter will call the AuthenticationEntryPoint to commence the
  829. authentication process (e.g. a user login).</para>
  830. <para>The <literal>AuthenticationEntryPoint</literal> will be called
  831. if the user requests a secure HTTP resource but they are not
  832. authenticated. The class handles presenting the appropriate response
  833. to the user so that authentication can begin. Three concrete
  834. implementations are provided with the Acegi Security System for
  835. Spring: <literal>AuthenticationProcessingFilterEntryPoint</literal>
  836. for commencing a form-based authentication,
  837. <literal>BasicProcessingFilterEntryPoint</literal> for commencing a
  838. HTTP Basic authentication process, and
  839. <literal>CasProcessingFilterEntryPoint</literal> for commencing a
  840. JA-SIG Central Authentication Service (CAS) login. The
  841. <literal>AuthenticationProcessingFilterEntryPoint</literal> and
  842. <literal>CasProcessingFilterEntryPoint</literal> have optional
  843. properties related to forcing the use of HTTPS, so please refer to the
  844. JavaDocs if you require this.</para>
  845. <para><literal>FilterSecurityInterceptor</literal> is responsible for
  846. handling the security of HTTP resources. Like any other security
  847. interceptor, it requires a reference to an
  848. <literal>AuthenticationManager</literal> and an
  849. <literal>AccessDecisionManager</literal>, which are both discussed in
  850. separate sections below. The
  851. <literal>FilterSecurityInterceptor</literal> is also configured with
  852. configuration attributes that apply to different HTTP URL requests. A
  853. full discussion of configuration attributes is provided in the High
  854. Level Design section of this document.</para>
  855. <para>The <literal>FilterSecurityInterceptor</literal> can be
  856. configured with configuration attributes in two ways. The first is via
  857. a property editor and the application context, which is shown above.
  858. The second is via writing your own
  859. <literal>ObjectDefinitionSource</literal>, although this is beyond the
  860. scope of this document. Irrespective of the approach used, the
  861. <literal>ObjectDefinitionSource</literal> is responsible for returning
  862. a <literal>ConfigAttributeDefinition</literal> object that contains
  863. all of the configuration attributes associated with a single secure
  864. HTTP URL.</para>
  865. <para>It should be noted that the
  866. <literal>FilterSecurityInterceptor.setObjectDefinitionSource()</literal>
  867. method actually expects an instance of
  868. <literal>FilterInvocationDefinitionSource</literal>. This is a marker
  869. interface which subclasses <literal>ObjectDefinitionSource</literal>.
  870. It simply denotes the <literal>ObjectDefinitionSource</literal>
  871. understands <literal>FilterInvocation</literal>s. In the interests of
  872. simplicity we'll continue to refer to the
  873. <literal>FilterInvocationDefinitionSource</literal> as an
  874. <literal>ObjectDefinitionSource</literal>, as the distinction is of
  875. little relevance to most users of the
  876. <literal>FilterSecurityInterceptor</literal>.</para>
  877. <para>If using the application context property editor approach (as
  878. shown above), commas are used to delimit the different configuration
  879. attributes that apply to each HTTP URL. Each configuration attribute
  880. is assigned into its own <literal>SecurityConfig</literal> object. The
  881. <literal>SecurityConfig</literal> object is discussed in the High
  882. Level Design section. The <literal>ObjectDefinitionSource</literal>
  883. created by the property editor,
  884. <literal>FilterInvocationDefinitionSource</literal>, matches
  885. configuration attributes against <literal>FilterInvocations</literal>
  886. based on expression evaluation of the request URL. Two standard
  887. expression syntaxes are supported. The default is to treat all
  888. expressions as regular expressions. Alternatively, the presence of a
  889. <literal>PATTERN_TYPE_APACHE_ANT</literal> directive will cause all
  890. expressions to be treated as Apache Ant paths. It is not possible to
  891. mix expression syntaxes within the same definition. For example, the
  892. earlier configuration could be generated using Apache Ant paths as
  893. follows:</para>
  894. <para><programlisting>
  895. &lt;bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor"&gt;
  896. &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
  897. &lt;property name="accessDecisionManager"&gt;&lt;ref bean="accessDecisionManager"/&gt;&lt;/property&gt;
  898. &lt;property name="runAsManager"&gt;&lt;ref bean="runAsManager"/&gt;&lt;/property&gt;
  899. &lt;property name="objectDefinitionSource"&gt;
  900. &lt;value&gt;
  901. CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
  902. PATTERN_TYPE_APACHE_ANT
  903. /secure/super/**=ROLE_WE_DONT_HAVE
  904. /secure/**=ROLE_SUPERVISOR,ROLE_TELLER
  905. &lt;/value&gt;
  906. &lt;/property&gt;
  907. &lt;/bean&gt;
  908. </programlisting></para>
  909. <para>Irrespective of the type of expression syntax used, expressions
  910. are always evaluated in the order they are defined. Thus it is
  911. important that more specific expressions are defined higher in the
  912. list than less specific expressions. This is reflected in our example
  913. above, where the more specific <literal>/secure/super/</literal>
  914. pattern appears higher than the less specific
  915. <literal>/secure/</literal> pattern. If they were reversed, the
  916. <literal>/secure/</literal> pattern would always match and the
  917. <literal>/secure/super/</literal> pattern would never be
  918. evaluated.</para>
  919. <para>The special keyword
  920. <literal>CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON</literal> causes
  921. the <literal>FilterInvocationDefinitionSource</literal> to
  922. automatically convert a request URL to lowercase before comparison
  923. against the expressions. Whilst by default the case of the request URL
  924. is not converted, it is generally recommended to use
  925. <literal>CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON</literal> and
  926. write each expression assuming lowercase.</para>
  927. <para>As with other security interceptors, the
  928. <literal>validateConfigAttributes</literal> property is observed. When
  929. set to <literal>true</literal> (the default), at startup time the
  930. <literal>FilterSecurityInterceptor</literal> will evaluate if the
  931. provided configuration attributes are valid. It does this by checking
  932. each configuration attribute can be processed by either the
  933. <literal>AccessDecisionManager</literal> or the
  934. <literal>RunAsManager</literal>. If neither of these can process a
  935. given configuration attribute, an exception is thrown.</para>
  936. </sect2>
  937. </sect1>
  938. <sect1 id="security-authentication">
  939. <title>Authentication</title>
  940. <sect2 id="security-authentication-requests">
  941. <title>Authentication Requests</title>
  942. <para>Authentication requires a way for client code to present its
  943. security identification to the Acegi Security System for Spring. This
  944. is the role of the <literal>Authentication</literal> interface. The
  945. <literal>Authentication</literal> interface holds three important
  946. objects: the principal (the identity of the caller), the credentials
  947. (the proof of the identity of the caller, such as a password), and the
  948. authorities that have been granted to the principal. The principal and
  949. its credentials are populated by the client code, whilst the granted
  950. authorities are populated by the
  951. <literal>AuthenticationManager</literal>.</para>
  952. <para><mediaobject>
  953. <imageobject role="html">
  954. <imagedata align="center" fileref="images/Authentication.gif"
  955. format="GIF" />
  956. </imageobject>
  957. <caption>
  958. <para>Figure 3: Key Authentication Architecture</para>
  959. </caption>
  960. </mediaobject></para>
  961. <para>As shown in Figure 3, the Acegi Security System for Spring
  962. includes several concrete <literal>Authentication</literal>
  963. implementations:</para>
  964. <itemizedlist spacing="compact">
  965. <listitem>
  966. <para><literal>UsernamePasswordAuthenticationToken</literal>
  967. allows a username and password to be presented as the principal
  968. and credentials respectively. It is also what is created by the
  969. HTTP Session Authentication system.</para>
  970. </listitem>
  971. <listitem>
  972. <para><literal>TestingAuthenticationToken</literal> facilitates
  973. unit testing by automatically being considered an authenticated
  974. object by its associated
  975. <literal>AuthenticationProvider</literal>.</para>
  976. </listitem>
  977. <listitem>
  978. <para><literal>RunAsUserToken</literal> is used by the default
  979. run-as authentication replacement implementation. This is
  980. discussed further in the Run-As Authentication Replacement
  981. section.</para>
  982. </listitem>
  983. <listitem>
  984. <para><literal>CasAuthenticationToken</literal> is used to
  985. represent a successful JA-SIG Central Authentication Service (CAS)
  986. authentication. This is discussed further in the CAS
  987. section.</para>
  988. </listitem>
  989. <listitem>
  990. <para><literal>PrincipalAcegiUserToken</literal> and
  991. <literal>JettyAcegiUserToken</literal> implement
  992. <literal>AuthByAdapter</literal> (a subclass of
  993. <literal>Authentication</literal>) and are used whenever
  994. authentication is completed by Acegi Security System for Spring
  995. container adapters. This is discussed further in the Container
  996. Adapters section.</para>
  997. </listitem>
  998. </itemizedlist>
  999. <para>The authorities granted to a principal are represented by the
  1000. <literal>GrantedAuthority</literal> interface. The
  1001. <literal>GrantedAuthority</literal> interface is discussed at length
  1002. in the Authorization section.</para>
  1003. </sect2>
  1004. <sect2 id="security-authentication-manager">
  1005. <title>Authentication Manager</title>
  1006. <para>As discussed in the Security Interception section, the
  1007. <literal>AbstractSecurityInterceptor</literal> extracts the
  1008. <literal>Authentication</literal> object from the
  1009. <literal>SecurityContext</literal> in the
  1010. <literal>SecurityContextHolder</literal>. This is then passed to an
  1011. <literal>AuthenticationManager</literal>. The
  1012. <literal>AuthenticationManager</literal> interface is very
  1013. simple:</para>
  1014. <programlisting>public Authentication authenticate(Authentication authentication) throws AuthenticationException;</programlisting>
  1015. <para>Implementations of <literal>AuthenticationManager</literal> are
  1016. required to throw an <literal>AuthenticationException</literal> should
  1017. authentication fail, or return a fully populated
  1018. <literal>Authentication</literal> object. In particular, the returned
  1019. <literal>Authentication</literal> object should contain an array of
  1020. <literal>GrantedAuthority</literal> objects. The
  1021. <literal>SecurityInterceptor</literal> places the populated
  1022. <literal>Authentication</literal> object back in the
  1023. <literal>SecurityContext</literal> in the
  1024. <literal>SecurityContextHolder</literal>, overwriting the original
  1025. <literal>Authentication</literal> object.</para>
  1026. <para>The <literal>AuthenticationException</literal> has a number of
  1027. subclasses. The most important are
  1028. <literal>BadCredentialsException</literal> (an incorrect principal or
  1029. credentials), <literal>DisabledException</literal> and
  1030. <literal>LockedException</literal>. The latter two exceptions indicate
  1031. the principal was found, but the credentials were not checked and
  1032. authentication is denied. An
  1033. <literal>AuthenticationServiceException</literal> is also provided,
  1034. which indicates the authentication system could not process the
  1035. request (eg a database was unavailable).
  1036. <literal>AuthenticationException</literal> also has a
  1037. <literal>CredentialsExpiredException</literal> and
  1038. <literal>AccoungtExpiredException</literal> subclass, although these
  1039. are less commonly used.</para>
  1040. </sect2>
  1041. <sect2 id="security-authentication-provider">
  1042. <title>Provider-Based Authentication</title>
  1043. <para>Whilst the basic <literal>Authentication</literal> and
  1044. <literal>AuthenticationManager</literal> interfaces enable users to
  1045. develop their own authentication systems, users should consider using
  1046. the provider-based authentication packages provided by the Acegi
  1047. Security System for Spring. The key class,
  1048. <literal>ProviderManager</literal>, is configured via the bean context
  1049. with a list of <literal>AuthenticationProvider</literal>s:</para>
  1050. <para><programlisting>
  1051. &lt;bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager"&gt;
  1052. &lt;property name="providers"&gt;
  1053. &lt;list&gt;
  1054. &lt;ref bean="daoAuthenticationProvider"/&gt;
  1055. &lt;ref bean="someOtherAuthenticationProvider"/&gt;
  1056. &lt;/list&gt;
  1057. &lt;/property&gt;
  1058. &lt;/bean&gt;
  1059. </programlisting></para>
  1060. <para><literal>ProviderManager</literal> calls a series of registered
  1061. <literal>AuthenticationProvider</literal> implementations, until one
  1062. is found that indicates it is able to authenticate a given
  1063. <literal>Authentication</literal> class. When the first compatible
  1064. <literal>AuthenticationProvider</literal> is located, it is passed the
  1065. authentication request. The <literal>AuthenticationProvider</literal>
  1066. will then either throw an <literal>AuthenticationException</literal>
  1067. or return a fully populated <literal>Authentication</literal>
  1068. object.</para>
  1069. <para>Note the <literal>ProviderManager</literal> may throw a
  1070. <literal>ProviderNotFoundException</literal> (a subclass of
  1071. <literal>AuthenticationException</literal>) if it none of the
  1072. registered <literal>AuthenticationProviders</literal> can validate the
  1073. <literal>Authentication</literal> object.</para>
  1074. <para>The <literal>ProviderManager</literal> also has several other
  1075. important functions. It integrates with concurrent session handling
  1076. support, and it also converts any exceptions thrown by an
  1077. <literal>AuthenticationProvider</literal> and publishes a suitable
  1078. event. The events that are published are located in the
  1079. <literal>org.acegisecurity.event.authentication</literal> package and
  1080. advanced users can map different exceptions to different events by
  1081. configuring the <literal>ProviderManager.exceptionMappings</literal>
  1082. property (generally this is not required and the default event
  1083. propagation is appropriate - especially as events will simply be
  1084. ignored if you don't have an <literal>ApplicationListener</literal>
  1085. configured in the <literal>ApplicationContext</literal>).</para>
  1086. <para>Several <literal>AuthenticationProvider</literal>
  1087. implementations are provided with the Acegi Security System for
  1088. Spring:</para>
  1089. <para><itemizedlist spacing="compact">
  1090. <listitem>
  1091. <para><literal>TestingAuthenticationProvider</literal> is able
  1092. to authenticate a <literal>TestingAuthenticationToken</literal>.
  1093. The limit of its authentication is simply to treat whatever is
  1094. contained in the <literal>TestingAuthenticationToken</literal>
  1095. as valid. This makes it ideal for use during unit testing, as
  1096. you can create an <literal>Authentication</literal> object with
  1097. precisely the <literal>GrantedAuthority</literal> objects
  1098. required for calling a given method. You definitely would not
  1099. register this <literal>AuthenticationProvider</literal> on a
  1100. production system.</para>
  1101. </listitem>
  1102. <listitem>
  1103. <para><literal>DaoAuthenticationProvider</literal> is able to
  1104. authenticate a
  1105. <literal>UsernamePasswordAuthenticationToken</literal> by
  1106. accessing an authentication respository via a data access
  1107. object. This is discussed further below, as it is the main way
  1108. authentication is initially handled.</para>
  1109. </listitem>
  1110. <listitem>
  1111. <para><literal>RunAsImplAuthenticationProvider</literal> is able
  1112. to authenticate a <literal>RunAsUserToken</literal>. This is
  1113. discussed further in the Run-As Authentication Replacement
  1114. section. You would not register this
  1115. <literal>AuthenticationProvider</literal> if you were not using
  1116. run-as replacement.</para>
  1117. </listitem>
  1118. <listitem>
  1119. <para><literal>AuthByAdapterProvider</literal> is able to
  1120. authenticate any <literal>AuthByAdapter</literal> (a subclass of
  1121. <literal>Authentication</literal> used with container adapters).
  1122. This is discussed further in the Container Adapters section. You
  1123. would not register this
  1124. <literal>AuthenticationProvider</literal> if you were not using
  1125. container adapters.</para>
  1126. </listitem>
  1127. <listitem>
  1128. <para><literal>CasAuthenticationProvider</literal> is able to
  1129. authenticate JA-SIG Central Authentication Service (CAS)
  1130. tickets. This is discussed further in the CAS Single Sign On
  1131. section.</para>
  1132. </listitem>
  1133. <listitem>
  1134. <para><literal>JaasAuthenticationProvider</literal> is able to
  1135. delegate authentication requests to a JAAS
  1136. <literal>LoginModule</literal>. This is discussed further
  1137. below.</para>
  1138. </listitem>
  1139. </itemizedlist></para>
  1140. </sect2>
  1141. <sect2 id="security-authentication-concurrent-login">
  1142. <title>Concurrent Session Support</title>
  1143. <para>Acegi Security is able to stop the same principal authenticating
  1144. to the same web application multiple times concurrently. Put
  1145. differently, you can stop user "Batman" from logging into a web
  1146. application twice at the same time.</para>
  1147. <para>To use concurrent session support, you'll need to add the
  1148. following to web.xml:</para>
  1149. <para><programlisting>
  1150. &lt;listener&gt;
  1151. &lt;listener-class&gt;org.acegisecurity.ui.session.HttpSessionEventPublisher&lt;/listener-class&gt;
  1152. &lt;/listener&gt;
  1153. </programlisting></para>
  1154. <para>In addition, you will need to add the
  1155. <literal>org.acegisecurity.concurrent.ConcurrentSessionFilter</literal>
  1156. to your <literal>FilterChainProxy</literal>. The
  1157. ConcurrentSessionFilter requires only one property, sessionRegistry,
  1158. which generally points to an instance of
  1159. <literal>SessionRegistryImpl</literal>.</para>
  1160. <para>The <literal>web.xml</literal>
  1161. <literal>HttpSessionEventPublisher</literal> causes an
  1162. <literal>ApplicationEvent</literal> to be published to the Spring
  1163. <literal>ApplicationContext</literal> every time a
  1164. <literal>HttpSession</literal> commences or terminates. This is
  1165. critical, as it allows the <literal>SessionRegistryImpl</literal> to
  1166. be notified when a session ends.</para>
  1167. <para>You will also need to wire up the
  1168. <literal>ConcurrentSessionControllerImpl</literal> and refer to it
  1169. from your <literal>ProviderManager</literal> bean:</para>
  1170. <para><programlisting>
  1171. &lt;bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager"&gt;
  1172. &lt;property name="providers"&gt;
  1173. &lt;!-- your providers go here --&gt;
  1174. &lt;/property&gt;
  1175. &lt;property name="sessionController"&gt;&lt;ref bean="concurrentSessionController"/&gt;&lt;/property&gt;
  1176. &lt;/bean&gt;
  1177. &lt;bean id="concurrentSessionController" class="org.acegisecurity.concurrent.ConcurrentSessionControllerImpl"&gt;
  1178. &lt;property name="maximumSessions"&gt;&lt;value&gt;1&lt;/value&gt;&lt;/property&gt;
  1179. &lt;property name="sessionRegistry"&gt;&lt;ref local="sessionRegistry"/&gt;&lt;/property&gt;
  1180. &lt;/bean&gt;
  1181. &lt;bean id="sessionRegistry" class="org.acegisecurity.concurrent.SessionRegistryImpl"/&gt;
  1182. </programlisting></para>
  1183. </sect2>
  1184. <sect2 id="security-authentication-provider-dao">
  1185. <title>Data Access Object Authentication Provider</title>
  1186. <para>The Acegi Security System for Spring includes a
  1187. production-quality <literal>AuthenticationProvider</literal>
  1188. implementation called <literal>DaoAuthenticationProvider</literal>.
  1189. This authentication provider is able to authenticate a
  1190. <literal>UsernamePasswordAuthenticationToken</literal> by obtaining
  1191. authentication details from a data access object configured at bean
  1192. creation time:</para>
  1193. <para><programlisting>
  1194. &lt;bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider"&gt;
  1195. &lt;property name="userDetailsService"&gt;&lt;ref bean="inMemoryDaoImpl"/&gt;&lt;/property&gt;
  1196. &lt;property name="saltSource"&gt;&lt;ref bean="saltSource"/&gt;&lt;/property&gt;
  1197. &lt;property name="passwordEncoder"&gt;&lt;ref bean="passwordEncoder"/&gt;&lt;/property&gt;
  1198. &lt;/bean&gt;
  1199. </programlisting></para>
  1200. <para>The <literal>PasswordEncoder</literal> and
  1201. <literal>SaltSource</literal> are optional. A
  1202. <literal>PasswordEncoder</literal> provides encoding and decoding of
  1203. passwords obtained from the authentication repository. A
  1204. <literal>SaltSource</literal> enables the passwords to be populated
  1205. with a "salt", which enhances the security of the passwords in the
  1206. authentication repository. <literal>PasswordEncoder</literal>
  1207. implementations are provided with the Acegi Security System for Spring
  1208. covering MD5, SHA and cleartext encodings. Two
  1209. <literal>SaltSource</literal> implementations are also provided:
  1210. <literal>SystemWideSaltSource</literal> which encodes all passwords
  1211. with the same salt, and <literal>ReflectionSaltSource</literal>, which
  1212. inspects a given property of the returned
  1213. <literal>UserDetails</literal> object to obtain the salt. Please refer
  1214. to the JavaDocs for further details on these optional features.</para>
  1215. <para>In addition to the properties above, the
  1216. <literal>DaoAuthenticationProvider</literal> supports optional caching
  1217. of <literal>UserDetails</literal> objects. The
  1218. <literal>UserCache</literal> interface enables the
  1219. <literal>DaoAuthenticationProvider</literal> to place a
  1220. <literal>UserDetails</literal> object into the cache, and retrieve it
  1221. from the cache upon subsequent authentication attempts for the same
  1222. username. By default the <literal>DaoAuthenticationProvider</literal>
  1223. uses the <literal>NullUserCache</literal>, which performs no caching.
  1224. A usable caching implementation is also provided,
  1225. <literal>EhCacheBasedUserCache</literal>, which is configured as
  1226. follows:</para>
  1227. <para><programlisting>
  1228. &lt;bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider"&gt;
  1229. &lt;property name="userDetailsService"&gt;&lt;ref bean="userDetailsService"/&gt;&lt;/property&gt;
  1230. &lt;property name="userCache"&gt;&lt;ref bean="userCache"/&gt;&lt;/property&gt;
  1231. &lt;/bean&gt;
  1232. &lt;bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"&gt;
  1233. &lt;property name="configLocation"&gt;
  1234. &lt;value&gt;classpath:/ehcache-failsafe.xml&lt;/value&gt;
  1235. &lt;/property&gt;
  1236. &lt;/bean&gt;
  1237. &lt;bean id="userCacheBackend" class="org.springframework.cache.ehcache.EhCacheFactoryBean"&gt;
  1238. &lt;property name="cacheManager"&gt;
  1239. &lt;ref local="cacheManager"/&gt;
  1240. &lt;/property&gt;
  1241. &lt;property name="cacheName"&gt;
  1242. &lt;value&gt;userCache&lt;/value&gt;
  1243. &lt;/property&gt;
  1244. &lt;/bean&gt;
  1245. &lt;bean id="userCache" class="org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache"&gt;
  1246. &lt;property name="cache"&gt;&lt;ref local="userCacheBackend"/&gt;&lt;/property&gt;
  1247. &lt;/bean&gt;
  1248. </programlisting></para>
  1249. <para>All Acegi Security EH-CACHE implementations (including
  1250. <literal>EhCacheBasedUserCache</literal>) require an EH-CACHE
  1251. <literal>Cache</literal> object. The <literal>Cache</literal> object
  1252. can be obtained from wherever you like, although we recommend you use
  1253. Spring's factory classes as shown in the above configuration. If using
  1254. Spring's factory classes, please refer to the Spring documentation for
  1255. further details on how to optimise the cache storage location, memory
  1256. usage, eviction policies, timeouts etc.</para>
  1257. <para>For a class to be able to provide the
  1258. <literal>DaoAuthenticationProvider</literal> with access to an
  1259. authentication repository, it must implement the
  1260. <literal>UserDetailsService</literal> interface:</para>
  1261. <para><programlisting>public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException;</programlisting></para>
  1262. <para>The <literal>UserDetails</literal> is an interface that provides
  1263. getters that guarantee non-null provision of basic authentication
  1264. information such as the username, password, granted authorities and
  1265. whether the user is enabled or disabled. A concrete implementation,
  1266. <literal>User</literal>, is also provided. Acegi Security users will
  1267. need to decide when writing their
  1268. <literal>UserDetailsService</literal> what type of
  1269. <literal>UserDetails</literal> to return. In most cases
  1270. <literal>User</literal> will be used directly or subclassed, although
  1271. special circumstances (such as object relational mappers) may require
  1272. users to write their own <literal>UserDetails</literal> implementation
  1273. from scratch. <literal>UserDetails</literal> is often used to store
  1274. additional principal-related properties (such as their telephone
  1275. number and email address), so they can be easily used by web
  1276. views.</para>
  1277. <para>Given <literal>UserDetailsService</literal> is so simple to
  1278. implement, it should be easy for users to retrieve authentication
  1279. information using a persistence strategy of their choice.</para>
  1280. <para>A design decision was made not to support account locking in the
  1281. <literal>DaoAuthenticationProvider</literal>, as doing so would have
  1282. increased the complexity of the <literal>UserDetailsService</literal>
  1283. interface. For instance, a method would be required to increase the
  1284. count of unsuccessful authentication attempts. Such functionality
  1285. could be easily provided by leveraging the application event
  1286. publishing features discussed below.</para>
  1287. <para><literal>DaoAuthenticationProvider</literal> returns an
  1288. <literal>Authentication</literal> object which in turn has its
  1289. <literal>principal</literal> property set. The principal will be
  1290. either a <literal>String</literal> (which is essentially the username)
  1291. or a <literal>UserDetails</literal> object (which was looked up from
  1292. the <literal>UserDetailsService</literal>). By default the
  1293. <literal>UserDetails</literal> is returned, as this enables
  1294. applications to add extra properties potentially of use in
  1295. applications, such as the user's full name, email address etc. If
  1296. using container adapters, or if your applications were written to
  1297. operate with <literal>String</literal>s (as was the case for releases
  1298. prior to Acegi Security 0.6), you should set the
  1299. <literal>DaoAuthenticationProvider.forcePrincipalAsString</literal>
  1300. property to <literal>true</literal> in your application
  1301. context.</para>
  1302. </sect2>
  1303. <sect2 id="security-authentication-provider-in-memory">
  1304. <title>In-Memory Authentication</title>
  1305. <para>Whilst it is easy to use the
  1306. <literal>DaoAuthenticationProvider</literal> and create a custom
  1307. <literal>UserDetailsService</literal> implementation that extracts
  1308. information from a persistence engine of choice, many applications do
  1309. not require such complexity. One alternative is to configure an
  1310. authentication repository in the application context itself using the
  1311. <literal>InMemoryDaoImpl</literal>:</para>
  1312. <para><programlisting>
  1313. &lt;bean id="inMemoryDaoImpl" class="org.acegisecurity.userdetails.memory.InMemoryDaoImpl"&gt;
  1314. &lt;property name="userMap"&gt;
  1315. &lt;value&gt;
  1316. marissa=koala,ROLE_TELLER,ROLE_SUPERVISOR
  1317. dianne=emu,ROLE_TELLER
  1318. scott=wombat,ROLE_TELLER
  1319. peter=opal,disabled,ROLE_TELLER
  1320. &lt;/value&gt;
  1321. &lt;/property&gt;
  1322. &lt;/bean&gt;
  1323. </programlisting></para>
  1324. <para>The <literal>userMap</literal> property contains each of the
  1325. usernames, passwords, a list of granted authorities and an optional
  1326. enabled/disabled keyword. Commas delimit each token. The username must
  1327. appear to the left of the equals sign, and the password must be the
  1328. first token to the right of the equals sign. The
  1329. <literal>enabled</literal> and <literal>disabled</literal> keywords
  1330. (case insensitive) may appear in the second or any subsequent token.
  1331. Any remaining tokens are treated as granted authorities, which are
  1332. created as <literal>GrantedAuthorityImpl</literal> objects (refer to
  1333. the Authorization section for further discussion on granted
  1334. authorities). Note that if a user has no password and/or no granted
  1335. authorities, the user will not be created in the in-memory
  1336. authentication repository.</para>
  1337. <para><literal>InMemoryDaoImpl</literal> also offers a
  1338. <literal>setUserProperties(Properties)</literal> method, which allows
  1339. you to externalise the <literal>java.util.Properties</literal> in
  1340. another Spring configured bean or an external properties file. This
  1341. might prove useful for simple applications that have a larger number
  1342. of users, or deployment-time configuration changes, but do not wish to
  1343. use a full database for authentication details.</para>
  1344. </sect2>
  1345. <sect2 id="security-authentication-provider-jdbc">
  1346. <title>JDBC Authentication</title>
  1347. <para>The Acegi Security System for Spring also includes an
  1348. authentication provider that can obtain authentication information
  1349. from a JDBC data source. The typical configuration for the
  1350. <literal>JdbcDaoImpl</literal> is shown below:</para>
  1351. <para><programlisting>
  1352. &lt;bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"&gt;
  1353. &lt;property name="driverClassName"&gt;&lt;value&gt;org.hsqldb.jdbcDriver&lt;/value&gt;&lt;/property&gt;
  1354. &lt;property name="url"&gt;&lt;value&gt;jdbc:hsqldb:hsql://localhost:9001&lt;/value&gt;&lt;/property&gt;
  1355. &lt;property name="username"&gt;&lt;value&gt;sa&lt;/value&gt;&lt;/property&gt;
  1356. &lt;property name="password"&gt;&lt;value&gt;&lt;/value&gt;&lt;/property&gt;
  1357. &lt;/bean&gt;
  1358. &lt;bean id="jdbcDaoImpl" class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl"&gt;
  1359. &lt;property name="dataSource"&gt;&lt;ref bean="dataSource"/&gt;&lt;/property&gt;
  1360. &lt;/bean&gt;
  1361. </programlisting></para>
  1362. <para>You can use different relational database management systems by
  1363. modifying the <literal>DriverManagerDataSource</literal> shown above.
  1364. Irrespective of the database used, a standard schema must be used as
  1365. indicated in <literal>dbinit.txt</literal>.</para>
  1366. <para>If you default schema is unsuitable for your needs,
  1367. <literal>JdbcDaoImpl</literal> provides two properties that allow
  1368. customisation of the SQL statements. You may also subclass the
  1369. <literal>JdbcDaoImpl</literal> if further customisation is necessary.
  1370. Please refer to the JavaDocs for details.</para>
  1371. </sect2>
  1372. <sect2 id="security-authentication-provider-jaas">
  1373. <title>JAAS Authentication</title>
  1374. <para>Acegi Security provides a package able to delegate
  1375. authentication requests to the Java Authentication and Authorization
  1376. Service (JAAS). This package is discussed in detail below.</para>
  1377. <para>Central to JAAS operation are login configuration files. To
  1378. learn more about JAAS login configuration files, consult the JAAS
  1379. reference documentation available from Sun Microsystems. We expect you
  1380. to have a basic understanding of JAAS and its login configuration file
  1381. syntax in order to understand this section.</para>
  1382. <sect3>
  1383. <title>JaasAuthenticationProvider</title>
  1384. <para>The <literal>JaasAuthenticationProvider</literal> attempts to
  1385. authenticate a user’s principal and credentials through JAAS.</para>
  1386. <para>Let’s assume we have a JAAS login configuration file,
  1387. <literal>/WEB-INF/login.conf</literal>, with the following
  1388. contents:</para>
  1389. <para><programlisting>JAASTest {
  1390. sample.SampleLoginModule required;
  1391. };</programlisting></para>
  1392. <para>Like all Acegi Security beans, the
  1393. <literal>JaasAuthenticationProvider</literal> is configured via the
  1394. application context. The following definitions would correspond to
  1395. the above JAAS login configuration file:</para>
  1396. <para><programlisting>
  1397. &lt;bean id="jaasAuthenticationProvider" class="org.acegisecurity.providers.jaas.JaasAuthenticationProvider"&gt;
  1398. &lt;property name="loginConfig"&gt;
  1399. &lt;value&gt;/WEB-INF/login.conf&lt;/value&gt;
  1400. &lt;/property&gt;
  1401. &lt;property name="loginContextName"&gt;
  1402. &lt;value&gt;JAASTest&lt;/value&gt;
  1403. &lt;/property&gt;
  1404. &lt;property name="callbackHandlers"&gt;
  1405. &lt;list&gt;
  1406. &lt;bean class="org.acegisecurity.providers.jaas.JaasNameCallbackHandler"/&gt;
  1407. &lt;bean class="org.acegisecurity.providers.jaas.JaasPasswordCallbackHandler"/&gt;
  1408. &lt;/list&gt;
  1409. &lt;/property&gt;
  1410. &lt;property name="authorityGranters"&gt;
  1411. &lt;list&gt;
  1412. &lt;bean class="org.acegisecurity.providers.jaas.TestAuthorityGranter"/&gt;
  1413. &lt;/list&gt;
  1414. &lt;/property&gt;
  1415. &lt;/bean&gt;
  1416. </programlisting></para>
  1417. <para>The <literal>CallbackHandler</literal>s and
  1418. <literal>AuthorityGranter</literal>s are discussed below.</para>
  1419. </sect3>
  1420. <sect3>
  1421. <title>Callbacks</title>
  1422. <para>Most JAAS <literal>LoginModule</literal>s require a callback
  1423. of some sort. These callbacks are usually used to obtain the
  1424. username and password from the user. In an Acegi Security
  1425. deployment, Acegi Security is responsible for this user interaction
  1426. (typically via a reference to a
  1427. <literal>ContextHolder</literal>-managed
  1428. <literal>Authentication</literal> object). The JAAS package for
  1429. Acegi Security provides two default callback handlers,
  1430. <literal>JaasNameCallbackHandler</literal> and
  1431. <literal>JaasPasswordCallbackHandler</literal>. Each of these
  1432. callback handlers implement
  1433. <literal>JaasAuthenticationCallbackHandler</literal>. In most cases
  1434. these callback handlers can simply be used without understanding the
  1435. internal mechanics. For those needing full control over the callback
  1436. behavior, internally <literal>JaasAutheticationProvider</literal>
  1437. wraps these <literal>JaasAuthenticationCallbackHandler</literal>s
  1438. with an <literal>InternalCallbackHandler</literal>. The
  1439. <literal>InternalCallbackHandler</literal> is the class that
  1440. actually implements JAAS’ normal <literal>CallbackHandler</literal>
  1441. interface. Any time that the JAAS <literal>LoginModule</literal> is
  1442. used, it is passed a list of application context configured
  1443. <literal>InternalCallbackHandler</literal>s. If the
  1444. <literal>LoginModule</literal> requests a callback against the
  1445. <literal>InternalCallbackHandler</literal>s, the callback is in-turn
  1446. passed to the <literal>JaasAuthenticationCallbackHandler</literal>s
  1447. being wrapped.</para>
  1448. </sect3>
  1449. <sect3>
  1450. <title>AuthorityGranters</title>
  1451. <para>JAAS works with principals. Even “roles” are represented as
  1452. principals in JAAS. Acegi Security, on the other hand, works with
  1453. <literal>Authentication</literal> objects. Each
  1454. <literal>Authentication</literal> object contains a single
  1455. principal, and multiple <literal>GrantedAuthority</literal>[]s. To
  1456. facilitate mapping between these different concepts, the Acegi
  1457. Security JAAS package includes an
  1458. <literal>AuthorityGranter</literal> interface. An
  1459. <literal>AuthorityGranter</literal> is responsible for inspecting a
  1460. JAAS principal and returning a <literal>String</literal>. The
  1461. <literal>JaasAuthenticationProvider</literal> then creates a
  1462. <literal>JaasGrantedAuthority</literal> (which implements Acegi
  1463. Security’s <literal>GrantedAuthority</literal> interface) containing
  1464. both the <literal>AuthorityGranter</literal>-returned
  1465. <literal>String</literal> and the JAAS principal that the
  1466. <literal>AuthorityGranter</literal> was passed. The
  1467. <literal>JaasAuthenticationProvider</literal> obtains the JAAS
  1468. principals by firstly successfully authenticating the user’s
  1469. credentials using the JAAS <literal>LoginModule</literal>, and then
  1470. accessing the <literal>LoginContext</literal> it returns. A call to
  1471. <literal>LoginContext.getSubject().getPrincipals()</literal> is
  1472. made, with each resulting principal passed to each
  1473. <literal>AuthorityGranter</literal> defined against the
  1474. <literal>JaasAuthenticationProvider.setAuthorityGranters(List)</literal>
  1475. property. Acegi Security does not include any production
  1476. <literal>AuthorityGranter</literal>s given every JAAS principal has
  1477. an implementation-specific meaning. However, there is a
  1478. <literal>TestAuthorityGranter</literal> in the unit tests that
  1479. demonstrates a simple <literal>AuthorityGranter</literal>
  1480. implementation.</para>
  1481. </sect3>
  1482. </sect2>
  1483. <sect2 id="security-authentication-provider-siteminder">
  1484. <title>Siteminder Authentication</title>
  1485. <para>Acegi Security provides a web filter
  1486. <literal>(org.acegisecurity.ui.webapp.SiteminderAuthenticationProcessingFilter</literal>)
  1487. that can be used to process requests that have been pre-authenticated
  1488. by Computer Associates' Siteminder. This filter assumes that you're
  1489. using Siteminder for <emphasis>authentication</emphasis>, and your
  1490. application (or backing datasource) is used for
  1491. <emphasis>authorization</emphasis>. The use of Siteminder for
  1492. <emphasis>authorization</emphasis> is not yet directly supported by
  1493. Acegi.</para>
  1494. <para>Recall that a Siteminder agent is set up on your web server to
  1495. intercept a user's first call to your application. This agent
  1496. redirects the initial request to a login page (usually
  1497. organization-wide), and only after successful authentication does your
  1498. application receive the request. Authenticated requests then contain
  1499. one or more HTTP headers populated by the Siteminder agent. Below
  1500. we'll assume that the request header key containing the user's
  1501. identity is "SM_USER", but of course your header values may be
  1502. different based on Siteminder policy server configuration. Please
  1503. refer to your organization's "single sign-on" group for header
  1504. details.</para>
  1505. <sect3>
  1506. <title>SiteminderAuthenticationProcessingFilter</title>
  1507. <para>The first step in setting up Acegi's Siteminder support is to
  1508. define an <literal>authenticationProcessingFilter</literal> bean and
  1509. give it an <literal>authenticationManager</literal> to use, as well
  1510. as to tell it where to send users upon success and failure and where
  1511. to find the Siteminder username and password values. Most people
  1512. won't need the password value since Siteminder has already
  1513. authenticated the user, so it's typical to use the same header for
  1514. both.</para>
  1515. <para><programlisting>
  1516. &lt;!-- ======================== SITEMINDER AUTHENTICATION PROCESSING FILTER ======================= --&gt;
  1517. &lt;bean id="authenticationProcessingFilter" class="org.acegisecurity.ui.webapp.SiteminderAuthenticationProcessingFilter"&gt;
  1518. &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
  1519. &lt;property name="authenticationFailureUrl"&gt;&lt;value&gt;/login.jsp?login_error=1&lt;/value&gt;&lt;/property&gt;
  1520. &lt;property name="defaultTargetUrl"&gt;&lt;value&gt;/security.do?method=getMainMenu&lt;/value&gt;&lt;/property&gt;
  1521. &lt;property name="filterProcessesUrl"&gt;&lt;value&gt;/j_acegi_security_check&lt;/value&gt;&lt;/property&gt;
  1522. &lt;property name="siteminderUsernameHeaderKey"&gt;&lt;value&gt;SM_USER&lt;/value&gt;&lt;/property&gt;
  1523. &lt;property name="siteminderPasswordHeaderKey"&gt;&lt;value&gt;SM_USER&lt;/value&gt;&lt;/property&gt;
  1524. &lt;/bean&gt;
  1525. </programlisting></para>
  1526. <para>Since this <literal>authenticationProcessingFilter</literal>
  1527. depends on an <literal>authenticationManager</literal>, we'll need
  1528. to define one:</para>
  1529. <para><programlisting>
  1530. &lt;!-- ======================== AUTHENTICATION ======================= --&gt;
  1531. &lt;!--
  1532. - The top-level Authentication Manager is responsible for all application AUTHENTICATION
  1533. - operations. Note that it must reference one or more provider(s) defined below.
  1534. --&gt;
  1535. &lt;bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager"&gt;
  1536. &lt;property name="providers"&gt;
  1537. &lt;list&gt;
  1538. &lt;ref local="daoAuthenticationProvider"/&gt;
  1539. &lt;/list&gt;
  1540. &lt;/property&gt;
  1541. &lt;/bean&gt;
  1542. </programlisting></para>
  1543. <para>Note that a <literal>daoAuthenticationProvider</literal> above
  1544. needs to expect the password property to match what it expects. In
  1545. this case, authentication has already been handled by Siteminder and
  1546. you've specified the same HTTP header for both username and
  1547. password, so you can code
  1548. <literal>daoAuthenticationProvider</literal> to simply make sure the
  1549. username and password values match. This may sound like a security
  1550. weakness, but remember that users have to authenticate with
  1551. Siteminder before your application ever receives the requests, so
  1552. the purpose of your <literal>daoAuthenticationProvider</literal>
  1553. should simply be to assign roles and other properties needed by
  1554. subsequent method interceptors, etc.</para>
  1555. <para>Finally we need to tell the
  1556. <literal>filterChainProxy</literal> to include the
  1557. <literal>authenticationProcessingFilter</literal> in its
  1558. operations.</para>
  1559. <para><programlisting>
  1560. &lt;!-- ======================== FILTER CHAIN ======================= --&gt;
  1561. &lt;!--
  1562. - The web.xml file has a single filter reference to this top-level bean, which
  1563. - invokes the chain of sub-filters specified below.
  1564. --&gt;
  1565. &lt;bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy"&gt;
  1566. &lt;property name="filterInvocationDefinitionSource"&gt;
  1567. &lt;value&gt;
  1568. CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
  1569. PATTERN_TYPE_APACHE_ANT
  1570. /**=httpSessionContextIntegrationFilter,authenticationProcessingFilter,exceptionTranslationFilter,filterSecurityInterceptor
  1571. &lt;/value&gt;
  1572. &lt;/property&gt;
  1573. &lt;/bean&gt;
  1574. </programlisting></para>
  1575. <para>If you already have Acegi configured prior to adding
  1576. Siteminder authentication, that's really all there is to it. In
  1577. summary, once the user has authenticated through Siteminder, their
  1578. header-loaded request will be brokered by
  1579. <literal>filterChainProxy</literal> to
  1580. <literal>authenticationProcessingFilter</literal>, which in turn
  1581. will grab the user's identity from the SM_USER request header. The
  1582. user's identity will then be passed to the
  1583. <literal>authenticationManager</literal> and finally your
  1584. <literal>daoAuthenticationProvider</literal> will do the work of
  1585. authorizing the user (against back-end databases, etc.) and loading
  1586. the <literal>UserDetails</literal> implementation with roles,
  1587. username and other properties you deem relevant.</para>
  1588. <para>Advanced tip &amp; word to the wise: the
  1589. <literal>SiteminderAuthenticationProcessingFilter</literal> actually
  1590. extends <literal>AuthenticationProcessingFilter</literal> and thus
  1591. additionally supports form validation. If you configure the filter
  1592. to support both, and code your
  1593. <literal>daoAuthenticationProvider</literal> to match the username
  1594. and passwords as described above, you'll potentially defeat any
  1595. security you have in place if the web server's Siteminder agent is
  1596. deactivated. Don't do this, especially in production!</para>
  1597. </sect3>
  1598. </sect2>
  1599. <sect2 id="security-authentication-recommendations">
  1600. <title>Authentication Recommendations</title>
  1601. <para>With the heavy use of interfaces throughout the authentication
  1602. system (<literal>Authentication</literal>,
  1603. <literal>AuthenticationManager</literal>,
  1604. <literal>AuthenticationProvider</literal> and
  1605. <literal>UserDetailsService</literal>) it might be confusing to a new
  1606. user to know which part of the authentication system to customize. In
  1607. general, the following is recommended:</para>
  1608. <itemizedlist>
  1609. <listitem>
  1610. <para>Use the
  1611. <literal>UsernamePasswordAuthenticationToken</literal>
  1612. implementation where possible.</para>
  1613. </listitem>
  1614. <listitem>
  1615. <para>If you simply need to implement a new authentication
  1616. repository (eg to obtain user details from your application’s
  1617. existing database), use the
  1618. <literal>DaoAuthenticationProvider</literal> along with the
  1619. <literal>UserDetailsService</literal>. It is the fastest and
  1620. safest way to integrate an external database.</para>
  1621. </listitem>
  1622. <listitem>
  1623. <para>If you're using Container Adapters or a
  1624. <literal>RunAsManager</literal> that replaces the
  1625. <literal>Authentication</literal> object, ensure you have
  1626. registered the <literal>AuthByAdapterProvider</literal> and
  1627. <literal>RunAsManagerImplProvider</literal> respectively with your
  1628. <literal>ProviderManager</literal>.</para>
  1629. </listitem>
  1630. <listitem>
  1631. <para>Never enable the
  1632. <literal>TestingAuthenticationProvider</literal> on a production
  1633. system. Doing so will allow any client to simply present a
  1634. <literal>TestingAuthenticationToken</literal> and obtain whatever
  1635. access they request.</para>
  1636. </listitem>
  1637. <listitem>
  1638. <para>Adding a new <literal>AuthenticationProvider</literal> is
  1639. sufficient to support most custom authentication requirements.
  1640. Only unusual requirements would require the
  1641. <literal>ProviderManager</literal> to be replaced with a different
  1642. <literal>AuthenticationManager</literal>.</para>
  1643. </listitem>
  1644. </itemizedlist>
  1645. </sect2>
  1646. </sect1>
  1647. <sect1 id="security-authorization">
  1648. <title>Authorization</title>
  1649. <sect2 id="security-authorization-granted-authorities">
  1650. <title>Granted Authorities</title>
  1651. <para>As briefly mentioned in the Authentication section, all
  1652. <literal>Authentication</literal> implementations are required to
  1653. store an array of <literal>GrantedAuthority</literal> objects. These
  1654. represent the authorities that have been granted to the principal. The
  1655. <literal>GrantedAuthority</literal> objects are inserted into the
  1656. <literal>Authentication</literal> object by the
  1657. <literal>AuthenticationManager</literal> and are later read by
  1658. <literal>AccessDecisionManager</literal>s when making authorization
  1659. decisions.</para>
  1660. <para><literal>GrantedAuthority</literal> is an interface with only
  1661. one method:</para>
  1662. <para><programlisting>public String getAuthority();</programlisting></para>
  1663. <para>This method allows <literal>AccessDecisionManager</literal>s to
  1664. obtain a precise <literal>String</literal> representation of the
  1665. <literal>GrantedAuthority</literal>. By returning a representation as
  1666. a <literal>String</literal>, a <literal>GrantedAuthority</literal> can
  1667. be easily "read" by most <literal>AccessDecisionManager</literal>s. If
  1668. a <literal>GrantedAuthority</literal> cannot be precisely represented
  1669. as a <literal>String</literal>, the
  1670. <literal>GrantedAuthority</literal> is considered "complex" and
  1671. <literal>getAuthority()</literal> must return
  1672. <literal>null</literal>.</para>
  1673. <para>An example of a "complex" <literal>GrantedAuthority</literal>
  1674. would be an implementation that stores a list of operations and
  1675. authority thresholds that apply to different customer account numbers.
  1676. Representing this complex <literal>GrantedAuthority</literal> as a
  1677. <literal>String</literal> would be quite complex, and as a result the
  1678. <literal>getAuthority()</literal> method should return
  1679. <literal>null</literal>. This will indicate to any
  1680. <literal>AccessDecisionManager</literal> that it will need to
  1681. specifically support the <literal>GrantedAuthority</literal>
  1682. implementation in order to understand its contents.</para>
  1683. <para>The Acegi Security System for Spring includes one concrete
  1684. <literal>GrantedAuthority</literal> implementation,
  1685. <literal>GrantedAuthorityImpl</literal>. This allows any
  1686. user-specified <literal>String</literal> to be converted into a
  1687. <literal>GrantedAuthority</literal>. All
  1688. <literal>AuthenticationProvider</literal>s included with the security
  1689. architecture use <literal>GrantedAuthorityImpl</literal> to populate
  1690. the <literal>Authentication</literal> object.</para>
  1691. </sect2>
  1692. <sect2 id="security-authorization-access-decision-managers">
  1693. <title>Access Decision Managers</title>
  1694. <para>The <literal>AccessDecisionManager</literal> is called by the
  1695. <literal>AbstractSecurityInterceptor</literal> and is responsible for
  1696. making final access control decisions. The
  1697. <literal>AccessDecisionManager</literal> interface contains three
  1698. methods:</para>
  1699. <para><programlisting>public void decide(Authentication authentication, Object object, ConfigAttributeDefinition config) throws AccessDeniedException;
  1700. public boolean supports(ConfigAttribute attribute);
  1701. public boolean supports(Class clazz);</programlisting></para>
  1702. <para>As can be seen from the first method, the
  1703. <literal>AccessDecisionManager</literal> is passed via method
  1704. parameters all information that is likely to be of value in assessing
  1705. an authorization decision. In particular, passing the secure
  1706. <literal>Object</literal> enables those arguments contained in the
  1707. actual secure object invocation to be inspected. For example, let's
  1708. assume the secure object was a <literal>MethodInvocation</literal>. It
  1709. would be easy to query the <literal>MethodInvocation</literal> for any
  1710. <literal>Customer</literal> argument, and then implement some sort of
  1711. security logic in the <literal>AccessDecisionManager</literal> to
  1712. ensure the principal is permitted to operate on that customer.
  1713. Implementations are expected to throw an
  1714. <literal>AccessDeniedException</literal> if access is denied.</para>
  1715. <para>The <literal>supports(ConfigAttribute)</literal> method is
  1716. called by the <literal>AbstractSecurityInterceptor</literal> at
  1717. startup time to determine if the
  1718. <literal>AccessDecisionManager</literal> can process the passed
  1719. <literal>ConfigAttribute</literal>. The
  1720. <literal>supports(Class)</literal> method is called by a security
  1721. interceptor implementation to ensure the configured
  1722. <literal>AccessDecisionManager</literal> supports the type of secure
  1723. object that the security interceptor will present.</para>
  1724. </sect2>
  1725. <sect2 id="security-authorization-voting-decision-manager">
  1726. <title>Voting Decision Manager</title>
  1727. <para>Whilst users can implement their own
  1728. <literal>AccessDecisionManager</literal> to control all aspects of
  1729. authorization, the Acegi Security System for Spring includes several
  1730. <literal>AccessDecisionManager</literal> implementations that are
  1731. based on voting. Figure 4 illustrates the relevant classes.</para>
  1732. <para><mediaobject>
  1733. <imageobject role="html">
  1734. <imagedata align="center"
  1735. fileref="images/AccessDecisionVoting.gif"
  1736. format="GIF" />
  1737. </imageobject>
  1738. <caption>
  1739. <para>Figure 4: Voting Decision Manager</para>
  1740. </caption>
  1741. </mediaobject></para>
  1742. <para>Using this approach, a series of
  1743. <literal>AccessDecisionVoter</literal> implementations are polled on
  1744. an authorization decision. The
  1745. <literal>AccessDecisionManager</literal> then decides whether or not
  1746. to throw an <literal>AccessDeniedException</literal> based on its
  1747. assessment of the votes.</para>
  1748. <para>The <literal>AccessDecisionVoter</literal> interface has three
  1749. methods:</para>
  1750. <para><programlisting>public int vote(Authentication authentication, Object object, ConfigAttributeDefinition config);
  1751. public boolean supports(ConfigAttribute attribute);
  1752. public boolean supports(Class clazz);</programlisting></para>
  1753. <para>Concrete implementations return an <literal>int</literal>, with
  1754. possible values being reflected in the
  1755. <literal>AccessDecisionVoter</literal> static fields
  1756. <literal>ACCESS_ABSTAIN</literal>, <literal>ACCESS_DENIED</literal>
  1757. and <literal>ACCESS_GRANTED</literal>. A voting implementation will
  1758. return <literal>ACCESS_ABSTAIN</literal> if it has no opinion on an
  1759. authorization decision. If it does have an opinion, it must return
  1760. either <literal>ACCESS_DENIED</literal> or
  1761. <literal>ACCESS_GRANTED</literal>.</para>
  1762. <para>There are three concrete
  1763. <literal>AccessDecisionManager</literal>s provided with the Acegi
  1764. Security System for Spring that tally the votes. The
  1765. <literal>ConsensusBased</literal> implementation will grant or deny
  1766. access based on the consensus of non-abstain votes. Properties are
  1767. provided to control behavior in the event of an equality of votes or
  1768. if all votes are abstain. The <literal>AffirmativeBased</literal>
  1769. implementation will grant access if one or more
  1770. <literal>ACCESS_GRANTED</literal> votes were received (ie a deny vote
  1771. will be ignored, provided there was at least one grant vote). Like the
  1772. <literal>ConsensusBased</literal> implementation, there is a parameter
  1773. that controls the behavior if all voters abstain. The
  1774. <literal>UnanimousBased</literal> provider expects unanimous
  1775. <literal>ACCESS_GRANTED</literal> votes in order to grant access,
  1776. ignoring abstains. It will deny access if there is any
  1777. <literal>ACCESS_DENIED</literal> vote. Like the other implementations,
  1778. there is a parameter that controls the behaviour if all voters
  1779. abstain.</para>
  1780. <para>It is possible to implement a custom
  1781. <literal>AccessDecisionManager</literal> that tallies votes
  1782. differently. For example, votes from a particular
  1783. <literal>AccessDecisionVoter</literal> might receive additional
  1784. weighting, whilst a deny vote from a particular voter may have a veto
  1785. effect.</para>
  1786. <para>There are two concrete <literal>AccessDecisionVoter</literal>
  1787. implementations provided with the Acegi Security System for Spring.
  1788. The <literal>RoleVoter</literal> class will vote if any
  1789. ConfigAttribute begins with <literal>ROLE_</literal>. It will vote to
  1790. grant access if there is a <literal>GrantedAuthority</literal> which
  1791. returns a <literal>String</literal> representation (via the
  1792. <literal>getAuthority()</literal> method) exactly equal to one or more
  1793. <literal>ConfigAttributes</literal> starting with
  1794. <literal>ROLE_</literal>. If there is no exact match of any
  1795. <literal>ConfigAttribute</literal> starting with
  1796. <literal>ROLE_</literal>, the <literal>RoleVoter</literal> will vote
  1797. to deny access. If no <literal>ConfigAttribute</literal> begins with
  1798. <literal>ROLE_</literal>, the voter will abstain.
  1799. <literal>RoleVoter</literal> is case sensitive on comparisons as well
  1800. as the <literal>ROLE_</literal> prefix.</para>
  1801. <para>BasicAclEntryVoter is the other concrete voter included with
  1802. Acegi Security. It integrates with Acegi Security's
  1803. <literal>AclManager</literal> (discussed later). This voter is
  1804. designed to have multiple instances in the same application context,
  1805. such as:</para>
  1806. <para><programlisting>
  1807. &lt;bean id="aclContactReadVoter" class="org.acegisecurity.vote.BasicAclEntryVoter"&gt;
  1808. &lt;property name="processConfigAttribute"&gt;&lt;value&gt;ACL_CONTACT_READ&lt;/value&gt;&lt;/property&gt;
  1809. &lt;property name="processDomainObjectClass"&gt;&lt;value&gt;sample.contact.Contact&lt;/value&gt;&lt;/property&gt;
  1810. &lt;property name="aclManager"&gt;&lt;ref local="aclManager"/&gt;&lt;/property&gt;
  1811. &lt;property name="requirePermission"&gt;
  1812. &lt;list&gt;
  1813. &lt;ref local="org.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/&gt;
  1814. &lt;ref local="org.acegisecurity.acl.basic.SimpleAclEntry.READ"/&gt;
  1815. &lt;/list&gt;
  1816. &lt;/property&gt;
  1817. &lt;/bean&gt;
  1818. &lt;bean id="aclContactDeleteVoter" class="org.acegisecurity.vote.BasicAclEntryVoter"&gt;
  1819. &lt;property name="processConfigAttribute"&gt;&lt;value&gt;ACL_CONTACT_DELETE&lt;/value&gt;&lt;/property&gt;
  1820. &lt;property name="processDomainObjectClass"&gt;&lt;value&gt;sample.contact.Contact&lt;/value&gt;&lt;/property&gt;
  1821. &lt;property name="aclManager"&gt;&lt;ref local="aclManager"/&gt;&lt;/property&gt;
  1822. &lt;property name="requirePermission"&gt;
  1823. &lt;list&gt;
  1824. &lt;ref local="org.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/&gt;
  1825. &lt;ref local="org.acegisecurity.acl.basic.SimpleAclEntry.DELETE"/&gt;
  1826. &lt;/list&gt;
  1827. &lt;/property&gt;
  1828. &lt;/bean&gt;
  1829. </programlisting></para>
  1830. <para>In the above example, you'd define
  1831. <literal>ACL_CONTACT_READ</literal> or
  1832. <literal>ACL_CONTACT_DELETE</literal> against some methods on a
  1833. <literal>MethodSecurityInterceptor</literal> or
  1834. <literal>AspectJSecurityInterceptor</literal>. When those methods are
  1835. invoked, the above applicable voter defined above would vote to grant
  1836. or deny access. The voter would look at the method invocation to
  1837. locate the first argument of type
  1838. <literal>sample.contact.Contact</literal>, and then pass that
  1839. <literal>Contact</literal> to the <literal>AclManager</literal>. The
  1840. <literal>AclManager</literal> will then return an access control list
  1841. (ACL) that applies to the current <literal>Authentication</literal>.
  1842. Assuming that ACL contains one of the listed
  1843. <literal>requirePermission</literal>s, the voter will vote to grant
  1844. access. If the ACL does not contain one of the permissions defined
  1845. against the voter, the voter will vote to deny access.
  1846. <literal>BasicAclEntryVoter</literal> is an important class as it
  1847. allows you to build truly complex applications with domain object
  1848. security entirely defined in the application context. If you're
  1849. interested in learning more about Acegi Security's ACL capabilities
  1850. and how best to apply them, please see the ACL and "After Invocation"
  1851. sections of this reference guide, and the Contacts sample
  1852. application.</para>
  1853. <para>It is also possible to implement a custom
  1854. <literal>AccessDecisionVoter</literal>. Several examples are provided
  1855. in the Acegi Security System for Spring unit tests, including
  1856. <literal>ContactSecurityVoter</literal> and
  1857. <literal>DenyVoter</literal>. The
  1858. <literal>ContactSecurityVoter</literal> abstains from voting decisions
  1859. where a <literal>CONTACT_OWNED_BY_CURRENT_USER</literal>
  1860. <literal>ConfigAttribute</literal> is not found. If voting, it queries
  1861. the <literal>MethodInvocation</literal> to extract the owner of the
  1862. <literal>Contact</literal> object that is subject of the method call.
  1863. It votes to grant access if the <literal>Contact</literal> owner
  1864. matches the principal presented in the
  1865. <literal>Authentication</literal> object. It could have just as easily
  1866. compared the <literal>Contact</literal> owner with some
  1867. <literal>GrantedAuthority</literal> the
  1868. <literal>Authentication</literal> object presented. All of this is
  1869. achieved with relatively few lines of code and demonstrates the
  1870. flexibility of the authorization model.</para>
  1871. </sect2>
  1872. <sect2 id="security-authorization-taglib">
  1873. <title>Authorization-Related Tag Libraries</title>
  1874. <para>The Acegi Security System for Spring comes bundled with several
  1875. JSP tag libraries that eases JSP writing. The tag libraries are known
  1876. as <literal>authz</literal> and provide a range of different
  1877. services.</para>
  1878. <para>All taglib classes are included in the core
  1879. <literal>acegi-security-xx.jar</literal> file, with the
  1880. <literal>authz.tld</literal> located in the JAR's
  1881. <literal>META-INF</literal> directory. This means for JSP 1.2+ web
  1882. containers you can simply include the JAR in the WAR's
  1883. <literal>WEB-INF/lib</literal> directory and it will be available. If
  1884. you're using a JSP 1.1 container, you'll need to declare the JSP
  1885. taglib in your <literal>web.xml file</literal>, and include
  1886. <literal>authz.tld</literal> in the <literal>WEB-INF/lib</literal>
  1887. directory. The following fragment is added to
  1888. <literal>web.xml</literal>:</para>
  1889. <para><programlisting>
  1890. &lt;taglib&gt;
  1891. &lt;taglib-uri&gt;http://acegisecurity.sf.net/authz&lt;/taglib-uri&gt;
  1892. &lt;taglib-location&gt;/WEB-INF/authz.tld&lt;/taglib-location&gt;
  1893. &lt;/taglib&gt;
  1894. </programlisting></para>
  1895. <sect3>
  1896. <title>AuthorizeTag</title>
  1897. <para><literal>AuthorizeTag</literal> is used to include content if
  1898. the current principal holds certain
  1899. <literal>GrantedAuthority</literal>s.</para>
  1900. <para>The following JSP fragment illustrates how to use the
  1901. <literal>AuthorizeTag</literal>:</para>
  1902. <para><programlisting>
  1903. &lt;authz:authorize ifAllGranted="ROLE_SUPERVISOR"&gt;
  1904. &lt;td&gt;
  1905. &lt;A HREF="del.htm?id=&lt;c:out value="${contact.id}"/&gt;"&gt;Del&lt;/A&gt;
  1906. &lt;/td&gt;
  1907. &lt;/authz:authorize&gt;
  1908. </programlisting></para>
  1909. <para>This tag would cause the tag's body to be output if the
  1910. principal has been granted ROLE_SUPERVISOR.</para>
  1911. <para>The <literal>authz:authorize</literal> tag declares the
  1912. following attributes:</para>
  1913. <para><itemizedlist spacing="compact">
  1914. <listitem>
  1915. <para><literal>ifAllGranted</literal>: All the listed roles
  1916. must be granted for the tag to output its body.</para>
  1917. </listitem>
  1918. <listitem>
  1919. <para><literal>ifAnyGranted</literal>: Any of the listed roles
  1920. must be granted for the tag to output its body.</para>
  1921. </listitem>
  1922. <listitem>
  1923. <para><literal>ifNotGranted</literal>: None of the listed
  1924. roles must be granted for the tag to output its body.</para>
  1925. </listitem>
  1926. </itemizedlist></para>
  1927. <para>You'll note that in each attribute you can list multiple
  1928. roles. Simply separate the roles using a comma. The
  1929. <literal>authorize</literal> tag ignores whitespace in
  1930. attributes.</para>
  1931. <para>The tag library logically ANDs all of it's parameters
  1932. together. This means that if you combine two or more attributes, all
  1933. attributes must be true for the tag to output it's body. Don't add
  1934. an <literal>ifAllGranted="ROLE_SUPERVISOR"</literal>, followed by an
  1935. <literal>ifNotGranted="ROLE_SUPERVISOR"</literal>, or you'll be
  1936. surprised to never see the tag's body.</para>
  1937. <para>By requiring all attributes to return true, the authorize tag
  1938. allows you to create more complex authorization scenarios. For
  1939. example, you could declare an
  1940. <literal>ifAllGranted="ROLE_SUPERVISOR"</literal> and an
  1941. <literal>ifNotGranted="ROLE_NEWBIE_SUPERVISOR"</literal> in the same
  1942. tag, in order to prevent new supervisors from seeing the tag body.
  1943. However it would no doubt be simpler to use
  1944. <literal>ifAllGranted="ROLE_EXPERIENCED_SUPERVISOR"</literal> rather
  1945. than inserting NOT conditions into your design.</para>
  1946. <para>One last item: the tag verifies the authorizations in a
  1947. specific order: first <literal>ifNotGranted</literal>, then
  1948. <literal>ifAllGranted</literal>, and finally,
  1949. <literal>ifAnyGranted</literal>.</para>
  1950. </sect3>
  1951. <sect3>
  1952. <title>AuthenticationTag</title>
  1953. <para><literal>AuthenticationTag</literal> is used to simply output
  1954. a property of the current principal's
  1955. <literal>Authentication.getPrincipal()</literal> object to the web
  1956. page.</para>
  1957. <para>The following JSP fragment illustrates how to use the
  1958. <literal>AuthenticationTag</literal>:</para>
  1959. <para><programlisting>&lt;authz:authentication operation="username"/&gt;</programlisting></para>
  1960. <para>This tag would cause the principal's name to be output. Here
  1961. we are assuming the <literal>Authentication.getPrincipal()</literal>
  1962. is a <literal>UserDetails</literal> object, which is generally the
  1963. case when using the typical
  1964. <literal>DaoAuthenticationProvider</literal>.</para>
  1965. </sect3>
  1966. <sect3>
  1967. <title>AclTag</title>
  1968. <para><literal>AclTag</literal> is used to include content if the
  1969. current principal has a ACL to the indicated domain object.</para>
  1970. <para>The following JSP fragment illustrates how to use the
  1971. <literal>AclTag</literal>:</para>
  1972. <para><programlisting>
  1973. &lt;authz:acl domainObject="${contact}" hasPermission="16,1"&gt;
  1974. &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;
  1975. &lt;/authz:acl&gt;
  1976. </programlisting></para>
  1977. <para>This tag would cause the tag's body to be output if the
  1978. principal holds either permission 16 or permission 1 for the
  1979. "contact" domain object. The numbers are actually integers that are
  1980. used with <literal>AbstractBasicAclEntry</literal> bit masking.
  1981. Please refer to the ACL section of this reference guide to
  1982. understand more about the ACL capabilities of Acegi Security.</para>
  1983. </sect3>
  1984. </sect2>
  1985. <sect2 id="security-authorization-recommendations">
  1986. <title>Authorization Recommendations</title>
  1987. <para>Given there are several ways to achieve similar authorization
  1988. outcomes in the Acegi Security System for Spring, the following
  1989. general recommendations are made:</para>
  1990. <itemizedlist>
  1991. <listitem>
  1992. <para>Grant authorities using
  1993. <literal>GrantedAuthorityImpl</literal> where possible. Because it
  1994. is already supported by the Acegi Security System for Spring, you
  1995. avoid the need to create custom
  1996. <literal>AuthenticationManager</literal> or
  1997. <literal>AuthenticationProvider</literal> implementations simply
  1998. to populate the <literal>Authentication</literal> object with a
  1999. custom <literal>GrantedAuthority</literal>.</para>
  2000. </listitem>
  2001. <listitem>
  2002. <para>Writing an <literal>AccessDecisionVoter</literal>
  2003. implementation and using either <literal>ConsensusBased</literal>,
  2004. <literal>AffirmativeBased</literal> or
  2005. <literal>UnanimousBased</literal> as the
  2006. <literal>AccessDecisionManager</literal> may be the best approach
  2007. to implementing your custom access decision rules.</para>
  2008. </listitem>
  2009. </itemizedlist>
  2010. </sect2>
  2011. </sect1>
  2012. <sect1 id="afterinvocation">
  2013. <title>After Invocation Handling</title>
  2014. <sect2 id="afterinvocation-overview">
  2015. <title>Overview</title>
  2016. <para>Whilst the <literal>AccessDecisionManager</literal> is called by
  2017. the <literal>AbstractSecurityInterceptor</literal> before proceeding
  2018. with the secure object invocation, some applications need a way of
  2019. modifying the object actually returned by the secure object
  2020. invocation. Whilst you could easily implement your own AOP concern to
  2021. achieve this, Acegi Security provides a convenient hook that has
  2022. several concrete implementations that integrate with its ACL
  2023. capabilities.</para>
  2024. <para>Figure 5 illustrates Acegi Security's
  2025. <literal>AfterInvocationManager</literal> and its concrete
  2026. implementations.</para>
  2027. <para><mediaobject>
  2028. <imageobject role="html">
  2029. <imagedata align="center" fileref="images/AfterInvocation.gif"
  2030. format="GIF" />
  2031. </imageobject>
  2032. <caption>
  2033. <para>Figure 5: After Invocation Implementation</para>
  2034. </caption>
  2035. </mediaobject></para>
  2036. <para>Like many other parts of Acegi Security,
  2037. <literal>AfterInvocationManager</literal> has a single concrete
  2038. implementation, <literal>AfterInvocationProvider</literal>, which
  2039. polls a list of <literal>AfterInvocationProvider</literal>s. Each
  2040. <literal>AfterInvocationProvider</literal> is allowed to modify the
  2041. return object or throw an <literal>AccessDeniedException</literal>.
  2042. Indeed multiple providers can modify the object, as the result of the
  2043. previous provider is passed to the next in the list. Let's now
  2044. consider our ACL-aware implementations of
  2045. <literal>AfterInvocationProvider</literal>.</para>
  2046. <para>Please be aware that if you're using
  2047. <literal>AfterInvocationManager</literal>, you will still need
  2048. configuration attributes that allow the
  2049. <literal>MethodSecurityInterceptor</literal>'s
  2050. <literal>AccessDecisionManager</literal> to allow an operation. If
  2051. you're using the typical Acegi Security included
  2052. <literal>AccessDecisionManager</literal> implementations, having no
  2053. configuration attributes defined for a particular secure method
  2054. invocation will cause each <literal>AccessDecisionVoter</literal> to
  2055. abstain from voting. In turn, if the
  2056. <literal>AccessDecisionManager</literal> property
  2057. "<literal>allowIfAllAbstainDecisions</literal>" is
  2058. <literal>false</literal>, an <literal>AccessDeniedException</literal>
  2059. will be thrown. You may avoid this potential issue by either (i)
  2060. setting "<literal>allowIfAllAbstainDecisions</literal>" to
  2061. <literal>true</literal> (although this is generally not recommended)
  2062. or (ii) simply ensure that there is at least one configuration
  2063. attribute that an <literal>AccessDecisionVoter</literal> will vote to
  2064. grant access for. This latter (recommended) approach is usually
  2065. achieved through a <literal>ROLE_USER</literal> or
  2066. <literal>ROLE_AUTHENTICATED</literal> configuration attribute.</para>
  2067. </sect2>
  2068. <sect2 id="afterinvocation-acl-aware">
  2069. <title>ACL-Aware AfterInvocationProviders</title>
  2070. <para>A common services layer method we've all written at one stage or
  2071. another looks like this:</para>
  2072. <para><programlisting>public Contact getById(Integer id);</programlisting></para>
  2073. <para>Quite often, only principals with permission to read the
  2074. <literal>Contact</literal> should be allowed to obtain it. In this
  2075. situation the <literal>AccessDecisionManager</literal> approach
  2076. provided by the <literal>AbstractSecurityInterceptor</literal> will
  2077. not suffice. This is because the identity of the
  2078. <literal>Contact</literal> is all that is available before the secure
  2079. object is invoked. The
  2080. <literal>BasicAclAfterInvocationProvider</literal> delivers a
  2081. solution, and is configured as follows:</para>
  2082. <para><programlisting>
  2083. &lt;bean id="afterAclRead" class="org.acegisecurity.afterinvocation.BasicAclEntryAfterInvocationProvider"&gt;
  2084. &lt;property name="aclManager"&gt;&lt;ref local="aclManager"/&gt;&lt;/property&gt;
  2085. &lt;property name="requirePermission"&gt;
  2086. &lt;list&gt;
  2087. &lt;ref local="org.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/&gt;
  2088. &lt;ref local="org.acegisecurity.acl.basic.SimpleAclEntry.READ"/&gt;
  2089. &lt;/list&gt;
  2090. &lt;/property&gt;
  2091. &lt;/bean&gt;
  2092. </programlisting></para>
  2093. <para>In the above example, the <literal>Contact</literal> will be
  2094. retrieved and passed to the
  2095. <literal>BasicAclEntryAfterInvocationProvider</literal>. The provider
  2096. will thrown an <literal>AccessDeniedException</literal> if one of the
  2097. listed <literal>requirePermission</literal>s is not held by the
  2098. <literal>Authentication</literal>. The
  2099. <literal>BasicAclEntryAfterInvocationProvider</literal> queries the
  2100. <literal>AclManager</literal> to determine the ACL that applies for
  2101. this domain object to this <literal>Authentication</literal>.</para>
  2102. <para>Similar to the
  2103. <literal>BasicAclEntryAfterInvocationProvider</literal> is
  2104. <literal>BasicAclEntryAfterInvocationCollectionFilteringProvider</literal>.
  2105. It is designed to remove <literal>Collection</literal> or array
  2106. elements for which a principal does not have access. It never thrown
  2107. an <literal>AccessDeniedException</literal> - simply silently removes
  2108. the offending elements. The provider is configured as follows:</para>
  2109. <para><programlisting>
  2110. &lt;bean id="afterAclCollectionRead" class="org.acegisecurity.afterinvocation.BasicAclEntryAfterInvocationCollectionFilteringProvider"&gt;
  2111. &lt;property name="aclManager"&gt;&lt;ref local="aclManager"/&gt;&lt;/property&gt;
  2112. &lt;property name="requirePermission"&gt;
  2113. &lt;list&gt;
  2114. &lt;ref local="org.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/&gt;
  2115. &lt;ref local="org.acegisecurity.acl.basic.SimpleAclEntry.READ"/&gt;
  2116. &lt;/list&gt;
  2117. &lt;/property&gt;
  2118. &lt;/bean&gt;
  2119. </programlisting></para>
  2120. <para>As you can imagine, the returned <literal>Object</literal> must
  2121. be a <literal>Collection</literal> or array for this provider to
  2122. operate. It will remove any element if the
  2123. <literal>AclManager</literal> indicates the
  2124. <literal>Authentication</literal> does not hold one of the listed
  2125. <literal>requirePermission</literal>s.</para>
  2126. <para>The Contacts sample application demonstrates these two
  2127. <literal>AfterInvocationProvider</literal>s.</para>
  2128. </sect2>
  2129. </sect1>
  2130. <sect1 id="security-run-as">
  2131. <title>Run-As Authentication Replacement</title>
  2132. <sect2 id="security-run-as-purpose">
  2133. <title>Purpose</title>
  2134. <para>The <literal>AbstractSecurityInterceptor</literal> is able to
  2135. temporarily replace the <literal>Authentication</literal> object in
  2136. the <literal>SecurityContext</literal> and
  2137. <literal>SecurityContextHolder</literal> during the
  2138. <literal>SecurityInterceptorCallback</literal>. This only occurs if
  2139. the original <literal>Authentication</literal> object was successfully
  2140. processed by the <literal>AuthenticationManager</literal> and
  2141. <literal>AccessDecisionManager</literal>. The
  2142. <literal>RunAsManager</literal> will indicate the replacement
  2143. <literal>Authentication</literal> object, if any, that should be used
  2144. during the <literal>SecurityInterceptorCallback</literal>.</para>
  2145. <para>By temporarily replacing the <literal>Authentication</literal>
  2146. object during a <literal>SecurityInterceptorCallback</literal>, the
  2147. secured invocation will be able to call other objects which require
  2148. different authentication and authorization credentials. It will also
  2149. be able to perform any internal security checks for specific
  2150. <literal>GrantedAuthority</literal> objects. Because Acegi Security
  2151. provides a number of helper classes that automatically configure
  2152. remoting protocols based on the contents of the
  2153. <literal>ContextHolder</literal>, these run-as replacements are
  2154. particularly useful when calling remote web services.</para>
  2155. </sect2>
  2156. <sect2 id="security-run-as-usage">
  2157. <title>Usage</title>
  2158. <para>A <literal>RunAsManager</literal> interface is provided by the
  2159. Acegi Security System for Spring:</para>
  2160. <para><programlisting>public Authentication buildRunAs(Authentication authentication, Object object, ConfigAttributeDefinition config);
  2161. public boolean supports(ConfigAttribute attribute);
  2162. public boolean supports(Class clazz);</programlisting></para>
  2163. <para>The first method returns the <literal>Authentication</literal>
  2164. object that should replace the existing
  2165. <literal>Authentication</literal> object for the duration of the
  2166. method invocation. If the method returns <literal>null</literal>, it
  2167. indicates no replacement should be made. The second method is used by
  2168. the <literal>AbstractSecurityInterceptor</literal> as part of its
  2169. startup validation of configuration attributes. The
  2170. <literal>supports(Class)</literal> method is called by a security
  2171. interceptor implementation to ensure the configured
  2172. <literal>RunAsManager</literal> supports the type of secure object
  2173. that the security interceptor will present.</para>
  2174. <para>One concrete implementation of a <literal>RunAsManager</literal>
  2175. is provided with the Acegi Security System for Spring. The
  2176. <literal>RunAsManagerImpl</literal> class returns a replacement
  2177. <literal>RunAsUserToken</literal> if any
  2178. <literal>ConfigAttribute</literal> starts with
  2179. <literal>RUN_AS_</literal>. If any such
  2180. <literal>ConfigAttribute</literal> is found, the replacement
  2181. <literal>RunAsUserToken</literal> will contain the same principal,
  2182. credentials and granted authorities as the original
  2183. <literal>Authentication</literal> object, along with a new
  2184. <literal>GrantedAuthorityImpl</literal> for each
  2185. <literal>RUN_AS_</literal> <literal>ConfigAttribute</literal>. Each
  2186. new <literal>GrantedAuthorityImpl</literal> will be prefixed with
  2187. <literal>ROLE_</literal>, followed by the <literal>RUN_AS</literal>
  2188. <literal>ConfigAttribute</literal>. For example, a
  2189. <literal>RUN_AS_SERVER</literal> will result in the replacement
  2190. <literal>RunAsUserToken</literal> containing a
  2191. <literal>ROLE_RUN_AS_SERVER</literal> granted authority.</para>
  2192. <para>The replacement <literal>RunAsUserToken</literal> is just like
  2193. any other <literal>Authentication</literal> object. It needs to be
  2194. authenticated by the <literal>AuthenticationManager</literal>,
  2195. probably via delegation to a suitable
  2196. <literal>AuthenticationProvider</literal>. The
  2197. <literal>RunAsImplAuthenticationProvider</literal> performs such
  2198. authentication. It simply accepts as valid any
  2199. <literal>RunAsUserToken</literal> presented.</para>
  2200. <para>To ensure malicious code does not create a
  2201. <literal>RunAsUserToken</literal> and present it for guaranteed
  2202. acceptance by the <literal>RunAsImplAuthenticationProvider</literal>,
  2203. the hash of a key is stored in all generated tokens. The
  2204. <literal>RunAsManagerImpl</literal> and
  2205. <literal>RunAsImplAuthenticationProvider</literal> is created in the
  2206. bean context with the same key:</para>
  2207. <para><programlisting>
  2208. &lt;bean id="runAsManager" class="org.acegisecurity.runas.RunAsManagerImpl"&gt;
  2209. &lt;property name="key"&gt;&lt;value&gt;my_run_as_password&lt;/value&gt;&lt;/property&gt;
  2210. &lt;/bean&gt;
  2211. &lt;bean id="runAsAuthenticationProvider" class="org.acegisecurity.runas.RunAsImplAuthenticationProvider"&gt;
  2212. &lt;property name="key"&gt;&lt;value&gt;my_run_as_password&lt;/value&gt;&lt;/property&gt;
  2213. &lt;/bean&gt;
  2214. </programlisting></para>
  2215. <para>By using the same key, each <literal>RunAsUserToken</literal>
  2216. can be validated it was created by an approved
  2217. <literal>RunAsManagerImpl</literal>. The
  2218. <literal>RunAsUserToken</literal> is immutable after creation for
  2219. security reasons.</para>
  2220. </sect2>
  2221. </sect1>
  2222. <sect1 id="security-ui">
  2223. <title>User Interfacing with the SecurityContextHolder</title>
  2224. <sect2 id="security-ui-purpose">
  2225. <title>Purpose</title>
  2226. <para>Everything presented so far assumes one thing: the
  2227. <literal>SecurityContextHolder</literal> is populated with a valid
  2228. <literal>SecurityContext</literal>, which in turn contains a valid
  2229. <literal>Authentication</literal> object. Developers are free to do
  2230. this in whichever way they like, such as directly calling the relevant
  2231. objects at runtime. However, several classes have been provided to
  2232. make this process transparent in many situations. We call these
  2233. classes "authentication mechanisms".</para>
  2234. <para>The <literal>org.acegisecurity.ui</literal> package provides
  2235. what we call "authentication processing mechanisms". An authentication
  2236. processing mechanism is solely concerned with received an
  2237. authentication request from the principal, testing if it seems valid,
  2238. and if so, placing the authentication request token onto the
  2239. <literal>SecurityContextHolder</literal>. Of course, if the
  2240. authentication request is invalid, the authentication processing
  2241. mechanism is responsible for informing the principal in whatever way
  2242. is appropriate to the protocol.</para>
  2243. <para>Recall the
  2244. <literal>HttpSessionContextIntegrationFilter</literal> (discussed in
  2245. the context section) is responsible for storing the
  2246. <literal>SecurityContextHolder</literal> contents between invocations.
  2247. This means no authentication processing mechanism need ever interact
  2248. directly with <literal>HttpSession</literal>. Indeed
  2249. <literal>HttpSessionContextIntegrationFilter</literal> has been
  2250. designed to minimise the unnecessary creation of
  2251. <literal>HttpSession</literal>s, as might occur when using Basic
  2252. authentication for example.</para>
  2253. <para>There are several authentication processing mechanisms included
  2254. with Acegi Security, which will be briefly discussed in this chapter.
  2255. The most popular (and almost always recommended) approach is HTTP Form
  2256. Authentication, which uses a login form to authenticate the user.
  2257. Another approach (commonly use with web services) is HTTP Basic
  2258. Authentication, which allows clients to use HTTP headers to present
  2259. authentication information to the Acegi Security System for Spring.
  2260. Alternatively, you can also use JA-SIG Central Authentication Service
  2261. (CAS) for enterprise-wide single sign on. The final (and generally
  2262. unrecommended) approach is via Container Adapters, which allow
  2263. supported web containers to perform the authentication themselves.
  2264. HTTP Form Authentication and Basic Authentication is discussed below,
  2265. whilst CAS and Container Adapters are discussed in separate sections
  2266. of this document.</para>
  2267. </sect2>
  2268. <sect2 id="security-ui-http-form">
  2269. <title>HTTP Form Authentication</title>
  2270. <para>HTTP Form Authentication involves using the
  2271. <literal>AuthenticationProcessingFilter</literal> to process a login
  2272. form. The login form simply contains <literal>j_username</literal> and
  2273. <literal>j_password</literal> input fields, and posts to a URL that is
  2274. monitored by the filter (by default
  2275. <literal>j_acegi_security_check</literal>). The filter is defined in
  2276. <literal>web.xml</literal> behind a
  2277. <literal>FilterToBeanProxy</literal> as follows:</para>
  2278. <para><programlisting>
  2279. &lt;filter&gt;
  2280. &lt;filter-name&gt;Acegi Authentication Processing Filter&lt;/filter-name&gt;
  2281. &lt;filter-class&gt;org.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
  2282. &lt;init-param&gt;
  2283. &lt;param-name&gt;targetClass&lt;/param-name&gt;
  2284. &lt;param-value&gt;org.acegisecurity.ui.webapp.AuthenticationProcessingFilter&lt;/param-value&gt;
  2285. &lt;/init-param&gt;
  2286. &lt;/filter&gt;
  2287. &lt;filter-mapping&gt;
  2288. &lt;filter-name&gt;Acegi Authentication Processing Filter&lt;/filter-name&gt;
  2289. &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
  2290. &lt;/filter-mapping&gt;
  2291. </programlisting></para>
  2292. <para>For a discussion of <literal>FilterToBeanProxy</literal>, please
  2293. refer to the Filters section. The application context will need to
  2294. define the <literal>AuthenticationProcessingFilter</literal>:</para>
  2295. <para><programlisting>
  2296. &lt;bean id="authenticationProcessingFilter" class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter"&gt;
  2297. &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
  2298. &lt;property name="authenticationFailureUrl"&gt;&lt;value&gt;/acegilogin.jsp?login_error=1&lt;/value&gt;&lt;/property&gt;
  2299. &lt;property name="defaultTargetUrl"&gt;&lt;value&gt;/&lt;/value&gt;&lt;/property&gt;
  2300. &lt;property name="filterProcessesUrl"&gt;&lt;value&gt;/j_acegi_security_check&lt;/value&gt;&lt;/property&gt;
  2301. &lt;/bean&gt;
  2302. </programlisting></para>
  2303. <para>The configured <literal>AuthenticationManager</literal>
  2304. processes each authentication request. If authentication fails, the
  2305. browser will be redirected to the
  2306. <literal>authenticationFailureUrl</literal>. The
  2307. <literal>AuthenticationException</literal> will be placed into the
  2308. <literal>HttpSession</literal> attribute indicated by
  2309. <literal>AbstractProcessingFilter.ACEGI_SECURITY_LAST_EXCEPTION_KEY</literal>,
  2310. enabling a reason to be provided to the user on the error page.</para>
  2311. <para>If authentication is successful, the resulting
  2312. <literal>Authentication</literal> object will be placed into the
  2313. <literal>SecurityContextHolder</literal>.</para>
  2314. <para>Once the <literal>SecurityContextHolder</literal> has been
  2315. updated, the browser will need to be redirected to the target URL. The
  2316. target URL is usually indicated by the <literal>HttpSession</literal>
  2317. attribute specified by
  2318. <literal>AbstractProcessingFilter.ACEGI_SECURITY_TARGET_URL_KEY</literal>.
  2319. This attribute is automatically set by the
  2320. <literal>ExceptionTranslationFilter</literal> when an
  2321. <literal>AuthenticationException</literal> occurs, so that after login
  2322. is completed the user can return to what they were trying to access.
  2323. If for some reason the <literal>HttpSession</literal> does not
  2324. indicate the target URL, the browser will be redirected to the
  2325. <literal>defaultTargetUrl</literal> property.</para>
  2326. <para>Because this authentication approach is fully contained within a
  2327. single web application, HTTP Form Authentication is recommended to be
  2328. used instead of Container Adapters.</para>
  2329. </sect2>
  2330. <sect2 id="security-ui-http-basic">
  2331. <title>HTTP Basic Authentication</title>
  2332. <para>The Acegi Security System for Spring provides a
  2333. <literal>BasicProcessingFilter</literal> which is capable of
  2334. processing basic authentication credentials presented in HTTP headers.
  2335. This can be used for authenticating calls made by Spring remoting
  2336. protocols (such as Hessian and Burlap), as well as normal user agents
  2337. (such as Internet Explorer and Navigator). The standard governing HTTP
  2338. Basic Authentication is defined by RFC 1945, Section 11, and the
  2339. <literal>BasicProcessingFilter</literal> conforms with this RFC. Basic
  2340. Authentication is an attractive approach to authentication, because it
  2341. is very widely deployed in user agents and implementation is extremely
  2342. simple (it's just a Base64 encoding of the username:password,
  2343. specified in a HTTP header).</para>
  2344. <para>To implement HTTP Basic Authentication, it is necessary to
  2345. define <literal>BasicProcessingFilter</literal> in the fitler chain.
  2346. The application context will need to define the
  2347. <literal>BasicProcessingFilter</literal> and its required
  2348. collaborator:</para>
  2349. <para><programlisting>
  2350. &lt;bean id="basicProcessingFilter" class="org.acegisecurity.ui.basicauth.BasicProcessingFilter"&gt;
  2351. &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
  2352. &lt;property name="authenticationEntryPoint"&gt;&lt;ref bean="authenticationEntryPoint"/&gt;&lt;/property&gt;
  2353. &lt;/bean&gt;
  2354. &lt;bean id="authenticationEntryPoint" class="org.acegisecurity.ui.basicauth.BasicProcessingFilterEntryPoint"&gt;
  2355. &lt;property name="realmName"&gt;&lt;value&gt;Name Of Your Realm&lt;/value&gt;&lt;/property&gt;
  2356. &lt;/bean&gt;
  2357. </programlisting></para>
  2358. <para>The configured <literal>AuthenticationManager</literal>
  2359. processes each authentication request. If authentication fails, the
  2360. configured <literal>AuthenticationEntryPoint</literal> will be used to
  2361. retry the authentication process. Usually you will use the
  2362. <literal>BasicProcessingFilterEntryPoint</literal>, which returns a
  2363. 401 response with a suitable header to retry HTTP Basic
  2364. authentication. If authentication is successful, the resulting
  2365. <literal>Authentication</literal> object will be placed into the
  2366. <literal>SecurityContextHolder</literal>.</para>
  2367. <para>If the authentication event was successful, or authentication
  2368. was not attempted because the HTTP header did not contain a supported
  2369. authentication request, the filter chain will continue as normal. The
  2370. only time the filter chain will be interrupted is if authentication
  2371. fails and the <literal>AuthenticationEntryPoint</literal> is called,
  2372. as discussed in the previous paragraph.</para>
  2373. </sect2>
  2374. <sect2 id="security-ui-http-digest">
  2375. <title>HTTP Digest Authentication</title>
  2376. <para>The Acegi Security System for Spring provides a
  2377. <literal>DigestProcessingFilter</literal> which is capable of
  2378. processing digest authentication credentials presented in HTTP
  2379. headers. Digest Authentication attempts to solve many of the
  2380. weakenesses of Basic authentication, specifically by ensuring
  2381. credentials are never sent in clear text across the wire. Many user
  2382. agents support Digest Authentication, including FireFox and Internet
  2383. Explorer. The standard governing HTTP Digest Authentication is defined
  2384. by RFC 2617, which updates an earlier version of the Digest
  2385. Authentication standard prescribed by RFC 2069. Most user agents
  2386. implement RFC 2617. The Acegi Security
  2387. <literal>DigestProcessingFilter</literal> is compatible with the
  2388. "<literal>auth</literal>" quality of protection
  2389. (<literal>qop</literal>) prescribed by RFC 2617, which also provides
  2390. backward compatibility with RFC 2069. Digest Authentication is a
  2391. highly attractive option if you need to use unencrypted HTTP (ie no
  2392. TLS/HTTPS) and wish to maximise security of the authentication
  2393. process. Indeed Digest Authentication is a mandatory requirement for
  2394. the WebDAV protocol, as noted by RFC 2518 Section 17.1, so we should
  2395. expect to see it increasingly deployed and replacing Basic
  2396. Authentication.</para>
  2397. <para>Digest Authentication is definitely the most secure choice
  2398. between Form Authentication, Basic Authentication and Digest
  2399. Authentication, although extra security also means more complex user
  2400. agent implementations. Central to Digest Authentication is a "nonce".
  2401. This is a value the server generates. Acegi Security's nonce adopts
  2402. the following format:</para>
  2403. <para><programlisting>base64(expirationTime + ":" + md5Hex(expirationTime + ":" + key))
  2404. expirationTime: The date and time when the nonce expires, expressed in milliseconds
  2405. key: A private key to prevent modification of the nonce token
  2406. </programlisting></para>
  2407. <para>The <literal>DigestProcessingFilterEntryPoint</literal> has a
  2408. property specifying the <literal>key</literal> used for generating the
  2409. nonce tokens, along with a <literal>nonceValiditySeconds</literal>
  2410. property for determining the expiration time (default 300, which
  2411. equals five minutes). Whilstever the nonce is valid, the digest is
  2412. computed by concatenating various strings including the username,
  2413. password, nonce, URI being requested, a client-generated nonce (merely
  2414. a random value which the user agent generates each request), the realm
  2415. name etc, then performing an MD5 hash. Both the server and user agent
  2416. perform this digest computation, resulting in different hash codes if
  2417. they disagree on an included value (eg password). In the Acegi
  2418. Security implementation, if the server-generated nonce has merely
  2419. expired (but the digest was otherwise valid), the
  2420. <literal>DigestProcessingFilterEntryPoint</literal> will send a
  2421. <literal>"stale=true"</literal> header. This tells the user agent
  2422. there is no need to disturb the user (as the password and username etc
  2423. is correct), but simply to try again using a new nonce.</para>
  2424. <para>An appropriate value for
  2425. <literal>DigestProcessingFilterEntryPoint</literal>'s
  2426. <literal>nonceValiditySeconds</literal> parameter will depend on your
  2427. application. Extremely secure applications should note that an
  2428. intercepted authentication header can be used to impersonate the
  2429. principal until the <literal>expirationTime</literal> contained in the
  2430. nonce is reached. This is the key principle when selecting an
  2431. appropriate setting, but it would be unusual for immensly secure
  2432. applications to not be running over TLS/HTTPS in the first
  2433. instance.</para>
  2434. <para>Because of the more complex implementation of Digest
  2435. Authentication, there are often user agent issues. For example,
  2436. Internet Explorer fails to present an "<literal>opaque</literal>"
  2437. token on subsequent requests in the same session. The Acegi Security
  2438. filters therefore encapsulate all state information into the
  2439. "<literal>nonce</literal>" token instead. In our testing, the Acegi
  2440. Security implementation works reliably with FireFox and Internet
  2441. Explorer, correctly handling nonce timeouts etc.</para>
  2442. <para>Now that we've reviewed the theory, let's see how to use it. To
  2443. implement HTTP Digest Authentication, it is necessary to define
  2444. <literal>DigestProcessingFilter</literal> in the fitler chain. The
  2445. application context will need to define the
  2446. <literal>DigestProcessingFilter</literal> and its required
  2447. collaborators:</para>
  2448. <para><programlisting>
  2449. &lt;bean id="digestProcessingFilter" class="org.acegisecurity.ui.digestauth.DigestProcessingFilter"&gt;
  2450. &lt;property name="userDetailsService"&gt;&lt;ref local="jdbcDaoImpl"/&gt;&lt;/property&gt;
  2451. &lt;property name="authenticationEntryPoint"&gt;&lt;ref local="digestProcessingFilterEntryPoint"/&gt;&lt;/property&gt;
  2452. &lt;property name="userCache"&gt;&lt;ref local="userCache"/&gt;&lt;/property&gt;
  2453. &lt;/bean&gt;
  2454. &lt;bean id="digestProcessingFilterEntryPoint" class="org.acegisecurity.ui.digestauth.DigestProcessingFilterEntryPoint"&gt;
  2455. &lt;property name="realmName"&gt;&lt;value&gt;Contacts Realm via Digest Authentication&lt;/value&gt;&lt;/property&gt;
  2456. &lt;property name="key"&gt;&lt;value&gt;acegi&lt;/value&gt;&lt;/property&gt;
  2457. &lt;property name="nonceValiditySeconds"&gt;&lt;value&gt;10&lt;/value&gt;&lt;/property&gt;
  2458. &lt;/bean&gt;
  2459. </programlisting></para>
  2460. <para>The configured <literal>UserDetailsService</literal> is needed
  2461. because <literal>DigestProcessingFilter</literal> must have direct
  2462. access to the clear text password of a user. Digest Authentication
  2463. will NOT work if you are using encoded passwords in your DAO. The DAO
  2464. collaborator, along with the <literal>UserCache</literal>, are
  2465. typically shared directly with a
  2466. <literal>DaoAuthenticationProvider</literal>. The
  2467. <literal>authenticationEntryPoint</literal> property must be
  2468. <literal>DigestProcessingFilterEntryPoint</literal>, so that
  2469. <literal>DigestProcessingFilter</literal> can obtain the correct
  2470. <literal>realmName</literal> and <literal>key</literal> for digest
  2471. calculations.</para>
  2472. <para>Like <literal>BasicAuthenticationFilter</literal>, if
  2473. authentication is successful an <literal>Authentication</literal>
  2474. request token will be placed into the
  2475. <literal>SecurityContextHolder</literal>. If the authentication event
  2476. was successful, or authentication was not attempted because the HTTP
  2477. header did not contain a Digest Authentication request, the filter
  2478. chain will continue as normal. The only time the filter chain will be
  2479. interrupted is if authentication fails and the
  2480. <literal>AuthenticationEntryPoint</literal> is called, as discussed in
  2481. the previous paragraph.</para>
  2482. <para>Digest Authentication's RFC offers a range of additional
  2483. features to further increase security. For example, the nonce can be
  2484. changed on every request. Despite this, the Acegi Security
  2485. implementation was designed to minimise the complexity of the
  2486. implementation (and the doubtless user agent incompatibilities that
  2487. would emerge), and avoid needing to store server-side state. You are
  2488. invited to review RFC 2617 if you wish to explore these features in
  2489. more detail. As far as we are aware, the Acegi Security implementation
  2490. does comply with the minimum standards of this RFC.</para>
  2491. </sect2>
  2492. <sect2 id="security-ui-anonymous">
  2493. <title>Anonymous Authentication</title>
  2494. <para>Particularly in the case of web request URI security, sometimes
  2495. it is more convenient to assign configuration attributes against every
  2496. possible secure object invocation. Put differently, sometimes it is
  2497. nice to say <literal>ROLE_SOMETHING</literal> is required by default
  2498. and only allow certain exceptions to this rule, such as for login,
  2499. logout and home pages of an application. There are also other
  2500. situations where anonymous authentication would be desired, such as
  2501. when an auditing interceptor queries the
  2502. <literal>SecurityContextHolder</literal> to identify which principal
  2503. was responsible for a given operation. Such classes can be authored
  2504. with more robustness if they know the
  2505. <literal>SecurityContextHolder</literal> always contains an
  2506. <literal>Authentication</literal> object, and never
  2507. <literal>null</literal>.</para>
  2508. <para>Acegi Security provides three classes that together provide an
  2509. anoymous authentication feature.
  2510. <literal>AnonymousAuthenticationToken</literal> is an implementation
  2511. of <literal>Authentication</literal>, and stores the
  2512. <literal>GrantedAuthority</literal>[]s which apply to the anonymous
  2513. principal. There is a corresponding
  2514. <literal>AnonymousAuthenticationProvider</literal>, which is chained
  2515. into the <literal>ProviderManager</literal> so that
  2516. <literal>AnonymousAuthenticationTokens</literal> are accepted.
  2517. Finally, there is an AnonymousProcessingFilter, which is chained after
  2518. the normal authentication mechanisms and automatically add an
  2519. <literal>AnonymousAuthenticationToken</literal> to the
  2520. <literal>SecurityContextHolder</literal> if there is no existing
  2521. <literal>Authentication</literal> held there. The definition of the
  2522. filter and authentication provider appears as follows:</para>
  2523. <para><programlisting>
  2524. &lt;bean id="anonymousProcessingFilter" class="org.acegisecurity.providers.anonymous.AnonymousProcessingFilter"&gt;
  2525. &lt;property name="key"&gt;&lt;value&gt;foobar&lt;/value&gt;&lt;/property&gt;
  2526. &lt;property name="userAttribute"&gt;&lt;value&gt;anonymousUser,ROLE_ANONYMOUS&lt;/value&gt;&lt;/property&gt;
  2527. &lt;/bean&gt;
  2528. &lt;bean id="anonymousAuthenticationProvider" class="org.acegisecurity.providers.anonymous.AnonymousAuthenticationProvider"&gt;
  2529. &lt;property name="key"&gt;&lt;value&gt;foobar&lt;/value&gt;&lt;/property&gt;
  2530. &lt;/bean&gt;
  2531. </programlisting></para>
  2532. <para>The <literal>key</literal> is shared between the filter and
  2533. authentication provider, so that tokens created by the former are
  2534. accepted by the latter. The <literal>userAttribute</literal> is
  2535. expressed in the form of
  2536. <literal>usernameInTheAuthenticationToken,grantedAuthority[,grantedAuthority]</literal>.
  2537. This is the same syntax as used after the equals sign for
  2538. <literal>InMemoryDaoImpl</literal>'s <literal>userMap</literal>
  2539. property.</para>
  2540. <para>As explained earlier, the benefit of anonymous authentication is
  2541. that all URI patterns can have security applied to them. For
  2542. example:</para>
  2543. <para><programlisting>
  2544. &lt;bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor"&gt;
  2545. &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
  2546. &lt;property name="accessDecisionManager"&gt;&lt;ref local="httpRequestAccessDecisionManager"/&gt;&lt;/property&gt;
  2547. &lt;property name="objectDefinitionSource"&gt;
  2548. &lt;value&gt;
  2549. CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
  2550. PATTERN_TYPE_APACHE_ANT
  2551. /index.jsp=ROLE_ANONYMOUS,ROLE_USER
  2552. /hello.htm=ROLE_ANONYMOUS,ROLE_USER
  2553. /logoff.jsp=ROLE_ANONYMOUS,ROLE_USER
  2554. /acegilogin.jsp*=ROLE_ANONYMOUS,ROLE_USER
  2555. /**=ROLE_USER
  2556. &lt;/value&gt;
  2557. &lt;/property&gt;
  2558. &lt;/bean&gt;
  2559. </programlisting>Rounding out the anonymous authentication discussion
  2560. is the <literal>AuthenticationTrustResolver</literal> interface, with
  2561. its corresponding <literal>AuthenticationTrustResolverImpl</literal>
  2562. implementation. This interface provides an
  2563. <literal>isAnonymous(Authentication)</literal> method, which allows
  2564. interested classes to take into account this special type of
  2565. authentication status. The
  2566. <literal>ExceptionTranslationFilter</literal> uses this interface in
  2567. processing <literal>AccessDeniedException</literal>s. If an
  2568. <literal>AccessDeniedException</literal> is thrown, and the
  2569. authentication is of an anonymous type, instead of throwing a 403
  2570. (forbidden) response, the filter will instead commence the
  2571. <literal>AuthenticationEntryPoint</literal> so the principal can
  2572. authenticate properly. This is a necessary distinction, otherwise
  2573. principals would always be deemed "authenticated" and never be given
  2574. an opportunity to login via form, basic, digest or some other normal
  2575. authentication mechanism.</para>
  2576. </sect2>
  2577. <sect2 id="security-ui-remember-me">
  2578. <title>Remember-Me Authentication</title>
  2579. <para>Remember-me authentication refers to web sites being able to
  2580. remember the identity of a principal between sessions. This is
  2581. typically accomplished by sending a cookie to the browser, with the
  2582. cookie being detected during future sessions and causing automated
  2583. login to take place. Acegi Security provides the necessary hooks so
  2584. that such operations can take place, along with providing a concrete
  2585. implementation that uses hashing to preserve the security of
  2586. cookie-based tokens.</para>
  2587. <para>Remember-me authentication is not used with digest or basic
  2588. authentication, given they are often not used with
  2589. <literal>HttpSession</literal>s. Remember-me is used with
  2590. <literal>AuthenticationProcessingFilter</literal>, and is implemented
  2591. via hooks in the <literal>AbstractProcessingFilter</literal>
  2592. superclass. The hooks will invoke a concrete
  2593. <literal>RememberMeServices</literal> at the appropriate times. The
  2594. interface looks like this:</para>
  2595. <para><programlisting>public Authentication autoLogin(HttpServletRequest request, HttpServletResponse response);
  2596. public void loginFail(HttpServletRequest request, HttpServletResponse response);
  2597. public void loginSuccess(HttpServletRequest request, HttpServletResponse response, Authentication successfulAuthentication);</programlisting></para>
  2598. <para>Please refer to JavaDocs for a fuller discussion on what the
  2599. methods do, although note at this stage
  2600. <literal>AbstractProcessingFilter</literal> only calls the
  2601. <literal>loginFail()</literal> and <literal>loginSuccess()</literal>
  2602. methods. The <literal>autoLogin()</literal> method is called by
  2603. <literal>RememberMeProcessingFilter</literal> whenever the
  2604. <literal>SecurityContextHolder</literal> does not contain an
  2605. <literal>Authentication</literal>. This interface therefore provides
  2606. the underlaying remember-me implementation with sufficient
  2607. notification of authentication-related events, and delegates to the
  2608. implementation whenever a candidate web request might contain a cookie
  2609. and wish to be remembered.</para>
  2610. <para>This design allows any number of remember-me implementation
  2611. strategies. In the interests of simplicity and avoiding the need for
  2612. DAO implementations that specify write and create methods, Acegi
  2613. Security's only concrete implementation,
  2614. <literal>TokenBasedRememberMeServices</literal>, uses hashing to
  2615. achieve a useful remember-me strategy. In essence a cookie is sent to
  2616. the browser upon successful interactive authentication, with that
  2617. cookie being composed as follows:</para>
  2618. <para><programlisting>base64(username + ":" + expirationTime + ":" + md5Hex(username + ":" + expirationTime + ":" password + ":" + key))
  2619. username: As identifiable to TokenBasedRememberMeServices.getUserDetailsService()
  2620. password: That matches the relevant UserDetails retrieved from TokenBasedRememberMeServices.getUserDetailsService()
  2621. expirationTime: The date and time when the remember-me token expires, expressed in milliseconds
  2622. key: A private key to prevent modification of the remember-me token
  2623. </programlisting></para>
  2624. <para>As such the remember-me token is valid only for the period
  2625. specified, and provided that the username, password and key does not
  2626. change. Notably, this has a potential security issue issue in that a
  2627. captured remember-me token will be usable from any user agent until
  2628. such time as the token expires. This is the same issue as with digest
  2629. authentication. If a principal is aware a token has been captured,
  2630. they can easily change their password and immediately invalidate all
  2631. remember-me tokens on issue. However, if more significant security is
  2632. needed a rolling token approach should be used (this would require a
  2633. database) or remember-me services should simply not be used.</para>
  2634. <para><literal>TokenBasedRememberMeServices</literal> generates a
  2635. <literal>RememberMeAuthenticationToken</literal>, which is processed
  2636. by <literal>RememberMeAuthenticationProvider</literal>. A
  2637. <literal>key</literal> is shared between this authentication provider
  2638. and the <literal>TokenBasedRememberMeServices</literal>. In addition,
  2639. <literal>TokenBasedRememberMeServices</literal> requires A
  2640. UserDetailsService from which it can retrieve the username and
  2641. password for signature comparison purposes, and generate the
  2642. <literal>RememberMeAuthenticationToken</literal> to contain the
  2643. correct <literal>GrantedAuthority</literal>[]s. Some sort of logout
  2644. command should be provided by the application (typically via a JSP)
  2645. that invalidates the cookie upon user request. See the Contacts Sample
  2646. application's <literal>logout.jsp</literal> for an example.</para>
  2647. <para>The beans required in an application context to enable
  2648. remember-me services are as follows:</para>
  2649. <para><programlisting>
  2650. &lt;bean id="rememberMeProcessingFilter" class="org.acegisecurity.ui.rememberme.RememberMeProcessingFilter"&gt;
  2651. &lt;property name="rememberMeServices"&gt;&lt;ref local="rememberMeServices"/&gt;&lt;/property&gt;
  2652. &lt;/bean&gt;
  2653. &lt;bean id="rememberMeServices" class="org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices"&gt;
  2654. &lt;property name="userDetailsService"&gt;&lt;ref local="jdbcDaoImpl"/&gt;&lt;/property&gt;
  2655. &lt;property name="key"&gt;&lt;value&gt;springRocks&lt;/value&gt;&lt;/property&gt;
  2656. &lt;/bean&gt;
  2657. &lt;bean id="rememberMeAuthenticationProvider" class="org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider"&gt;
  2658. &lt;property name="key"&gt;&lt;value&gt;springRocks&lt;/value&gt;&lt;/property&gt;
  2659. &lt;/bean&gt;
  2660. </programlisting>Don't forget to add your
  2661. <literal>RememberMeServices</literal> implementation to your
  2662. <literal>AuthenticationProcessingFilter.setRememberMeServices()</literal>
  2663. property, include the
  2664. <literal>RememberMeAuthenticationProvider</literal> in your
  2665. <literal>AuthenticationManager.setProviders()</literal> list, and add
  2666. a call to <literal>RememberMeProcessingFilter</literal> into your
  2667. <literal>FilterChainProxy</literal> (typically immediately after your
  2668. <literal>AuthenticationProcessingFilter</literal>).</para>
  2669. </sect2>
  2670. <sect2 id="security-ui-well-known">
  2671. <title>Well-Known Locations</title>
  2672. <para>Prior to release 0.8.0, Acegi Security referred to "well-known
  2673. locations" in discussions about storing the
  2674. <literal>Authentication</literal>. This approach did not explicitly
  2675. separate the function of <literal>HttpSession</literal> storage of
  2676. <literal>SecurityContextHolder</literal> contents from the processing
  2677. of authentication requests received through various protocols. In
  2678. addition, the previous approach did not facilitate storage of
  2679. non-<literal>Authentication</literal> objects between requests, which
  2680. was limiting usefulness of the
  2681. <literal>SecurityContextHolder</literal> system to member of the
  2682. community. For these reasons, the notion of well-known locations was
  2683. abandoned, the <literal>HttpSessionContextIntegrationFilter</literal>
  2684. was established, and the purpose of authentication processing
  2685. mechanisms was explicitly defined and limited to interaction with the
  2686. <literal>SecurityContextHolder</literal> only. There is no need to
  2687. refer to well-known locations any more and we hope this clearer
  2688. separation of responsibilities enhances understanding of the
  2689. design.</para>
  2690. </sect2>
  2691. </sect1>
  2692. <sect1 id="security-container-adapters">
  2693. <title>Container Adapters</title>
  2694. <sect2 id="security-container-adapters-overview">
  2695. <title>Overview</title>
  2696. <para>Very early versions of the Acegi Security System for Spring
  2697. exclusively used Container Adapters for interfacing authentication
  2698. with end users. Whilst this worked well, it required considerable time
  2699. to support multiple container versions and the configuration itself
  2700. was relatively time-consuming for developers. For this reason the HTTP
  2701. Form Authentication and HTTP Basic Authentication approaches were
  2702. developed, and are today recommended for almost all
  2703. applications.</para>
  2704. <para>Container Adapters enable the Acegi Security System for Spring
  2705. to integrate directly with the containers used to host end user
  2706. applications. This integration means that applications can continue to
  2707. leverage the authentication and authorization capabilities built into
  2708. containers (such as <literal>isUserInRole()</literal> and form-based
  2709. or basic authentication), whilst benefiting from the enhanced security
  2710. interception capabilities provided by the Acegi Security System for
  2711. Spring (it should be noted that Acegi Security also offers
  2712. <literal>ContextHolderAwareRequestWrapper</literal> to deliver
  2713. <literal>isUserInRole()</literal> and similar Servlet Specification
  2714. compatibility methods).</para>
  2715. <para>The integration between a container and the Acegi Security
  2716. System for Spring is achieved through an adapter. The adapter provides
  2717. a container-compatible user authentication provider, and needs to
  2718. return a container-compatible user object.</para>
  2719. <para>The adapter is instantiated by the container and is defined in a
  2720. container-specific configuration file. The adapter then loads a Spring
  2721. application context which defines the normal authentication manager
  2722. settings, such as the authentication providers that can be used to
  2723. authenticate the request. The application context is usually named
  2724. <literal>acegisecurity.xml</literal> and is placed in a
  2725. container-specific location.</para>
  2726. <para>The Acegi Security System for Spring currently supports Jetty,
  2727. Catalina (Tomcat), JBoss and Resin. Additional container adapters can
  2728. easily be written.</para>
  2729. </sect2>
  2730. <sect2 id="security-container-adapters-adapter-provider">
  2731. <title>Adapter Authentication Provider</title>
  2732. <para>As is always the case, the container adapter generated
  2733. <literal>Authentication</literal> object still needs to be
  2734. authenticated by an <literal>AuthenticationManager</literal> when
  2735. requested to do so by the
  2736. <literal>AbstractSecurityInterceptor</literal>. The
  2737. <literal>AuthenticationManager</literal> needs to be certain the
  2738. adapter-provided <literal>Authentication</literal> object is valid and
  2739. was actually authenticated by a trusted adapter.</para>
  2740. <para>Adapters create <literal>Authentication</literal> objects which
  2741. are immutable and implement the <literal>AuthByAdapter</literal>
  2742. interface. These objects store the hash of a key that is defined by
  2743. the adapter. This allows the <literal>Authentication</literal> object
  2744. to be validated by the <literal>AuthByAdapterProvider</literal>. This
  2745. authentication provider is defined as follows:</para>
  2746. <para><programlisting>
  2747. &lt;bean id="authByAdapterProvider" class="org.acegisecurity.adapters.AuthByAdapterProvider"&gt;
  2748. &lt;property name="key"&gt;&lt;value&gt;my_password&lt;/value&gt;&lt;/property&gt;
  2749. &lt;/bean&gt;
  2750. </programlisting></para>
  2751. <para>The key must match the key that is defined in the
  2752. container-specific configuration file that starts the adapter. The
  2753. <literal>AuthByAdapterProvider</literal> automatically accepts as
  2754. valid any <literal>AuthByAdapter</literal> implementation that returns
  2755. the expected hash of the key.</para>
  2756. <para>To reiterate, this means the adapter will perform the initial
  2757. authentication using providers such as
  2758. <literal>DaoAuthenticationProvider</literal>, returning an
  2759. <literal>AuthByAdapter</literal> instance that contains a hash code of
  2760. the key. Later, when an application calls a security interceptor
  2761. managed resource, the <literal>AuthByAdapter</literal> instance in the
  2762. <literal>SecurityContext</literal> in the
  2763. <literal>SecurityContextHolder</literal> will be tested by the
  2764. application's <literal>AuthByAdapterProvider</literal>. There is no
  2765. requirement for additional authentication providers such as
  2766. <literal>DaoAuthenticationProvider</literal> within the
  2767. application-specific application context, as the only type of
  2768. <literal>Authentication</literal> instance that will be presented by
  2769. the application is from the container adapter.</para>
  2770. <para>Classloader issues are frequent with containers and the use of
  2771. container adapters illustrates this further. Each container requires a
  2772. very specific configuration. The installation instructions are
  2773. provided below. Once installed, please take the time to try the sample
  2774. application to ensure your container adapter is properly
  2775. configured.</para>
  2776. <para>When using container adapters with the
  2777. <literal>DaoAuthenticationProvider</literal>, ensure you set its
  2778. <literal>forcePrincipalAsString</literal> property to
  2779. <literal>true</literal>.</para>
  2780. </sect2>
  2781. <sect2 id="security-container-adapters-catalina">
  2782. <title>Catalina (Tomcat) Installation</title>
  2783. <para>The following was tested with Jakarta Tomcat 4.1.30 and
  2784. 5.0.19.</para>
  2785. <para><literal>$CATALINA_HOME</literal> refers to the root of your
  2786. Catalina (Tomcat) installation.</para>
  2787. <para>Edit your <literal>$CATALINA_HOME/conf/server.xml</literal> file
  2788. so the <literal>&lt;Engine&gt;</literal> section contains only one
  2789. active <literal>&lt;Realm&gt;</literal> entry. An example realm
  2790. entry:</para>
  2791. <para><programlisting> &lt;Realm className="org.acegisecurity.adapters.catalina.CatalinaAcegiUserRealm"
  2792. appContextLocation="conf/acegisecurity.xml"
  2793. key="my_password" /&gt;</programlisting></para>
  2794. <para>Be sure to remove any other <literal>&lt;Realm&gt;</literal>
  2795. entry from your <literal>&lt;Engine&gt;</literal> section.</para>
  2796. <para>Copy <literal>acegisecurity.xml</literal> into
  2797. <literal>$CATALINA_HOME/conf</literal>.</para>
  2798. <para>Copy <literal>acegi-security-catalina-XX.jar</literal> into
  2799. <literal>$CATALINA_HOME/server/lib</literal>.</para>
  2800. <para>Copy the following files into
  2801. <literal>$CATALINA_HOME/common/lib</literal>:</para>
  2802. <itemizedlist>
  2803. <listitem>
  2804. <para><literal>aopalliance.jar</literal></para>
  2805. </listitem>
  2806. <listitem>
  2807. <para><literal>spring.jar</literal></para>
  2808. </listitem>
  2809. <listitem>
  2810. <para><literal>commons-codec.jar</literal></para>
  2811. </listitem>
  2812. <listitem>
  2813. <para><literal>burlap.jar</literal></para>
  2814. </listitem>
  2815. <listitem>
  2816. <para><literal>hessian.jar</literal></para>
  2817. </listitem>
  2818. </itemizedlist>
  2819. <para>None of the above JAR files (or
  2820. <literal>acegi-security-XX.jar</literal>) should be in your
  2821. application's <literal>WEB-INF/lib</literal>. The realm name indicated
  2822. in your <literal>web.xml</literal> does not matter with
  2823. Catalina.</para>
  2824. <para>We have received reports of problems using this Container
  2825. Adapter with Mac OS X. A work-around is to use a script such as
  2826. follows:</para>
  2827. <para><programlisting>#!/bin/sh
  2828. export CATALINA_HOME="/Library/Tomcat"
  2829. export JAVA_HOME="/Library/Java/Home"
  2830. cd /
  2831. $CATALINA_HOME/bin/startup.sh</programlisting></para>
  2832. </sect2>
  2833. <sect2 id="security-container-adapters-jetty">
  2834. <title>Jetty Installation</title>
  2835. <para>The following was tested with Jetty 4.2.18.</para>
  2836. <para><literal>$JETTY_HOME</literal> refers to the root of your Jetty
  2837. installation.</para>
  2838. <para>Edit your <literal>$JETTY_HOME/etc/jetty.xml</literal> file so
  2839. the <literal>&lt;Configure class&gt;</literal> section has a new
  2840. addRealm call:</para>
  2841. <para><programlisting>
  2842. &lt;Call name="addRealm"&gt;
  2843. &lt;Arg&gt;
  2844. &lt;New class="org.acegisecurity.adapters.jetty.JettyAcegiUserRealm"&gt;
  2845. &lt;Arg&gt;Spring Powered Realm&lt;/Arg&gt;
  2846. &lt;Arg&gt;my_password&lt;/Arg&gt;
  2847. &lt;Arg&gt;etc/acegisecurity.xml&lt;/Arg&gt;
  2848. &lt;/New&gt;
  2849. &lt;/Arg&gt;
  2850. &lt;/Call&gt;
  2851. </programlisting></para>
  2852. <para>Copy <literal>acegisecurity.xml</literal> into
  2853. <literal>$JETTY_HOME/etc</literal>.</para>
  2854. <para>Copy the following files into
  2855. <literal>$JETTY_HOME/ext</literal>:<itemizedlist>
  2856. <listitem>
  2857. <para><literal>aopalliance.jar</literal></para>
  2858. </listitem>
  2859. <listitem>
  2860. <para><literal>commons-logging.jar</literal></para>
  2861. </listitem>
  2862. <listitem>
  2863. <para><literal>spring.jar</literal></para>
  2864. </listitem>
  2865. <listitem>
  2866. <para><literal>acegi-security-jetty-XX.jar</literal></para>
  2867. </listitem>
  2868. <listitem>
  2869. <para><literal>commons-codec.jar</literal></para>
  2870. </listitem>
  2871. <listitem>
  2872. <para><literal>burlap.jar</literal></para>
  2873. </listitem>
  2874. <listitem>
  2875. <para><literal>hessian.jar</literal></para>
  2876. </listitem>
  2877. </itemizedlist></para>
  2878. <para>None of the above JAR files (or
  2879. <literal>acegi-security-XX.jar</literal>) should be in your
  2880. application's <literal>WEB-INF/lib</literal>. The realm name indicated
  2881. in your <literal>web.xml</literal> does matter with Jetty. The
  2882. <literal>web.xml</literal> must express the same
  2883. <literal>&lt;realm-name&gt;</literal> as your
  2884. <literal>jetty.xml</literal> (in the example above, "Spring Powered
  2885. Realm").</para>
  2886. </sect2>
  2887. <sect2 id="security-container-adapters-joss">
  2888. <title>JBoss Installation</title>
  2889. <para>The following was tested with JBoss 3.2.6.</para>
  2890. <para><literal>$JBOSS_HOME</literal> refers to the root of your JBoss
  2891. installation.</para>
  2892. <para>There are two different ways of making spring context available
  2893. to the Jboss integration classes.</para>
  2894. <para>The first approach is by editing your
  2895. <literal>$JBOSS_HOME/server/your_config/conf/login-config.xml</literal>
  2896. file so that it contains a new entry under the
  2897. <literal>&lt;Policy&gt;</literal> section:</para>
  2898. <para><programlisting>
  2899. &lt;application-policy name = "SpringPoweredRealm"&gt;
  2900. &lt;authentication&gt;
  2901. &lt;login-module code = "org.acegisecurity.adapters.jboss.JbossSpringLoginModule"
  2902. flag = "required"&gt;
  2903. &lt;module-option name = "appContextLocation"&gt;acegisecurity.xml&lt;/module-option&gt;
  2904. &lt;module-option name = "key"&gt;my_password&lt;/module-option&gt;
  2905. &lt;/login-module&gt;
  2906. &lt;/authentication&gt;
  2907. &lt;/application-policy&gt;
  2908. </programlisting></para>
  2909. <para>Copy <literal>acegisecurity.xml</literal> into
  2910. <literal>$JBOSS_HOME/server/your_config/conf</literal>.</para>
  2911. <para>In this configuration <literal>acegisecurity.xml</literal>
  2912. contains the spring context definition including all the
  2913. authentication manager beans. You have to bear in mind though, that
  2914. <literal>SecurityContext</literal> is created and destroyed on each
  2915. login request, so the login operation might become costly.
  2916. Alternatively, the second approach is to use Spring singleton
  2917. capabilities through
  2918. <literal>org.springframework.beans.factory.access.SingletonBeanFactoryLocator</literal>.
  2919. The required configuration for this approach is:</para>
  2920. <para><programlisting>
  2921. &lt;application-policy name = "SpringPoweredRealm"&gt;
  2922. &lt;authentication&gt;
  2923. &lt;login-module code = "org.acegisecurity.adapters.jboss.JbossSpringLoginModule"
  2924. flag = "required"&gt;
  2925. &lt;module-option name = "singletonId"&gt;springRealm&lt;/module-option&gt;
  2926. &lt;module-option name = "key"&gt;my_password&lt;/module-option&gt;
  2927. &lt;module-option name = "authenticationManager"&gt;authenticationManager&lt;/module-option&gt;
  2928. &lt;/login-module&gt;
  2929. &lt;/authentication&gt;
  2930. &lt;/application-policy&gt;
  2931. </programlisting></para>
  2932. <para>In the above code fragment,
  2933. <literal>authenticationManager</literal> is a helper property that
  2934. defines the expected name of the
  2935. <literal>AuthenticationManager</literal> in case you have several
  2936. defined in the IoC container. The <literal>singletonId</literal>
  2937. property references a bean defined in a
  2938. <literal>beanRefFactory.xml</literal> file. This file needs to be
  2939. available from anywhere on the JBoss classpath, including
  2940. <literal>$JBOSS_HOME/server/your_config/conf</literal>. The
  2941. <literal>beanRefFactory.xml</literal> contains the following
  2942. declaration:</para>
  2943. <para><programlisting>
  2944. &lt;beans&gt;
  2945. &lt;bean id="springRealm" singleton="true" lazy-init="true" class="org.springframework.context.support.ClassPathXmlApplicationContext"&gt;
  2946. &lt;constructor-arg&gt;
  2947. &lt;list&gt;
  2948. &lt;value&gt;acegisecurity.xml&lt;/value&gt;
  2949. &lt;/list&gt;
  2950. &lt;/constructor-arg&gt;
  2951. &lt;/bean&gt;
  2952. &lt;/beans&gt;
  2953. </programlisting></para>
  2954. <para>Finally, irrespective of the configuration approach you need to
  2955. copy the following files into
  2956. <literal>$JBOSS_HOME/server/your_config/lib</literal>:<itemizedlist>
  2957. <listitem>
  2958. <para><literal>aopalliance.jar</literal></para>
  2959. </listitem>
  2960. <listitem>
  2961. <para><literal>spring.jar</literal></para>
  2962. </listitem>
  2963. <listitem>
  2964. <para><literal>acegi-security-jboss-XX.jar</literal></para>
  2965. </listitem>
  2966. <listitem>
  2967. <para><literal>commons-codec.jar</literal></para>
  2968. </listitem>
  2969. <listitem>
  2970. <para><literal>burlap.jar</literal></para>
  2971. </listitem>
  2972. <listitem>
  2973. <para><literal>hessian.jar</literal></para>
  2974. </listitem>
  2975. </itemizedlist></para>
  2976. <para>None of the above JAR files (or
  2977. <literal>acegi-security-XX.jar</literal>) should be in your
  2978. application's <literal>WEB-INF/lib</literal>. The realm name indicated
  2979. in your <literal>web.xml</literal> does not matter with JBoss.
  2980. However, your web application's
  2981. <literal>WEB-INF/jboss-web.xml</literal> must express the same
  2982. <literal>&lt;security-domain&gt;</literal> as your
  2983. <literal>login-config.xml</literal>. For example, to match the above
  2984. example, your <literal>jboss-web.xml</literal> would look like
  2985. this:</para>
  2986. <para><programlisting>
  2987. &lt;jboss-web&gt;
  2988. &lt;security-domain&gt;java:/jaas/SpringPoweredRealm&lt;/security-domain&gt;
  2989. &lt;/jboss-web&gt;
  2990. </programlisting></para>
  2991. </sect2>
  2992. <sect2 id="security-container-adapters-resin">
  2993. <title>Resin Installation</title>
  2994. <para>The following was tested with Resin 3.0.6.</para>
  2995. <para><literal>$RESIN_HOME</literal> refers to the root of your Resin
  2996. installation.</para>
  2997. <para>Resin provides several ways to support the container adapter. In
  2998. the instructions below we have elected to maximise consistency with
  2999. other container adapter configurations. This will allow Resin users to
  3000. simply deploy the sample application and confirm correct
  3001. configuration. Developers comfortable with Resin are naturally able to
  3002. use its capabilities to package the JARs with the web application
  3003. itself, and/or support single sign-on.</para>
  3004. <para>Copy the following files into
  3005. <literal>$RESIN_HOME/lib</literal>:<itemizedlist>
  3006. <listitem>
  3007. <para><literal>aopalliance.jar</literal></para>
  3008. </listitem>
  3009. <listitem>
  3010. <para><literal>commons-logging.jar</literal></para>
  3011. </listitem>
  3012. <listitem>
  3013. <para><literal>spring.jar</literal></para>
  3014. </listitem>
  3015. <listitem>
  3016. <para><literal>acegi-security-resin-XX.jar</literal></para>
  3017. </listitem>
  3018. <listitem>
  3019. <para><literal>commons-codec.jar</literal></para>
  3020. </listitem>
  3021. <listitem>
  3022. <para><literal>burlap.jar</literal></para>
  3023. </listitem>
  3024. <listitem>
  3025. <para><literal>hessian.jar</literal></para>
  3026. </listitem>
  3027. </itemizedlist></para>
  3028. <para>Unlike the container-wide <literal>acegisecurity.xml</literal>
  3029. files used by other container adapters, each Resin web application
  3030. will contain its own
  3031. <literal>WEB-INF/resin-acegisecurity.xml</literal> file. Each web
  3032. application will also contain a <literal>resin-web.xml</literal> file
  3033. which Resin uses to start the container adapter:</para>
  3034. <para><programlisting>
  3035. &lt;web-app&gt;
  3036. &lt;authenticator&gt;
  3037. &lt;type&gt;org.acegisecurity.adapters.resin.ResinAcegiAuthenticator&lt;/type&gt;
  3038. &lt;init&gt;
  3039. &lt;app-context-location&gt;WEB-INF/resin-acegisecurity.xml&lt;/app-context-location&gt;
  3040. &lt;key&gt;my_password&lt;/key&gt;
  3041. &lt;/init&gt;
  3042. &lt;/authenticator&gt;
  3043. &lt;/web-app&gt;
  3044. </programlisting></para>
  3045. <para>With the basic configuration provided above, none of the JAR
  3046. files listed (or <literal>acegi-security-XX.jar</literal>) should be
  3047. in your application's <literal>WEB-INF/lib</literal>. The realm name
  3048. indicated in your <literal>web.xml</literal> does not matter with
  3049. Resin, as the relevant authentication class is indicated by the
  3050. <literal>&lt;authenticator&gt;</literal> setting.</para>
  3051. </sect2>
  3052. </sect1>
  3053. <sect1 id="security-cas">
  3054. <title>JA-SIG Central Authentication Service (CAS) Single Sign
  3055. On</title>
  3056. <sect2 id="security-cas-overview">
  3057. <title>Overview</title>
  3058. <para>JA-SIG produces an enterprise-wide single sign on system known
  3059. as CAS. Unlike other initiatives, JA-SIG's Central Authentication
  3060. Service is open source, widely used, simple to understand, platform
  3061. independent, and supports proxy capabilities. The Acegi Security
  3062. System for Spring fully supports CAS, and provides an easy migration
  3063. path from single-application deployments of Acegi Security through to
  3064. multiple-application deployments secured by an enterprise-wide CAS
  3065. server.</para>
  3066. <para>You can learn more about CAS at
  3067. <literal>http://www.ja-sig.org/products/cas/</literal>. You will need
  3068. to visit this URL to download the CAS Server files. Whilst the Acegi
  3069. Security System for Spring includes two CAS libraries in the
  3070. "-with-dependencies" ZIP file, you will still need the CAS Java Server
  3071. Pages and <literal>web.xml</literal> to customise and deploy your CAS
  3072. server.</para>
  3073. </sect2>
  3074. <sect2 id="security-cas-how-cas-works">
  3075. <title>How CAS Works</title>
  3076. <para>Whilst the CAS web site above contains two documents that detail
  3077. the architecture of CAS, we present the general overview again here
  3078. within the context of the Acegi Security System for Spring. The
  3079. following refers to both CAS 2.0 (produced by Yale) and CAS 3.0
  3080. (produced by JA-SIG), being the versions of CAS that Acegi Security
  3081. System for Spring supports.</para>
  3082. <para>Somewhere in your enterprise you will need to setup a CAS
  3083. server. The CAS server is simply a standard WAR file, so there isn't
  3084. anything difficult about setting up your server. Inside the WAR file
  3085. you will customise the login and other single sign on pages displayed
  3086. to users.</para>
  3087. <para>If you are deploying CAS 2.0, you will also need to specify in
  3088. the web.xml a <literal>PasswordHandler</literal>. The
  3089. <literal>PasswordHandler</literal> has a simple method that returns a
  3090. boolean as to whether a given username and password is valid. Your
  3091. <literal>PasswordHandler</literal> implementation will need to link
  3092. into some type of backend authentication repository, such as an LDAP
  3093. server or database.</para>
  3094. <para>If you are already running an existing CAS 2.0 server instance,
  3095. you will have already established a
  3096. <literal>PasswordHandler</literal>. If you do not already have a
  3097. <literal>PasswordHandler</literal>, you might prefer to use the Acegi
  3098. Security System for Spring <literal>CasPasswordHandler</literal>
  3099. class. This class delegates through to the standard Acegi Security
  3100. <literal>AuthenticationManager</literal>, enabling you to use a
  3101. security configuration you might already have in place. You do not
  3102. need to use the <literal>CasPasswordHandler</literal> class on your
  3103. CAS server if you do not wish. The Acegi Security System for Spring
  3104. will function as a CAS client successfully irrespective of the
  3105. <literal>PasswordHandler</literal> you've chosen for your CAS
  3106. server.</para>
  3107. <para>If you are deploying CAS 3.0, you will also need to specify an
  3108. <literal>AuthenticationHandler</literal> in the
  3109. deployerConfigContext.xml included with CAS. The
  3110. <literal>AuthenticationHandler</literal> has a simple method that
  3111. returns a boolean as to whether a given set of Credentials is valid.
  3112. Your <literal>AuthenticationHandler</literal> implementation will need
  3113. to link into some type of backend authentication repository, such as
  3114. an LDAP server or database. CAS itself includes numerous
  3115. <literal>AuthenticationHandler</literal>s out of the box to assist
  3116. with this.</para>
  3117. <para>If you are already running an existing CAS 3.0 server instance,
  3118. you will have already established an
  3119. <literal>AuthenticationHandler</literal>. If you do not already have
  3120. an <literal>AuthenticationHandler</literal>, you might prefer to use
  3121. the Acegi Security System for Spring
  3122. <literal>CasAuthenticationHandler</literal> class. This class
  3123. delegates through to the standard Acegi Security
  3124. <literal>AuthenticationManager</literal>, enabling you to use a
  3125. security configuration you might already have in place. You do not
  3126. need to use the <literal>CasAuthenticationHandler</literal> class on
  3127. your CAS server if you do not wish. The Acegi Security System for
  3128. Spring will function as a CAS client successfully irrespective of the
  3129. <literal>AuthenticationHandler</literal> you've chosen for your CAS
  3130. server.</para>
  3131. <para>Apart from the CAS server itself, the other key player is of
  3132. course the secure web applications deployed throughout your
  3133. enterprise. These web applications are known as "services". There are
  3134. two types of services: standard services and proxy services. A proxy
  3135. service is able to request resources from other services on behalf of
  3136. the user. This will be explained more fully later.</para>
  3137. <para>Services can be developed in a large variety of languages, due
  3138. to CAS 2.0's very light XML-based protocol. The JA-SIG CAS home page
  3139. contains a clients archive which demonstrates CAS clients in Java,
  3140. Active Server Pages, Perl, Python and others. Naturally, Java support
  3141. is very strong given the CAS server is written in Java. You do not
  3142. need to use any of CAS' client classes in applications secured by the
  3143. Acegi Security System for Spring. This is handled transparently for
  3144. you.</para>
  3145. <para>The basic interaction between a web browser, CAS server and an
  3146. Acegi Security for System Spring secured service is as follows:</para>
  3147. <orderedlist>
  3148. <listitem>
  3149. <para>The web user is browsing the service's public pages. CAS or
  3150. Acegi Security is not involved.</para>
  3151. </listitem>
  3152. <listitem>
  3153. <para>The user eventually requests a page that is either secure or
  3154. one of the beans it uses is secure. Acegi Security's
  3155. <literal>ExceptionTranslationFilter</literal> will detect the
  3156. <literal>AuthenticationException</literal>.</para>
  3157. </listitem>
  3158. <listitem>
  3159. <para>Because the user's <literal>Authentication</literal> object
  3160. (or lack thereof) caused an
  3161. <literal>AuthenticationException</literal>, the
  3162. <literal>ExceptionTranslationFilter</literal> will call the
  3163. configured <literal>AuthenticationEntryPoint</literal>. If using
  3164. CAS, this will be the
  3165. <literal>CasProcessingFilterEntryPoint</literal> class.</para>
  3166. </listitem>
  3167. <listitem>
  3168. <para>The <literal>CasProcessingFilterEntry</literal> point will
  3169. redirect the user's browser to the CAS server. It will also
  3170. indicate a <literal>service</literal> parameter, which is the
  3171. callback URL for the Acegi Security service. For example, the URL
  3172. to which the browser is redirected might be
  3173. <literal>https://my.company.com/cas/login?service=https%3A%2F%2Fserver3.company.com%2Fwebapp%2Fj_acegi_cas_security_check</literal>.</para>
  3174. </listitem>
  3175. <listitem>
  3176. <para>After the user's browser redirects to CAS, they will be
  3177. prompted for their username and password. If the user presents a
  3178. session cookie which indicates they've previously logged on, they
  3179. will not be prompted to login again (there is an exception to this
  3180. procedure, which we'll cover later). CAS will use the
  3181. <literal>PasswordHandler</literal> (or
  3182. <literal>AuthenticationHandler</literal> if using CAS 3.0)
  3183. discussed above to decide whether the username and password is
  3184. valid.</para>
  3185. </listitem>
  3186. <listitem>
  3187. <para>Upon successful login, CAS will redirect the user's browser
  3188. back to the original service. It will also include a
  3189. <literal>ticket</literal> parameter, which is an opaque string
  3190. representing the "service ticket". Continuing our earlier example,
  3191. the URL the browser is redirected to might be
  3192. <literal>https://server3.company.com/webapp/j_acegi_cas_security_check?ticket=ST-0-ER94xMJmn6pha35CQRoZ</literal>.</para>
  3193. </listitem>
  3194. <listitem>
  3195. <para>Back in the service web application, the
  3196. <literal>CasProcessingFilter</literal> is always listening for
  3197. requests to <literal>/j_acegi_cas_security_check</literal> (this
  3198. is configurable, but we'll use the defaults in this introduction).
  3199. The processing filter will construct a
  3200. <literal>UsernamePasswordAuthenticationToken</literal>
  3201. representing the service ticket. The principal will be equal to
  3202. <literal>CasProcessingFilter.CAS_STATEFUL_IDENTIFIER</literal>,
  3203. whilst the credentials will be the service ticket opaque value.
  3204. This authentication request will then be handed to the configured
  3205. <literal>AuthenticationManager</literal>.</para>
  3206. </listitem>
  3207. <listitem>
  3208. <para>The <literal>AuthenticationManager</literal> implementation
  3209. will be the <literal>ProviderManager</literal>, which is in turn
  3210. configured with the <literal>CasAuthenticationProvider</literal>.
  3211. The <literal>CasAuthenticationProvider</literal> only responds to
  3212. <literal>UsernamePasswordAuthenticationToken</literal>s containing
  3213. the CAS-specific principal (such as
  3214. <literal>CasProcessingFilter.CAS_STATEFUL_IDENTIFIER</literal>)
  3215. and <literal>CasAuthenticationToken</literal>s (discussed
  3216. later).</para>
  3217. </listitem>
  3218. <listitem>
  3219. <para><literal>CasAuthenticationProvider</literal> will validate
  3220. the service ticket using a <literal>TicketValidator</literal>
  3221. implementation. Acegi Security includes one implementation, the
  3222. <literal>CasProxyTicketValidator</literal>. This implementation a
  3223. ticket validation class included in the CAS client library. The
  3224. <literal>CasProxyTicketValidator</literal> makes a HTTPS request
  3225. to the CAS server in order to validate the service ticket. The
  3226. <literal>CasProxyTicketValidator</literal> may also include a
  3227. proxy callback URL, which is included in this example:
  3228. <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>
  3229. </listitem>
  3230. <listitem>
  3231. <para>Back on the CAS server, the proxy validation request will be
  3232. received. If the presented service ticket matches the service URL
  3233. the ticket was issued to, CAS will provide an affirmative response
  3234. in XML indicating the username. If any proxy was involved in the
  3235. authentication (discussed below), the list of proxies is also
  3236. included in the XML response.</para>
  3237. </listitem>
  3238. <listitem>
  3239. <para>[OPTIONAL] If the request to the CAS validation service
  3240. included the proxy callback URL (in the <literal>pgtUrl</literal>
  3241. parameter), CAS will include a <literal>pgtIou</literal> string in
  3242. the XML response. This <literal>pgtIou</literal> represents a
  3243. proxy-granting ticket IOU. The CAS server will then create its own
  3244. HTTPS connection back to the <literal>pgtUrl</literal>. This is to
  3245. mutually authenticate the CAS server and the claimed service URL.
  3246. The HTTPS connection will be used to send a proxy granting ticket
  3247. to the original web application. For example,
  3248. <literal>https://server3.company.com/webapp/casProxy/receptor?pgtIou=PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt&amp;pgtId=PGT-1-si9YkkHLrtACBo64rmsi3v2nf7cpCResXg5MpESZFArbaZiOKH</literal>.
  3249. We suggest you use CAS' <literal>ProxyTicketReceptor</literal>
  3250. servlet to receive these proxy-granting tickets, if they are
  3251. required.</para>
  3252. </listitem>
  3253. <listitem>
  3254. <para>The <literal>CasProxyTicketValidator</literal> will parse
  3255. the XML received from the CAS server. It will return to the
  3256. <literal>CasAuthenticationProvider</literal> a
  3257. <literal>TicketResponse</literal>, which includes the username
  3258. (mandatory), proxy list (if any were involved), and proxy-granting
  3259. ticket IOU (if the proxy callback was requested).</para>
  3260. </listitem>
  3261. <listitem>
  3262. <para>Next <literal>CasAuthenticationProvider</literal> will call
  3263. a configured <literal>CasProxyDecider</literal>. The
  3264. <literal>CasProxyDecider</literal> indicates whether the proxy
  3265. list in the <literal>TicketResponse</literal> is acceptable to the
  3266. service. Several implementations are provided with the Acegi
  3267. Security System: <literal>RejectProxyTickets</literal>,
  3268. <literal>AcceptAnyCasProxy</literal> and
  3269. <literal>NamedCasProxyDecider</literal>. These names are largely
  3270. self-explanatory, except <literal>NamedCasProxyDecider</literal>
  3271. which allows a <literal>List</literal> of trusted proxies to be
  3272. provided.</para>
  3273. </listitem>
  3274. <listitem>
  3275. <para><literal>CasAuthenticationProvider</literal> will next
  3276. request a <literal>CasAuthoritiesPopulator</literal> to advise the
  3277. <literal>GrantedAuthority</literal> objects that apply to the user
  3278. contained in the <literal>TicketResponse</literal>. Acegi Security
  3279. includes a <literal>DaoCasAuthoritiesPopulator</literal> which
  3280. simply uses the <literal>UserDetailsService</literal>
  3281. infrastructure to find the <literal>UserDetails</literal> and
  3282. their associated <literal>GrantedAuthority</literal>s. Note that
  3283. the password and enabled/disabled status of
  3284. <literal>UserDetails</literal> returned by the
  3285. <literal>UserDetailsService</literal> are ignored, as the CAS
  3286. server is responsible for authentication decisions.
  3287. <literal>DaoCasAuthoritiesPopulator</literal> is only concerned
  3288. with retrieving the <literal>GrantedAuthority</literal>s.</para>
  3289. </listitem>
  3290. <listitem>
  3291. <para>If there were no problems,
  3292. <literal>CasAuthenticationProvider</literal> constructs a
  3293. <literal>CasAuthenticationToken</literal> including the details
  3294. contained in the <literal>TicketResponse</literal> and the
  3295. <literal>GrantedAuthority</literal>s. The
  3296. <literal>CasAuthenticationToken</literal> contains the hash of a
  3297. key, so that the <literal>CasAuthenticationProvider</literal>
  3298. knows it created it.</para>
  3299. </listitem>
  3300. <listitem>
  3301. <para>Control then returns to
  3302. <literal>CasProcessingFilter</literal>, which places the created
  3303. <literal>CasAuthenticationToken</literal> into the
  3304. <literal>HttpSession</literal> attribute named
  3305. <literal>HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY</literal>.</para>
  3306. </listitem>
  3307. <listitem>
  3308. <para>The user's browser is redirected to the original page that
  3309. caused the <literal>AuthenticationException</literal>.</para>
  3310. </listitem>
  3311. <listitem>
  3312. <para>As the <literal>Authentication</literal> object is now in
  3313. the well-known location, it is handled like any other
  3314. authentication approach. Usually the
  3315. <literal>HttpSessionIntegrationFilter</literal> will be used to
  3316. associate the <literal>Authentication</literal> object with the
  3317. <literal>SecurityContextHolder</literal> for the duration of each
  3318. request.</para>
  3319. </listitem>
  3320. </orderedlist>
  3321. <para>It's good that you're still here! It might sound involved, but
  3322. you can relax as the Acegi Security System for Spring classes hide
  3323. much of the complexity. Let's now look at how this is
  3324. configured.</para>
  3325. </sect2>
  3326. <sect2 id="security-cas-2-install-server">
  3327. <title>CAS 2.0 Server Installation (Optional)</title>
  3328. <para>As mentioned above, the Acegi Security System for Spring
  3329. includes a <literal>PasswordHandler</literal> that bridges your
  3330. existing <literal>AuthenticationManager</literal> into CAS 2.0. You do
  3331. not need to use this <literal>PasswordHandler</literal> to use Acegi
  3332. Security on the client side (any CAS
  3333. <literal>PasswordHandler</literal> will do).</para>
  3334. <para>To install, you will need to download and extract the CAS server
  3335. archive. We used version 2.0.12. There will be a
  3336. <literal>/web</literal> directory in the root of the deployment. Copy
  3337. an <literal>applicationContext.xml</literal> containing your
  3338. <literal>AuthenticationManager</literal> as well as the
  3339. <literal>CasPasswordHandler</literal> into the
  3340. <literal>/web/WEB-INF</literal> directory. A sample
  3341. <literal>applicationContext.xml</literal> is included below:</para>
  3342. <programlisting>
  3343. &lt;bean id="inMemoryDaoImpl" class="org.acegisecurity.userdetails.memory.InMemoryDaoImpl"&gt;
  3344. &lt;property name="userMap"&gt;
  3345. &lt;value&gt;
  3346. marissa=koala,ROLES_IGNORED_BY_CAS
  3347. dianne=emu,ROLES_IGNORED_BY_CAS
  3348. scott=wombat,ROLES_IGNORED_BY_CAS
  3349. peter=opal,disabled,ROLES_IGNORED_BY_CAS
  3350. &lt;/value&gt;
  3351. &lt;/property&gt;
  3352. &lt;/bean&gt;
  3353. &lt;bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider"&gt;
  3354. &lt;property name="userDetailsService"&gt;&lt;ref bean="inMemoryDaoImpl"/&gt;&lt;/property&gt;
  3355. &lt;/bean&gt;
  3356. &lt;bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager"&gt;
  3357. &lt;property name="providers"&gt;
  3358. &lt;list&gt;
  3359. &lt;ref bean="daoAuthenticationProvider"/&gt;
  3360. &lt;/list&gt;
  3361. &lt;/property&gt;
  3362. &lt;/bean&gt;
  3363. &lt;bean id="casPasswordHandler" class="org.acegisecurity.adapters.cas.CasPasswordHandler"&gt;
  3364. &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
  3365. &lt;/bean&gt;
  3366. </programlisting>
  3367. <para>Note the granted authorities are ignored by CAS because it has
  3368. no way of communicating the granted authorities to calling
  3369. applications. CAS is only concerned with username and passwords (and
  3370. the enabled/disabled status).</para>
  3371. <para>Next you will need to edit the existing
  3372. <literal>/web/WEB-INF/web.xml</literal> file. Add (or edit in the case
  3373. of the <literal>authHandler</literal> property) the following
  3374. lines:</para>
  3375. <para><programlisting>
  3376. &lt;context-param&gt;
  3377. &lt;param-name&gt;edu.yale.its.tp.cas.authHandler&lt;/param-name&gt;
  3378. &lt;param-value&gt;org.acegisecurity.adapters.cas.CasPasswordHandlerProxy&lt;/param-value&gt;
  3379. &lt;/context-param&gt;
  3380. &lt;context-param&gt;
  3381. &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
  3382. &lt;param-value&gt;/WEB-INF/applicationContext.xml&lt;/param-value&gt;
  3383. &lt;/context-param&gt;
  3384. &lt;listener&gt;
  3385. &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;
  3386. &lt;/listener&gt;
  3387. </programlisting></para>
  3388. <para>Copy the <literal>spring.jar</literal> and
  3389. <literal>acegi-security.jar</literal> files into
  3390. <literal>/web/WEB-INF/lib</literal>. Now use the <literal>ant
  3391. dist</literal> task in the <literal>build.xml</literal> in the root of
  3392. the directory structure. This will create
  3393. <literal>/lib/cas.war</literal>, which is ready for deployment to your
  3394. servlet container.</para>
  3395. <para>Note CAS heavily relies on HTTPS. You can't even test the system
  3396. without a HTTPS certificate. Whilst you should refer to your web
  3397. container's documentation on setting up HTTPS, if you need some
  3398. additional help or a test certificate you might like to check the
  3399. <literal>samples/contacts/etc/ssl</literal> directory.</para>
  3400. </sect2>
  3401. <sect2 id="security-cas-3-install-server">
  3402. <title>CAS 3.0 Server Installation (Optional)</title>
  3403. <para>As mentioned above, the Acegi Security System for Spring
  3404. includes an <literal>AuthenticationHandler</literal> that bridges your
  3405. existing <literal>AuthenticationManager</literal> into CAS 3.0. You do
  3406. not need to use this <literal>AuthenticationHandler</literal> to use
  3407. Acegi Security on the client side (any CAS
  3408. <literal>AuthenticationHandler</literal> will do).</para>
  3409. <para>To install, you will need to download and extract the CAS server
  3410. archive. We used version 3.0.4. There will be a
  3411. <literal>/webapp</literal> directory in the root of the deployment.
  3412. Edit the an <literal>deployerConfigContext.xml</literal> so that it
  3413. contains your <literal>AuthenticationManager</literal> as well as the
  3414. <literal>CasAuthenticationHandler</literal>. A sample
  3415. <literal>applicationContext.xml</literal> is included below:</para>
  3416. <programlisting>
  3417. &lt;?xml version="1.0" encoding="UTF-8"?&gt;
  3418. &lt;!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"&gt;
  3419. &lt;beans&gt;
  3420. &lt;bean
  3421. id="authenticationManager"
  3422. class="org.jasig.cas.authentication.AuthenticationManagerImpl"&gt;
  3423. &lt;property name="credentialsToPrincipalResolvers"&gt;
  3424. &lt;list&gt;
  3425. &lt;bean class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver" /&gt;
  3426. &lt;bean class="org.jasig.cas.authentication.principal.HttpBasedServiceCredentialsToPrincipalResolver" /&gt;
  3427. &lt;/list&gt;
  3428. &lt;/property&gt;
  3429. &lt;property name="authenticationHandlers"&gt;
  3430. &lt;list&gt;
  3431. &lt;bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler" /&gt;
  3432. &lt;bean class="org.acegisecurity.adapters.cas3.CasAuthenticationHandler"&gt;
  3433. &lt;property name="authenticationManager" ref="acegiAuthenticationManager" /&gt;
  3434. &lt;/bean&gt;
  3435. &lt;/list&gt;
  3436. &lt;/property&gt;
  3437. &lt;/bean&gt;
  3438. &lt;bean id="inMemoryDaoImpl" class="org.acegisecurity.userdetails.memory.InMemoryDaoImpl"&gt;
  3439. &lt;property name="userMap"&gt;
  3440. &lt;value&gt;
  3441. marissa=koala,ROLES_IGNORED_BY_CAS
  3442. dianne=emu,ROLES_IGNORED_BY_CAS
  3443. scott=wombat,ROLES_IGNORED_BY_CAS
  3444. peter=opal,disabled,ROLES_IGNORED_BY_CAS
  3445. &lt;/value&gt;
  3446. &lt;/property&gt;
  3447. &lt;/bean&gt;
  3448. &lt;bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider"&gt;
  3449. &lt;property name="userDetailsService"&gt;&lt;ref bean="inMemoryDaoImpl"/&gt;&lt;/property&gt;
  3450. &lt;/bean&gt;
  3451. &lt;bean id="acegiAuthenticationManager" class="org.acegisecurity.providers.ProviderManager"&gt;
  3452. &lt;property name="providers"&gt;
  3453. &lt;list&gt;
  3454. &lt;ref bean="daoAuthenticationProvider"/&gt;
  3455. &lt;/list&gt;
  3456. &lt;/property&gt;
  3457. &lt;/bean&gt;
  3458. &lt;/beans&gt;
  3459. </programlisting>
  3460. <para>Note the granted authorities are ignored by CAS because it has
  3461. no way of communicating the granted authorities to calling
  3462. applications. CAS is only concerned with username and passwords (and
  3463. the enabled/disabled status).</para>
  3464. <para>Copy the <literal>acegi-security.jar</literal> file into
  3465. <literal>/localPlugins/lib</literal>. Now use the <literal>ant
  3466. war</literal> task in the <literal>build.xml</literal> in the
  3467. /localPlugins directory. This will create
  3468. <literal>/localPlugins/target/cas.war</literal>, which is ready for
  3469. deployment to your servlet container.</para>
  3470. <para>Note CAS heavily relies on HTTPS. You can't even test the system
  3471. without a HTTPS certificate. Whilst you should refer to your web
  3472. container's documentation on setting up HTTPS, if you need some
  3473. additional help or a test certificate you might like to check the CAS
  3474. documentation on setting up SSL:
  3475. <literal>http://www.ja-sig.org/products/cas/server/ssl/index.html</literal></para>
  3476. </sect2>
  3477. <sect2 id="security-cas-install-client">
  3478. <title>CAS Acegi Security System Client Installation</title>
  3479. <para>The web application side of CAS is made easy due to the Acegi
  3480. Security System for Spring. It is assumed you already know the basics
  3481. of using the Acegi Security System for Spring, so these are not
  3482. covered again below. Only the CAS-specific beans are mentioned.</para>
  3483. <para>You will need to add a <literal>ServiceProperties</literal> bean
  3484. to your application context. This represents your service:</para>
  3485. <para><programlisting>
  3486. &lt;bean id="serviceProperties" class="org.acegisecurity.ui.cas.ServiceProperties"&gt;
  3487. &lt;property name="service"&gt;&lt;value&gt;https://localhost:8443/contacts-cas/j_acegi_cas_security_check&lt;/value&gt;&lt;/property&gt;
  3488. &lt;property name="sendRenew"&gt;&lt;value&gt;false&lt;/value&gt;&lt;/property&gt;
  3489. &lt;/bean&gt;
  3490. </programlisting></para>
  3491. <para>The <literal>service</literal> must equal a URL that will be
  3492. monitored by the <literal>CasProcessingFilter</literal>. The
  3493. <literal>sendRenew</literal> defaults to false, but should be set to
  3494. true if your application is particularly sensitive. What this
  3495. parameter does is tell the CAS login service that a single sign on
  3496. login is unacceptable. Instead, the user will need to re-enter their
  3497. username and password in order to gain access to the service.</para>
  3498. <para>The following beans should be configured to commence the CAS
  3499. authentication process:</para>
  3500. <para><programlisting>
  3501. &lt;bean id="casProcessingFilter" class="org.acegisecurity.ui.cas.CasProcessingFilter"&gt;
  3502. &lt;property name="authenticationManager"&gt;&lt;ref bean="authenticationManager"/&gt;&lt;/property&gt;
  3503. &lt;property name="authenticationFailureUrl"&gt;&lt;value&gt;/casfailed.jsp&lt;/value&gt;&lt;/property&gt;
  3504. &lt;property name="defaultTargetUrl"&gt;&lt;value&gt;/&lt;/value&gt;&lt;/property&gt;
  3505. &lt;property name="filterProcessesUrl"&gt;&lt;value&gt;/j_acegi_cas_security_check&lt;/value&gt;&lt;/property&gt;
  3506. &lt;/bean&gt;
  3507. &lt;bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter"&gt;
  3508. &lt;property name="authenticationEntryPoint"&gt;&lt;ref local="casProcessingFilterEntryPoint"/&gt;&lt;/property&gt;
  3509. &lt;/bean&gt;
  3510. &lt;bean id="casProcessingFilterEntryPoint" class="org.acegisecurity.ui.cas.CasProcessingFilterEntryPoint"&gt;
  3511. &lt;property name="loginUrl"&gt;&lt;value&gt;https://localhost:8443/cas/login&lt;/value&gt;&lt;/property&gt;
  3512. &lt;property name="serviceProperties"&gt;&lt;ref bean="serviceProperties"/&gt;&lt;/property&gt;
  3513. &lt;/bean&gt;
  3514. </programlisting></para>
  3515. <para>You will also need to add the
  3516. <literal>CasProcessingFilter</literal> to web.xml:</para>
  3517. <para><programlisting>
  3518. &lt;filter&gt;
  3519. &lt;filter-name&gt;Acegi CAS Processing Filter&lt;/filter-name&gt;
  3520. &lt;filter-class&gt;org.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
  3521. &lt;init-param&gt;
  3522. &lt;param-name&gt;targetClass&lt;/param-name&gt;
  3523. &lt;param-value&gt;org.acegisecurity.ui.cas.CasProcessingFilter&lt;/param-value&gt;
  3524. &lt;/init-param&gt;
  3525. &lt;/filter&gt;
  3526. &lt;filter-mapping&gt;
  3527. &lt;filter-name&gt;Acegi CAS Processing Filter&lt;/filter-name&gt;
  3528. &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
  3529. &lt;/filter-mapping&gt;
  3530. </programlisting></para>
  3531. <para>The <literal>CasProcessingFilter</literal> has very similar
  3532. properties to the <literal>AuthenticationProcessingFilter</literal>
  3533. (used for form-based logins). Each property is
  3534. self-explanatory.</para>
  3535. <para>For CAS to operate, the
  3536. <literal>ExceptionTranslationFilter</literal> must have its
  3537. <literal>authenticationEntryPoint</literal> property set to the
  3538. <literal>CasProcessingFilterEntryPoint</literal> bean.</para>
  3539. <para>The <literal>CasProcessingFilterEntryPoint</literal> must refer
  3540. to the <literal>ServiceProperties</literal> bean (discussed above),
  3541. which provides the URL to the enterprise's CAS login server. This is
  3542. where the user's browser will be redirected.</para>
  3543. <para>Next you need to add an <literal>AuthenticationManager</literal>
  3544. that uses <literal>CasAuthenticationProvider</literal> and its
  3545. collaborators:</para>
  3546. <para><programlisting>
  3547. &lt;bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager"&gt;
  3548. &lt;property name="providers"&gt;
  3549. &lt;list&gt;
  3550. &lt;ref bean="casAuthenticationProvider"/&gt;
  3551. &lt;/list&gt;
  3552. &lt;/property&gt;
  3553. &lt;/bean&gt;
  3554. &lt;bean id="casAuthenticationProvider" class="org.acegisecurity.providers.cas.CasAuthenticationProvider"&gt;
  3555. &lt;property name="casAuthoritiesPopulator"&gt;&lt;ref bean="casAuthoritiesPopulator"/&gt;&lt;/property&gt;
  3556. &lt;property name="casProxyDecider"&gt;&lt;ref bean="casProxyDecider"/&gt;&lt;/property&gt;
  3557. &lt;property name="ticketValidator"&gt;&lt;ref bean="casProxyTicketValidator"/&gt;&lt;/property&gt;
  3558. &lt;property name="statelessTicketCache"&gt;&lt;ref bean="statelessTicketCache"/&gt;&lt;/property&gt;
  3559. &lt;property name="key"&gt;&lt;value&gt;my_password_for_this_auth_provider_only&lt;/value&gt;&lt;/property&gt;
  3560. &lt;/bean&gt;
  3561. &lt;bean id="casProxyTicketValidator" class="org.acegisecurity.providers.cas.ticketvalidator.CasProxyTicketValidator"&gt;
  3562. &lt;property name="casValidate"&gt;&lt;value&gt;https://localhost:8443/cas/proxyValidate&lt;/value&gt;&lt;/property&gt;
  3563. &lt;property name="proxyCallbackUrl"&gt;&lt;value&gt;https://localhost:8443/contacts-cas/casProxy/receptor&lt;/value&gt;&lt;/property&gt;
  3564. &lt;property name="serviceProperties"&gt;&lt;ref bean="serviceProperties"/&gt;&lt;/property&gt;
  3565. &lt;!-- &lt;property name="trustStore"&gt;&lt;value&gt;/some/path/to/your/lib/security/cacerts&lt;/value&gt;&lt;/property&gt; --&gt;
  3566. &lt;/bean&gt;
  3567. &lt;bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"&gt;
  3568. &lt;property name="configLocation"&gt;
  3569. &lt;value&gt;classpath:/ehcache-failsafe.xml&lt;/value&gt;
  3570. &lt;/property&gt;
  3571. &lt;/bean&gt;
  3572. &lt;bean id="ticketCacheBackend" class="org.springframework.cache.ehcache.EhCacheFactoryBean"&gt;
  3573. &lt;property name="cacheManager"&gt;
  3574. &lt;ref local="cacheManager"/&gt;
  3575. &lt;/property&gt;
  3576. &lt;property name="cacheName"&gt;
  3577. &lt;value&gt;ticketCache&lt;/value&gt;
  3578. &lt;/property&gt;
  3579. &lt;/bean&gt;
  3580. &lt;bean id="statelessTicketCache" class="org.acegisecurity.providers.cas.cache.EhCacheBasedTicketCache"&gt;
  3581. &lt;property name="cache"&gt;&lt;ref local="ticketCacheBackend"/&gt;&lt;/property&gt;
  3582. &lt;/bean&gt;
  3583. &lt;bean id="casAuthoritiesPopulator" class="org.acegisecurity.providers.cas.populator.DaoCasAuthoritiesPopulator"&gt;
  3584. &lt;property name="userDetailsService"&gt;&lt;ref bean="inMemoryDaoImpl"/&gt;&lt;/property&gt;
  3585. &lt;/bean&gt;
  3586. &lt;bean id="casProxyDecider" class="org.acegisecurity.providers.cas.proxy.RejectProxyTickets"/&gt;
  3587. </programlisting></para>
  3588. <para>The beans are all reasonable self-explanatory if you refer back
  3589. to the "How CAS Works" section. Careful readers might notice one
  3590. surprise: the <literal>statelessTicketCache</literal> property of the
  3591. <literal>CasAuthenticationProvider</literal>. This is discussed in
  3592. detail in the "Advanced CAS Usage" section.</para>
  3593. <para>Note the <literal>CasProxyTicketValidator</literal> has a
  3594. remarked out <literal>trustStore</literal> property. This property
  3595. might be helpful if you experience HTTPS certificate issues. Also note
  3596. the <literal>proxyCallbackUrl</literal> is set so the service can
  3597. receive a proxy-granting ticket. As mentioned above, this is optional
  3598. and unnecessary if you do not require proxy-granting tickets. If you
  3599. do use this feature, you will need to configure a suitable servlet to
  3600. receive the proxy-granting tickets. We suggest you use CAS'
  3601. <literal>ProxyTicketReceptor</literal> by adding the following to your
  3602. web application's <literal>web.xml</literal>:</para>
  3603. <para><programlisting>
  3604. &lt;servlet&gt;
  3605. &lt;servlet-name&gt;casproxy&lt;/servlet-name&gt;
  3606. &lt;servlet-class&gt;edu.yale.its.tp.cas.proxy.ProxyTicketReceptor&lt;/servlet-class&gt;
  3607. &lt;/servlet&gt;
  3608. &lt;servlet-mapping&gt;
  3609. &lt;servlet-name&gt;casproxy&lt;/servlet-name&gt;
  3610. &lt;url-pattern&gt;/casProxy/*&lt;/url-pattern&gt;
  3611. &lt;/servlet-mapping&gt;
  3612. </programlisting></para>
  3613. <para>This completes the configuration of CAS. If you haven't made any
  3614. mistakes, your web application should happily work within the
  3615. framework of CAS single sign on. No other parts of the Acegi Security
  3616. System for Spring need to be concerned about the fact CAS handled
  3617. authentication.</para>
  3618. <para>There is also a <literal>contacts-cas.war</literal> file in the
  3619. sample applications directory. This sample application uses the above
  3620. settings and can be deployed to see CAS in operation.</para>
  3621. </sect2>
  3622. <sect2 id="security-cas-advanced-usage">
  3623. <title>Advanced CAS Usage</title>
  3624. <para>The <literal>CasAuthenticationProvider</literal> distinguishes
  3625. between stateful and stateless clients. A stateful client is
  3626. considered any that originates via the
  3627. <literal>CasProcessingFilter</literal>. A stateless client is any that
  3628. presents an authentication request via the
  3629. <literal>UsernamePasswordAuthenticationToken</literal> with a
  3630. principal equal to
  3631. <literal>CasProcessingFilter.CAS_STATELESS_IDENTIFIER</literal>.</para>
  3632. <para>Stateless clients are likely to be via remoting protocols such
  3633. as Hessian and Burlap. The <literal>BasicProcessingFilter</literal> is
  3634. still used in this case, but the remoting protocol client is expected
  3635. to present a username equal to the static string above, and a password
  3636. equal to a CAS service ticket. Clients should acquire a CAS service
  3637. ticket directly from the CAS server.</para>
  3638. <para>Because remoting protocols have no way of presenting themselves
  3639. within the context of a <literal>HttpSession</literal>, it isn't
  3640. possible to rely on the <literal>HttpSession</literal>'s
  3641. <literal>HttpSessionIntegrationFilter.ACEGI_SECURITY_AUTHENTICATION_KEY</literal>
  3642. attribute to locate the <literal>CasAuthenticationToken</literal>.
  3643. Furthermore, because the CAS server invalidates a service ticket after
  3644. it has been validated by the <literal>TicketValidator</literal>,
  3645. presenting the same service ticket on subsequent requests will not
  3646. work. It is similarly very difficult to obtain a proxy-granting ticket
  3647. for a remoting protocol client, as they are often deployed on client
  3648. machines which rarely have HTTPS URLs that would be accessible to the
  3649. CAS server.</para>
  3650. <para>One obvious option is to not use CAS at all for remoting
  3651. protocol clients. However, this would eliminate many of the desirable
  3652. features of CAS.</para>
  3653. <para>As a middle-ground, the
  3654. <literal>CasAuthenticationProvider</literal> uses a
  3655. <literal>StatelessTicketCache</literal>. This is used solely for
  3656. requests with a principal equal to
  3657. <literal>CasProcessingFilter.CAS_STATELESS_IDENTIFIER</literal>. What
  3658. happens is the <literal>CasAuthenticationProvider</literal> will store
  3659. the resulting <literal>CasAuthenticationToken</literal> in the
  3660. <literal>StatelessTicketCache</literal>, keyed on the service ticket.
  3661. Accordingly, remoting protocol clients can present the same service
  3662. ticket and the <literal>CasAuthenticationProvider</literal> will not
  3663. need to contact the CAS server for validation (aside from the first
  3664. request).</para>
  3665. <para>The other aspect of advanced CAS usage involves creating proxy
  3666. tickets from the proxy-granting ticket. As indicated above, we
  3667. recommend you use CAS' <literal>ProxyTicketReceptor</literal> to
  3668. receive these tickets. The <literal>ProxyTicketReceptor</literal>
  3669. provides a static method that enables you to obtain a proxy ticket by
  3670. presenting the proxy-granting IOU ticket. You can obtain the
  3671. proxy-granting IOU ticket by calling
  3672. <literal>CasAuthenticationToken.getProxyGrantingTicketIou()</literal>.</para>
  3673. <para>It is hoped you find CAS integration easy and useful with the
  3674. Acegi Security System for Spring classes. Welcome to enterprise-wide
  3675. single sign on!</para>
  3676. </sect2>
  3677. </sect1>
  3678. <sect1 id="security-x509">
  3679. <title>X509 Authentication</title>
  3680. <sect2 id="security-x509-overview">
  3681. <title>Overview</title>
  3682. <para>The most common use of X509 certificate authentication is in
  3683. verifying the identity of a server when using SSL, most commonly when
  3684. using HTTPS from a browser. The browser will automatically check that
  3685. the certificate presented by a server has been issued (ie digitally
  3686. signed) by one of a list of trusted certificate authorities which it
  3687. maintains.</para>
  3688. <para>You can also use SSL with <quote>mutual authentication</quote>;
  3689. the server will then request a valid certificate from the client as
  3690. part of the SSL handshake. The server will authenticate the client by
  3691. checking that it's certificate is signed by an acceptable authority.
  3692. If a valid certificate has been provided, it can be obtained through
  3693. the servlet API in an application. The Acegi Security X509 module
  3694. extracts the certificate using a filter and passes it to the
  3695. configured X509 authentication provider to allow any additional
  3696. application-specific checks to be applied. It also maps the
  3697. certificate to an application user and loads that user's set of
  3698. granted authorities for use with the standard Acegi Security
  3699. infrastructure.</para>
  3700. <para>You should be familiar with using certificates and setting up
  3701. client authentication for your servlet container before attempting to
  3702. use it with Acegi Security. Most of the work is in creating and
  3703. installing suitable certificates and keys. For example, if you're
  3704. using Tomcat then read the instructions here <ulink
  3705. url="http://jakarta.apache.org/tomcat/tomcat-5.0-doc/ssl-howto.html"></ulink>.
  3706. It's important that you get this working before trying it out with
  3707. Acegi Security.</para>
  3708. </sect2>
  3709. <sect2 id="security-x509-details">
  3710. <title>X509 with Acegi Security</title>
  3711. <para>With X509 authentication, there is no explicit login procedure
  3712. so the implementation is relatively simple; there is no need to
  3713. redirect requests in order to interact with the user. As a result,
  3714. some of the classes behave slightly differently from their equivalents
  3715. in other packages. For example, the default <quote>entry point</quote>
  3716. class, which is normally responsible for starting the authentication
  3717. process, is only invoked if the certificate is rejected and it always
  3718. returns an error to the user. With a suitable bean configuration, the
  3719. normal sequence of events is as follows <orderedlist>
  3720. <listitem>
  3721. <para>The <classname>X509ProcessingFilter</classname> extracts
  3722. the certificate from the request and uses it as the credentials
  3723. for an authentication request. The generated authentication
  3724. request is an <classname>X509AuthenticationToken</classname>.
  3725. The request is passed to the authentication manager.</para>
  3726. </listitem>
  3727. <listitem>
  3728. <para>The <classname>X509AuthenticationProvider</classname>
  3729. receives the token. Its main concern is to obtain the user
  3730. information (in particular the user's granted authorities) that
  3731. matches the certificate. It delegates this responsibility to an
  3732. <interfacename>X509AuthoritiesPopulator</interfacename>.</para>
  3733. </listitem>
  3734. <listitem>
  3735. <para>The populator's single method,
  3736. <methodname>getUserDetails(X509Certificate
  3737. userCertificate)</methodname> is invoked. Implementations should
  3738. return a <classname>UserDetails</classname> instance containing
  3739. the array of <classname>GrantedAuthority</classname> objects for
  3740. the user. This method can also choose to reject the certificate
  3741. (for example if it doesn't contain a matching user name). In
  3742. such cases it should throw a
  3743. <exceptionname>BadCredentialsException</exceptionname>. A
  3744. DAO-based implementation,
  3745. <classname>DaoX509AuthoritiesPopulator</classname>, is provided
  3746. which extracts the user's name from the subject <quote>common
  3747. name</quote> (CN) in the certificate. It also allows you to set
  3748. your own regular expression to match a different part of the
  3749. subject's distinguished name. A UserDetailsService is used to
  3750. load the user information.<!-- TODO: Give email matching as an example --></para>
  3751. </listitem>
  3752. <listitem>
  3753. <para>If everything has gone smoothly then there should be a
  3754. valid <classname>Authentication</classname> object in the secure
  3755. context and the invocation will procede as normal. If no
  3756. certificate was found, or the certificate was rejected, then the
  3757. <classname>ExceptionTranslationFilter</classname> will invoke
  3758. the <classname>X509ProcessingFilterEntryPoint</classname> which
  3759. returns a 403 error (forbidden) to the user.</para>
  3760. </listitem>
  3761. </orderedlist></para>
  3762. </sect2>
  3763. <sect2 id="security-x509-config">
  3764. <title>Configuring the X509 Provider</title>
  3765. <para>There is a version of the <link
  3766. linkend="security-sample">Contacts Sample Application</link> which
  3767. uses X509. Copy the beans and filter setup from this as a starting
  3768. point for configuring your own application. A set of example
  3769. certificates is also included which you can use to configure your
  3770. server. These are <itemizedlist>
  3771. <listitem>
  3772. <para><filename>marissa.p12</filename>: A PKCS12 format file
  3773. containing the client key and certificate. These should be
  3774. installed in your browser. It maps to the user
  3775. <quote>marissa</quote> in the application.</para>
  3776. </listitem>
  3777. <listitem>
  3778. <para><filename>server.p12</filename>: The server certificate
  3779. and key for HTTPS connections.</para>
  3780. </listitem>
  3781. <listitem>
  3782. <para><filename>ca.jks</filename>: A Java keystore containing
  3783. the certificate for the authority which issued marissa's
  3784. certificate. This will be used by the container to validate
  3785. client certificates.</para>
  3786. </listitem>
  3787. </itemizedlist> For JBoss 3.2.7 (with Tomcat 5.0), the SSL
  3788. configuration in the <filename>server.xml</filename> file looks like
  3789. this <programlisting>
  3790. &lt;!-- SSL/TLS Connector configuration --&gt;
  3791. &lt;Connector port="8443" address="${jboss.bind.address}"
  3792. maxThreads="100" minSpareThreads="5" maxSpareThreads="15"
  3793. scheme="https" secure="true"
  3794. sslProtocol = "TLS"
  3795. clientAuth="true" keystoreFile="${jboss.server.home.dir}/conf/server.p12"
  3796. keystoreType="PKCS12" keystorePass="password"
  3797. truststoreFile="${jboss.server.home.dir}/conf/ca.jks"
  3798. truststoreType="JKS" truststorePass="password"
  3799. /&gt;
  3800. </programlisting><parameter>clientAuth</parameter> can also be set to
  3801. <parameter>want</parameter> if you still want SSL connections to
  3802. succeed even if the client doesn't provide a certificate. Obviously
  3803. these clients won't be able to access any objects secured by Acegi
  3804. Security (unless you use a non-X509 authentication mechanism, such as
  3805. BASIC authentication, to authenticate the user).</para>
  3806. </sect2>
  3807. </sect1>
  3808. <sect1 id="security-ldap">
  3809. <title>LDAP Authentication Provider</title>
  3810. <sect2 id="security-ldap-overview">
  3811. <title>Overview</title>
  3812. <para>LDAP is often used by organizations as a central repository for
  3813. user information and as an authentication service. It can also be used
  3814. to store the role information for application users.</para>
  3815. <para>There are many different scenarios for how an LDAP server may be
  3816. configured so the Acegi LDAP provider is fully configurable. It uses
  3817. separate strategy interfaces for authentication and role retrieval and
  3818. provides default implementations which can be configured to handle a
  3819. wide range of situations.</para>
  3820. <para>You should be familiar with LDAP before trying to use it with
  3821. Acegi. The following link provides a good introduction to the concepts
  3822. involved and a guide to setting up a directory using the free LDAP
  3823. server OpenLDAP: <ulink
  3824. url="http://www.zytrax.com/books/ldap/"></ulink>. Some familiarity
  3825. with the JNDI APIs used to access LDAP from Java may also be useful.
  3826. We don't use any third-party LDAP libraries (Mozilla/Netscape, JLDAP
  3827. etc.) in the LDAP provider.</para>
  3828. <sect3 id="security-ldap-details">
  3829. <title>LDAP with Acegi Security</title>
  3830. <para>The main LDAP provider class is
  3831. <classname>org.acegisecurity.providers.ldap.LdapAuthenticationProvider</classname>.
  3832. This bean doesn't actually do much itself other than implement the
  3833. <methodname>retrieveUser</methodname> method required by its base
  3834. class,
  3835. <classname>AbstractUserDetailsAuthenticationProvider</classname>. It
  3836. delegates the work to two other beans, an
  3837. <interfacename>LdapAuthenticator</interfacename> and an
  3838. <interfacename>LdapAuthoritiesPopulator</interfacename> which are
  3839. responsible for authenticating the user and retrieving the user's
  3840. set of <interfacename>GrantedAuthority</interfacename>s
  3841. respectively.</para>
  3842. </sect3>
  3843. </sect2>
  3844. <sect2 id="security-ldap-authenticators">
  3845. <title>LdapAuthenticator Implementations</title>
  3846. <para>The authenticator is also responsible for retrieving any
  3847. required user attributes. This is because the permissions on the
  3848. attributes may depend on the type of authentication being used. For
  3849. example, if binding as the user, it may be necessary to read them with
  3850. the user's own permissions.</para>
  3851. <para>There are currently two authentication strategies supplied with
  3852. Acegi Security: <itemizedlist>
  3853. <listitem>
  3854. <para>Authentication directly to the LDAP server ("bind"
  3855. authentication).</para>
  3856. </listitem>
  3857. <listitem>
  3858. <para>Password comparison, where the password supplied by the
  3859. user is compared with the one stored in the repository. This can
  3860. either be done by retrieving the value of the password attribute
  3861. and checking it locally or by performing an LDAP "compare"
  3862. operation, where the supplied password is passed to the server
  3863. for comparison and the real password value is never
  3864. retrieved.</para>
  3865. </listitem>
  3866. </itemizedlist></para>
  3867. <sect3>
  3868. <title>Common Functionality</title>
  3869. <para>Before it is possible to authenticate a user (by either
  3870. strategy), the distinguished name (DN) has to be obtained from the
  3871. login name supplied to the application. This can be done either by
  3872. simple pattern-matching (by setting the
  3873. <property>setUserDnPatterns</property> array property) or by setting
  3874. the <property>userSearch</property> property. For the DN
  3875. pattern-matching approach, a standard Java pattern format is used,
  3876. and the login name will be substituted for the parameter
  3877. <parameter>{0}</parameter>. The pattern should be relative to the DN
  3878. that the configured
  3879. <interfacename>InitialDirContextFactory</interfacename> will bind to
  3880. (see the section on <link
  3881. linkend="security-ldap-dircontextfactory">connecting to the LDAP
  3882. server</link> for more information on this). For example, if you are
  3883. using an LDAP server specified by the URL
  3884. <literal>ldap://monkeymachine.co.uk/dc=acegisecurity,dc=org</literal>,
  3885. and have a pattern <literal>uid={0},ou=greatapes</literal>, then a
  3886. login name of "gorilla" will map to a DN
  3887. <literal>uid=gorilla,ou=greatapes,dc=acegisecurity,dc=org</literal>.
  3888. Each configured DN pattern will be tried in turn until a match is
  3889. found. For information on using a search, see the section on <link
  3890. linkend="security-ldap-searchobjects">search objects</link> below. A
  3891. combination of the two approaches can also be used - the patterns
  3892. will be checked first and if no matching DN is found, the search
  3893. will be used.</para>
  3894. </sect3>
  3895. <sect3>
  3896. <title>BindAuthenticator</title>
  3897. <para>The class
  3898. <classname>org.acegisecurity.providers.ldap.authenticator.BindAuthenticator</classname>
  3899. implements the bind authentication strategy. It simply attempts to
  3900. bind as the user.</para>
  3901. </sect3>
  3902. <sect3>
  3903. <title>PasswordComparisonAuthenticator</title>
  3904. <para>The class
  3905. <classname>org.acegisecurity.providers.ldap.authenticator.PasswordComparisonAuthenticator</classname>
  3906. implements the password comparison authentication strategy.</para>
  3907. </sect3>
  3908. <sect3 id="security-ldap-authenticators-adauth">
  3909. <title>Active Directory Authentication</title>
  3910. <para>In addition to standard LDAP authentication (binding with a
  3911. DN), Active Directory has its own non-standard syntax for user
  3912. authentication.</para>
  3913. </sect3>
  3914. </sect2>
  3915. <sect2 id="security-ldap-dircontextfactory">
  3916. <title>Connecting to the LDAP Server</title>
  3917. <para>The beans discussed above have to be able to connect to the
  3918. server. They both have to be supplied with an
  3919. <interfacename>InitialDirContextFactory</interfacename> instance.
  3920. Unless you have special requirements, this will usually be a
  3921. <classname>DefaultInitialDirContextFactory</classname> bean, which can
  3922. be configured with the URL of your LDAP server and optionally with the
  3923. username and password of a "manager" user which will be used by
  3924. default when binding to the server (instead of binding anonymously).
  3925. It currently supports "simple" LDAP authentication.</para>
  3926. <para><classname>DefaultInitialDirContextFactory</classname> uses
  3927. Sun's JNDI LDAP implementation by default (the one that comes with the
  3928. JDK). It also supports the built in connection pooling offered by
  3929. Sun's provider. Connections which are obtained either anonymously or
  3930. with the "manager" user's identity will be pooled automatically.
  3931. Connections obtained with a specific user's identity will not be
  3932. pooled. Connection pooling can be disabled completely by setting the
  3933. <property>useConnectionPool</property> property to false.</para>
  3934. <para>See the <ulink
  3935. url="http://acegisecurity.org/multiproject/acegi-security/xref/org/acegisecurity/providers/ldap/DefaultInitialDirContextFactory.html">class
  3936. Javadoc and source</ulink> for more information on this bean and its
  3937. properties.</para>
  3938. </sect2>
  3939. <sect2 id="security-ldap-searchobjects">
  3940. <title>LDAP Search Objects</title>
  3941. <para>Often more a more complicated strategy than simple DN-matching
  3942. is required to locate a user entry in the directory. This can be
  3943. encapsulated in an <interfacename>LdapUserSearch</interfacename>
  3944. instance which can be supplied to the authenticator implementations,
  3945. for example, to allow them to locate a user. The supplied
  3946. implementation is
  3947. <classname>FilterBasedLdapUserSearch</classname>.</para>
  3948. <sect3>
  3949. <title><classname>FilterBasedLdapUserSearch</classname></title>
  3950. <para>This bean uses an LDAP filter to match the user object in the
  3951. directory. The process is explained in the Javadoc for the
  3952. corresponding search method on the <ulink
  3953. url="http://java.sun.com/j2se/1.4.2/docs/api/javax/naming/directory/DirContext.html#search(javax.naming.Name,%20java.lang.String,%20java.lang.Object[],%20javax.naming.directory.SearchControls)">JDK
  3954. DirContext class</ulink>. As explained there, the search filter can
  3955. be supplied with parameters. For this class, the only valid
  3956. parameter is <parameter>{0}</parameter> which will be replaced with
  3957. the user's login name.</para>
  3958. </sect3>
  3959. </sect2>
  3960. <sect2 id="security-ldap-config">
  3961. <title>Configuring the LDAP Provider</title>
  3962. <para>There is a version of the <link
  3963. linkend="security-sample">Contacts Sample Application</link> which
  3964. uses LDAP. You can copy the beans and filter setup from this as a
  3965. starting point for configuring your own application.</para>
  3966. <para>A typical configuration, using some of the beans we've discussed
  3967. above, might look like this: <programlisting>
  3968. &lt;bean id="initialDirContextFactory"
  3969. class="org.acegisecurity.providers.ldap.DefaultInitialDirContextFactory"&gt;
  3970. &lt;constructor-arg value="ldap://monkeymachine:389/dc=acegisecurity,dc=org"/&gt;
  3971. &lt;property name="managerDn"&gt;&lt;value&gt;cn=manager,dc=acegisecurity,dc=org&lt;/value&gt;&lt;/property&gt;
  3972. &lt;property name="managerPassword"&gt;&lt;value&gt;password&lt;/value&gt;&lt;/property&gt;
  3973. &lt;/bean&gt;
  3974. &lt;bean id="userSearch"
  3975. class="org.acegisecurity.providers.ldap.search.FilterBasedLdapUserSearch"&gt;
  3976. &lt;constructor-arg index="0"&gt;
  3977. &lt;value&gt;&lt;/value&gt;
  3978. &lt;/constructor-arg&gt;
  3979. &lt;constructor-arg index="1"&gt;
  3980. &lt;value&gt;(uid={0})&lt;/value&gt;
  3981. &lt;/constructor-arg&gt;
  3982. &lt;constructor-arg index="2"&gt;
  3983. &lt;ref local="initialDirContextFactory" /&gt;
  3984. &lt;/constructor-arg&gt;
  3985. &lt;property name="searchSubtree"&gt;
  3986. &lt;value&gt;true&lt;/value&gt;
  3987. &lt;/property&gt;
  3988. &lt;/bean&gt;
  3989. &lt;bean id="ldapAuthProvider"
  3990. class="org.acegisecurity.providers.ldap.LdapAuthenticationProvider"&gt;
  3991. &lt;constructor-arg&gt;
  3992. &lt;bean class="org.acegisecurity.providers.ldap.authenticator.BindAuthenticator"&gt;
  3993. &lt;constructor-arg&gt;&lt;ref local="initialDirContextFactory"/&gt;&lt;/constructor-arg&gt;
  3994. &lt;property name="userDnPatterns"&gt;&lt;list&gt;&lt;value&gt;uid={0},ou=people&lt;/value&gt;&lt;/list&gt;&lt;/property&gt;
  3995. &lt;/bean&gt;
  3996. &lt;/constructor-arg&gt;
  3997. &lt;constructor-arg&gt;
  3998. &lt;bean class="org.acegisecurity.providers.ldap.populator.DefaultLdapAuthoritiesPopulator"&gt;
  3999. &lt;constructor-arg&gt;&lt;ref local="initialDirContextFactory"/&gt;&lt;/constructor-arg&gt;
  4000. &lt;constructor-arg&gt;&lt;value&gt;ou=groups&lt;/value&gt;&lt;/constructor-arg&gt;
  4001. &lt;property name="groupRoleAttribute"&gt;&lt;value&gt;ou&lt;/value&gt;&lt;/property&gt;
  4002. &lt;/bean&gt;
  4003. &lt;/constructor-arg&gt;
  4004. &lt;/bean&gt;
  4005. </programlisting> This would set up the provider to access an LDAP
  4006. server with URL
  4007. <literal>ldap://monkeymachine:389/dc=acegisecurity,dc=org</literal>.
  4008. Authentication will be performed by attempting to bind with the DN
  4009. <literal>uid=&lt;user-login-name&gt;,ou=people,dc=acegisecurity,dc=org</literal>.
  4010. After successful authentication, roles will be assigned to the user by
  4011. searching under the DN
  4012. <literal>ou=groups,dc=acegisecurity,dc=org</literal> with the default
  4013. filter <literal>(member=&lt;user's-DN&gt;)</literal>. The role name
  4014. will be taken from the <quote>ou</quote> attribute of each
  4015. match.</para>
  4016. <para>We've also included the configuration for a user search object,
  4017. which uses the filter
  4018. <literal>(uid=&lt;user-login-name&gt;)</literal>. This could be used
  4019. instead of the DN-pattern (or in addition to it), by setting the
  4020. authenticator's <property>userSearch</property> property. The
  4021. autheticator would then call the search object to obtain the correct
  4022. user's DN before attempting to bind as this user.</para>
  4023. </sect2>
  4024. </sect1>
  4025. <sect1 id="security-channels">
  4026. <title>Channel Security</title>
  4027. <sect2 id="security-channels-overview">
  4028. <title>Overview</title>
  4029. <para>In addition to coordinating the authentication and authorization
  4030. requirements of your application, the Acegi Security System for Spring
  4031. is also able to ensure unauthenticated web requests have certain
  4032. properties. These properties may include being of a particular
  4033. transport type, having a particular <literal>HttpSession</literal>
  4034. attribute set and so on. The most common requirement is for your web
  4035. requests to be received using a particular transport protocol, such as
  4036. HTTPS.</para>
  4037. <para>An important issue in considering transport security is that of
  4038. session hijacking. Your web container manages a
  4039. <literal>HttpSession</literal> by reference to a
  4040. <literal>jsessionid</literal> that is sent to user agents either via a
  4041. cookie or URL rewriting. If the <literal>jsessionid</literal> is ever
  4042. sent over HTTP, there is a possibility that session identifier can be
  4043. intercepted and used to impersonate the user after they complete the
  4044. authentication process. This is because most web containers maintain
  4045. the same session identifier for a given user, even after they switch
  4046. from HTTP to HTTPS pages.</para>
  4047. <para>If session hijacking is considered too significant a risk for
  4048. your particular application, the only option is to use HTTPS for every
  4049. request. This means the <literal>jsessionid</literal> is never sent
  4050. across an insecure channel. You will need to ensure your
  4051. <literal>web.xml</literal>-defined
  4052. <literal>&lt;welcome-file&gt;</literal> points to a HTTPS location,
  4053. and the application never directs the user to a HTTP location. The
  4054. Acegi Security System for Spring provides a solution to assist with
  4055. the latter.</para>
  4056. </sect2>
  4057. <sect2 id="security-channels-installation">
  4058. <title>Configuration</title>
  4059. <para>To utilise Acegi Security's channel security services, add the
  4060. following lines to <literal>web.xml</literal>:</para>
  4061. <para><programlisting>
  4062. &lt;filter&gt;
  4063. &lt;filter-name&gt;Acegi Channel Processing Filter&lt;/filter-name&gt;
  4064. &lt;filter-class&gt;org.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
  4065. &lt;init-param&gt;
  4066. &lt;param-name&gt;targetClass&lt;/param-name&gt;
  4067. &lt;param-value&gt;org.acegisecurity.securechannel.ChannelProcessingFilter&lt;/param-value&gt;
  4068. &lt;/init-param&gt;
  4069. &lt;/filter&gt;
  4070. &lt;filter-mapping&gt;
  4071. &lt;filter-name&gt;Acegi Channel Processing Filter&lt;/filter-name&gt;
  4072. &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
  4073. &lt;/filter-mapping&gt;
  4074. </programlisting></para>
  4075. <para>As usual when running <literal>FilterToBeanProxy</literal>, you
  4076. will also need to configure the filter in your application
  4077. context:</para>
  4078. <para><programlisting>
  4079. &lt;bean id="channelProcessingFilter" class="org.acegisecurity.securechannel.ChannelProcessingFilter"&gt;
  4080. &lt;property name="channelDecisionManager"&gt;&lt;ref bean="channelDecisionManager"/&gt;&lt;/property&gt;
  4081. &lt;property name="filterInvocationDefinitionSource"&gt;
  4082. &lt;value&gt;
  4083. CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
  4084. \A/secure/.*\Z=REQUIRES_SECURE_CHANNEL
  4085. \A/acegilogin.jsp.*\Z=REQUIRES_SECURE_CHANNEL
  4086. \A/j_acegi_security_check.*\Z=REQUIRES_SECURE_CHANNEL
  4087. \A.*\Z=REQUIRES_INSECURE_CHANNEL
  4088. &lt;/value&gt;
  4089. &lt;/property&gt;
  4090. &lt;/bean&gt;
  4091. &lt;bean id="channelDecisionManager" class="org.acegisecurity.securechannel.ChannelDecisionManagerImpl"&gt;
  4092. &lt;property name="channelProcessors"&gt;
  4093. &lt;list&gt;
  4094. &lt;ref bean="secureChannelProcessor"/&gt;
  4095. &lt;ref bean="insecureChannelProcessor"/&gt;
  4096. &lt;/list&gt;
  4097. &lt;/property&gt;
  4098. &lt;/bean&gt;
  4099. &lt;bean id="secureChannelProcessor" class="org.acegisecurity.securechannel.SecureChannelProcessor"/&gt;
  4100. &lt;bean id="insecureChannelProcessor" class="org.acegisecurity.securechannel.InsecureChannelProcessor"/&gt;
  4101. </programlisting></para>
  4102. <para>Like <literal>FilterSecurityInterceptor</literal>, Apache Ant
  4103. style paths are also supported by the
  4104. <literal>ChannelProcessingFilter</literal>.</para>
  4105. <para>The <literal>ChannelProcessingFilter</literal> operates by
  4106. filtering all web requests and determining the configuration
  4107. attributes that apply. It then delegates to the
  4108. <literal>ChannelDecisionManager</literal>. The default implementation,
  4109. <literal>ChannelDecisionManagerImpl</literal>, should suffice in most
  4110. cases. It simply delegates through the list of configured
  4111. <literal>ChannelProcessor</literal> instances. A
  4112. <literal>ChannelProcessor</literal> will review the request, and if it
  4113. is unhappy with the request (eg it was received across the incorrect
  4114. transport protocol), it will perform a redirect, throw an exception or
  4115. take whatever other action is appropriate.</para>
  4116. <para>Included with the Acegi Security System for Spring are two
  4117. concrete <literal>ChannelProcessor</literal> implementations:
  4118. <literal>SecureChannelProcessor</literal> ensures requests with a
  4119. configuration attribute of <literal>REQUIRES_SECURE_CHANNEL</literal>
  4120. are received over HTTPS, whilst
  4121. <literal>InsecureChannelProcessor</literal> ensures requests with a
  4122. configuration attribute of
  4123. <literal>REQUIRES_INSECURE_CHANNEL</literal> are received over HTTP.
  4124. Both implementations delegate to a
  4125. <literal>ChannelEntryPoint</literal> if the required transport
  4126. protocol is not used. The two <literal>ChannelEntryPoint</literal>
  4127. implementations included with Acegi Security simply redirect the
  4128. request to HTTP and HTTPS as appropriate. Appropriate defaults are
  4129. assigned to the <literal>ChannelProcessor</literal> implementations
  4130. for the configuration attribute keywords they respond to and the
  4131. <literal>ChannelEntryPoint</literal> they delegate to, although you
  4132. have the ability to override these using the application
  4133. context.</para>
  4134. <para>Note that the redirections are absolute (eg
  4135. <literal>http://www.company.com:8080/app/page</literal>), not relative
  4136. (eg <literal>/app/page</literal>). During testing it was discovered
  4137. that Internet Explorer 6 Service Pack 1 has a bug whereby it does not
  4138. respond correctly to a redirection instruction which also changes the
  4139. port to use. Accordingly, absolute URLs are used in conjunction with
  4140. bug detection logic in the <literal>PortResolverImpl</literal> that is
  4141. wired up by default to many Acegi Security beans. Please refer to the
  4142. JavaDocs for <literal>PortResolverImpl</literal> for further
  4143. details.</para>
  4144. </sect2>
  4145. <sect2 id="security-channels-usage">
  4146. <title>Usage</title>
  4147. <para>Once configured, using the channel security filter is very easy.
  4148. Simply request pages without regard to the protocol (ie HTTP or HTTPS)
  4149. or port (eg 80, 8080, 443, 8443 etc). Obviously you'll still need a
  4150. way of making the initial request (probably via the
  4151. <literal>web.xml</literal> <literal>&lt;welcome-file&gt;</literal> or
  4152. a well-known home page URL), but once this is done the filter will
  4153. perform redirects as defined by your application context.</para>
  4154. <para>You can also add your own <literal>ChannelProcessor</literal>
  4155. implementations to the <literal>ChannelDecisionManagerImpl</literal>.
  4156. For example, you might set a <literal>HttpSession</literal> attribute
  4157. when a human user is detected via a "enter the contents of this
  4158. graphic" procedure. Your <literal>ChannelProcessor</literal> would
  4159. respond to say <literal>REQUIRES_HUMAN_USER</literal> configuration
  4160. attributes and redirect to an appropriate entry point to start the
  4161. human user validation process if the <literal>HttpSession</literal>
  4162. attribute is not currently set.</para>
  4163. <para>To decide whether a security check belongs in a
  4164. <literal>ChannelProcessor</literal> or an
  4165. <literal>AccessDecisionVoter</literal>, remember that the former is
  4166. designed to handle unauthenticated requests, whilst the latter is
  4167. designed to handle authenticated requests. The latter therefore has
  4168. access to the granted authorities of the authenticated principal. In
  4169. addition, problems detected by a <literal>ChannelProcessor</literal>
  4170. will generally cause a HTTP/HTTPS redirection so its requirements can
  4171. be met, whilst problems detected by an
  4172. <literal>AccessDecisionVoter</literal> will ultimately result in an
  4173. <literal>AccessDeniedException</literal> (depending on the governing
  4174. <literal>AccessDecisionManager</literal>).</para>
  4175. </sect2>
  4176. </sect1>
  4177. <sect1 id="acls">
  4178. <title>Instance-Based Access Control List (ACL) Security</title>
  4179. <sect2 id="acls-overview">
  4180. <title>Overview</title>
  4181. <para>Complex applications often will find the need to define access
  4182. permissions not simply at a web request or method invocation level.
  4183. Instead, security decisions need to comprise both who
  4184. (<literal>Authentication</literal>), where
  4185. (<literal>MethodInvocation</literal>) and what
  4186. (<literal>SomeDomainObject</literal>). In other words, authorization
  4187. decisions also need to consider the actual domain object instance
  4188. subject of a method invocation.</para>
  4189. <para>Imagine you're designing an application for a pet clinic. There
  4190. will be two main groups of users of your Spring-based application:
  4191. staff of the pet clinic, as well as the pet clinic's customers. The
  4192. staff will have access to all of the data, whilst your customers will
  4193. only be able to see their own customer records. To make it a little
  4194. more interesting, your customers can allow other users to see their
  4195. customer records, such as their "puppy preschool "mentor or president
  4196. of their local "Pony Club". Using Acegi Security System for Spring as
  4197. the foundation, you have several approaches that can be
  4198. used:<orderedlist>
  4199. <listitem>
  4200. <para>Write your business methods to enforce the security. You
  4201. could consult a collection within the
  4202. <literal>Customer</literal> domain object instance to determine
  4203. which users have access. By using the
  4204. <literal>SecurityContextHolder.getContext().getAuthentication()</literal>,
  4205. you'll be able to access the <literal>Authentication</literal>
  4206. object.</para>
  4207. </listitem>
  4208. <listitem>
  4209. <para>Write an <literal>AccessDecisionVoter</literal> to enforce
  4210. the security from the <literal>GrantedAuthority[]</literal>s
  4211. stored in the <literal>Authentication</literal> object. This
  4212. would mean your <literal>AuthenticationManager</literal> would
  4213. need to populate the <literal>Authentication</literal> with
  4214. custom <literal>GrantedAuthority</literal>[]s representing each
  4215. of the <literal>Customer</literal> domain object instances the
  4216. principal has access to.</para>
  4217. </listitem>
  4218. <listitem>
  4219. <para>Write an <literal>AccessDecisionVoter</literal> to enforce
  4220. the security and open the target <literal>Customer</literal>
  4221. domain object directly. This would mean your voter needs access
  4222. to a DAO that allows it to retrieve the
  4223. <literal>Customer</literal> object. It would then access the
  4224. <literal>Customer</literal> object's collection of approved
  4225. users and make the appropriate decision.</para>
  4226. </listitem>
  4227. </orderedlist></para>
  4228. <para>Each one of these approaches is perfectly legitimate. However,
  4229. the first couples your authorization checking to your business code.
  4230. The main problems with this include the enhanced difficulty of unit
  4231. testing and the fact it would be more difficult to reuse the
  4232. <literal>Customer</literal> authorization logic elsewhere. Obtaining
  4233. the <literal>GrantedAuthority[]</literal>s from the
  4234. <literal>Authentication</literal> object is also fine, but will not
  4235. scale to large numbers of <literal>Customer</literal>s. If a user
  4236. might be able to access 5,000 <literal>Customer</literal>s (unlikely
  4237. in this case, but imagine if it were a popular vet for a large Pony
  4238. Club!) the amount of memory consumed and time required to construct
  4239. the <literal>Authentication</literal> object would be undesirable. The
  4240. final method, opening the <literal>Customer</literal> directly from
  4241. external code, is probably the best of the three. It achieves
  4242. separation of concerns, and doesn't misuse memory or CPU cycles, but
  4243. it is still inefficient in that both the
  4244. <literal>AccessDecisionVoter</literal> and the eventual business
  4245. method itself will perform a call to the DAO responsible for
  4246. retrieving the <literal>Customer</literal> object. Two accesses per
  4247. method invocation is clearly undesirable. In addition, with every
  4248. approach listed you'll need to write your own access control list
  4249. (ACL) persistence and business logic from scratch.</para>
  4250. <para>Fortunately, there is another alternative, which we'll talk
  4251. about below.</para>
  4252. </sect2>
  4253. <sect2 id="acls-acl-package">
  4254. <title>The org.acegisecurity.acl Package</title>
  4255. <para>The <literal>org.acegisecurity.acl</literal> package is very
  4256. simple, comprising only a handful of interfaces and a single class, as
  4257. shown in Figure 6. It provides the basic foundation for access control
  4258. list (ACL) lookups.</para>
  4259. <para><mediaobject>
  4260. <imageobject role="html">
  4261. <imagedata align="center" fileref="images/ACLSecurity.gif"
  4262. format="GIF" />
  4263. </imageobject>
  4264. <caption>
  4265. <para>Figure 6: Access Control List Manager</para>
  4266. </caption>
  4267. </mediaobject></para>
  4268. <para>The central interface is <literal>AclManager</literal>, which is
  4269. defined by two methods:</para>
  4270. <para><programlisting>public AclEntry[] getAcls(java.lang.Object domainInstance);
  4271. public AclEntry[] getAcls(java.lang.Object domainInstance, Authentication authentication);</programlisting></para>
  4272. <para><literal>AclManager</literal> is intended to be used as a
  4273. collaborator against your business objects, or, more desirably,
  4274. <literal>AccessDecisionVoter</literal>s. This means you use Spring's
  4275. normal <literal>ApplicationContext</literal> features to wire up your
  4276. <literal>AccessDecisionVoter</literal> (or business method) with an
  4277. <literal>AclManager</literal>. Consideration was given to placing the
  4278. ACL information in the <literal>ContextHolder</literal>, but it was
  4279. felt this would be inefficient both in terms of memory usage as well
  4280. as the time spent loading potentially unused ACL information. The
  4281. trade-off of needing to wire up a collaborator for those objects
  4282. requiring ACL information is rather minor, particularly in a
  4283. Spring-managed application.</para>
  4284. <para>The first method of the <literal>AclManager</literal> will
  4285. return all ACLs applying to the domain object instance passed to it.
  4286. The second method does the same, but only returns those ACLs which
  4287. apply to the passed <literal>Authentication</literal> object.</para>
  4288. <para>The <literal>AclEntry</literal> interface returned by
  4289. <literal>AclManager</literal> is merely a marker interface. You will
  4290. need to provide an implementation that reflects that ACL permissions
  4291. for your application.</para>
  4292. <para>Rounding out the <literal>org.acegisecurity.acl</literal>
  4293. package is an <literal>AclProviderManager</literal> class, with a
  4294. corresponding <literal>AclProvider</literal> interface.
  4295. <literal>AclProviderManager</literal> is a concrete implementation of
  4296. <literal>AclManager</literal>, which iterates through registered
  4297. <literal>AclProvider</literal>s. The first
  4298. <literal>AclProvider</literal> that indicates it can authoritatively
  4299. provide ACL information for the presented domain object instance will
  4300. be used. This is very similar to the
  4301. <literal>AuthenticationProvider</literal> interface used for
  4302. authentication.</para>
  4303. <para>With this background, let's now look at a usable ACL
  4304. implementation.</para>
  4305. </sect2>
  4306. <sect2 id="acls-masking">
  4307. <title>Integer Masked ACLs</title>
  4308. <para>Acegi Security System for Spring includes a production-quality
  4309. ACL provider implementation, which is shown in Figure 7.</para>
  4310. <para><mediaobject>
  4311. <imageobject role="html">
  4312. <imagedata align="center" fileref="images/BasicAclProvider.gif"
  4313. format="GIF" />
  4314. </imageobject>
  4315. <caption>
  4316. <para>Figure 7: Basic ACL Manager</para>
  4317. </caption>
  4318. </mediaobject></para>
  4319. <para>The implementation is based on integer masking, which is
  4320. commonly used for ACL permissions given its flexibility and speed.
  4321. Anyone who has used Unix's <literal>chmod</literal> command will know
  4322. all about this type of permission masking (eg <literal>chmod
  4323. 777</literal>). You'll find the classes and interfaces for the integer
  4324. masking ACL package under
  4325. <literal>org.acegisecurity.acl.basic</literal>.</para>
  4326. <para>Extending the <literal>AclEntry</literal> interface is a
  4327. <literal>BasicAclEntry</literal> interface, with the main methods
  4328. shown below:</para>
  4329. <para><programlisting>public AclObjectIdentity getAclObjectIdentity();
  4330. public AclObjectIdentity getAclObjectParentIdentity();
  4331. public int getMask();
  4332. public java.lang.Object getRecipient();</programlisting></para>
  4333. <para>As shown, each <literal>BasicAclEntry</literal> has four main
  4334. properties. The <literal>mask</literal> is the integer that represents
  4335. the permissions granted to the <literal>recipient</literal>. The
  4336. <literal>aclObjectIdentity</literal> is able to identify the domain
  4337. object instance for which the ACL applies, and the
  4338. <literal>aclObjectParentIdentity</literal> optionally specifies the
  4339. parent of the domain object instance. Multiple
  4340. <literal>BasicAclEntry</literal>s usually exist against a single
  4341. domain object instance, and as suggested by the parent identity
  4342. property, permissions granted higher in the object hierarchy will
  4343. trickle down and be inherited (unless blocked by integer zero).</para>
  4344. <para><literal>BasicAclEntry</literal> implementations typically
  4345. provide convenience methods, such as
  4346. <literal>isReadAllowed()</literal>, to avoid application classes
  4347. needing to perform bit masking themselves. The
  4348. <literal>SimpleAclEntry</literal> and
  4349. <literal>AbstractBasicAclEntry</literal> demonstrate and provide much
  4350. of this bit masking logic.</para>
  4351. <para>The <literal>AclObjectIdentity</literal> itself is merely a
  4352. marker interface, so you need to provide implementations for your
  4353. domain objects. However, the package does include a
  4354. <literal>NamedEntityObjectIdentity</literal> implementation which will
  4355. suit many needs. The <literal>NamedEntityObjectIdentity</literal>
  4356. identifies a given domain object instance by the classname of the
  4357. instance and the identity of the instance. A
  4358. <literal>NamedEntityObjectIdentity</literal> can be constructed
  4359. manually (by calling the constructor and providing the classname and
  4360. identity <literal>String</literal>s), or by passing in any domain
  4361. object that contains a <literal>getId()</literal> method.</para>
  4362. <para>The actual <literal>AclProvider</literal> implementation is
  4363. named <literal>BasicAclProvider</literal>. It has adopted a similar
  4364. design to that used by the authentication-related
  4365. <literal>DaoAuthenticationProvder</literal>. Specifically, you define
  4366. a <literal>BasicAclDao</literal> against the provider, so different
  4367. ACL repository types can be accessed in a pluggable manner. The
  4368. <literal>BasicAclProvider</literal> also supports pluggable cache
  4369. providers (with Acegi Security System for Spring including an
  4370. implementation that fronts EH-CACHE).</para>
  4371. <para>The <literal>BasicAclDao</literal> interface is very simple to
  4372. implement:</para>
  4373. <para><programlisting>public BasicAclEntry[] getAcls(AclObjectIdentity aclObjectIdentity);</programlisting></para>
  4374. <para>A <literal>BasicAclDao</literal> implementation needs to
  4375. understand the presented <literal>AclObjectIdentity</literal> and how
  4376. it maps to a storage repository, find the relevant records, and create
  4377. appropriate <literal>BasicAclEntry</literal> objects and return
  4378. them.</para>
  4379. <para>Acegi Security includes a single <literal>BasicAclDao</literal>
  4380. implementation called <literal>JdbcDaoImpl</literal>. As implied by
  4381. the name, <literal>JdbcDaoImpl</literal> accesses ACL information from
  4382. a JDBC database. There is also an extended version of this DAO,
  4383. <literal>JdbcExtendedDaoImpl</literal>, which provides CRUD operations
  4384. on the JDBC database, although we won't discuss these features here.
  4385. The default database schema and some sample data will aid in
  4386. understanding its function:</para>
  4387. <para><programlisting>CREATE TABLE acl_object_identity (
  4388. id IDENTITY NOT NULL,
  4389. object_identity VARCHAR_IGNORECASE(250) NOT NULL,
  4390. parent_object INTEGER,
  4391. acl_class VARCHAR_IGNORECASE(250) NOT NULL,
  4392. CONSTRAINT unique_object_identity UNIQUE(object_identity),
  4393. FOREIGN KEY (parent_object) REFERENCES acl_object_identity(id)
  4394. );
  4395. CREATE TABLE acl_permission (
  4396. id IDENTITY NOT NULL,
  4397. acl_object_identity INTEGER NOT NULL,
  4398. recipient VARCHAR_IGNORECASE(100) NOT NULL,
  4399. mask INTEGER NOT NULL,
  4400. CONSTRAINT unique_recipient UNIQUE(acl_object_identity, recipient),
  4401. FOREIGN KEY (acl_object_identity) REFERENCES acl_object_identity(id)
  4402. );
  4403. INSERT INTO acl_object_identity VALUES (1, 'corp.DomainObject:1', null, 'org.acegisecurity.acl.basic.SimpleAclEntry');
  4404. INSERT INTO acl_object_identity VALUES (2, 'corp.DomainObject:2', 1, 'org.acegisecurity.acl.basic.SimpleAclEntry');
  4405. INSERT INTO acl_object_identity VALUES (3, 'corp.DomainObject:3', 1, 'org.acegisecurity.acl.basic.SimpleAclEntry');
  4406. INSERT INTO acl_object_identity VALUES (4, 'corp.DomainObject:4', 1, 'org.acegisecurity.acl.basic.SimpleAclEntry');
  4407. INSERT INTO acl_object_identity VALUES (5, 'corp.DomainObject:5', 3, 'org.acegisecurity.acl.basic.SimpleAclEntry');
  4408. INSERT INTO acl_object_identity VALUES (6, 'corp.DomainObject:6', 3, 'org.acegisecurity.acl.basic.SimpleAclEntry');
  4409. INSERT INTO acl_permission VALUES (null, 1, 'ROLE_SUPERVISOR', 1);
  4410. INSERT INTO acl_permission VALUES (null, 2, 'ROLE_SUPERVISOR', 0);
  4411. INSERT INTO acl_permission VALUES (null, 2, 'marissa', 2);
  4412. INSERT INTO acl_permission VALUES (null, 3, 'scott', 14);
  4413. INSERT INTO acl_permission VALUES (null, 6, 'scott', 1);</programlisting></para>
  4414. <para>As can be seen, database-specific constraints are used
  4415. extensively to ensure the integrity of the ACL information. If you
  4416. need to use a different database (Hypersonic SQL statements are shown
  4417. above), you should try to implement equivalent constraints. The
  4418. equivalent Oracle configuration is:</para>
  4419. <para><programlisting>CREATE TABLE ACL_OBJECT_IDENTITY (
  4420. ID number(19,0) not null,
  4421. OBJECT_IDENTITY varchar2(255) NOT NULL,
  4422. PARENT_OBJECT number(19,0),
  4423. ACL_CLASS varchar2(255) NOT NULL,
  4424. primary key (ID)
  4425. );
  4426. ALTER TABLE ACL_OBJECT_IDENTITY ADD CONTRAINT FK_PARENT_OBJECT foreign key (ID) references ACL_OBJECT_IDENTITY
  4427. CREATE SEQUENCE ACL_OBJECT_IDENTITY_SEQ;
  4428. CREATE OR REPLACE TRIGGER ACL_OBJECT_IDENTITY_ID
  4429. BEFORE INSERT ON ACL_OBJECT_IDENTITY
  4430. FOR EACH ROW
  4431. BEGIN
  4432. SELECT ACL_OBJECT_IDENTITY_SEQ.NEXTVAL INTO :new.id FROM dual;
  4433. END;
  4434. CREATE TABLE ACL_PERMISSION (
  4435. ID number(19,0) not null,
  4436. ACL_OBJECT_IDENTITY number(19,0) NOT NULL,
  4437. RECIPIENT varchar2(255) NOT NULL,
  4438. MASK number(19,0) NOT NULL,
  4439. primary key (ID)
  4440. );
  4441. ALTER TABLE ACL_PERMISSION ADD CONTRAINT UNIQUE_ID_RECIPIENT unique (acl_object_identity, recipient);
  4442. CREATE SEQUENCE ACL_PERMISSION_SEQ;
  4443. CREATE OR REPLACE TRIGGER ACL_PERMISSION_ID
  4444. BEFORE INSERT ON ACL_PERMISSION
  4445. FOR EACH ROW
  4446. BEGIN
  4447. SELECT ACL_PERMISSION_SEQ.NEXTVAL INTO :new.id FROM dual;
  4448. END;
  4449. &lt;bean id="basicAclExtendedDao" class="org.acegisecurity.acl.basic.jdbc.JdbcExtendedDaoImpl"&gt;
  4450. &lt;property name="dataSource"&gt;
  4451. &lt;ref bean="dataSource"/&gt;
  4452. &lt;/property&gt;
  4453. &lt;property name="objectPropertiesQuery" value="${acegi.objectPropertiesQuery}"/&gt;
  4454. &lt;/bean&gt;
  4455. &lt;prop key="acegi.objectPropertiesQuery"&gt;SELECT CHILD.ID, CHILD.OBJECT_IDENTITY, CHILD.ACL_CLASS, PARENT.OBJECT_IDENTITY as PARENT_OBJECT_IDENTITY FROM acl_object_identity as CHILD LEFT OUTER JOIN acl_object_identity as PARENT ON CHILD.parent_object=PARENT.id WHERE CHILD.object_identity = ?&lt;/prop&gt; </programlisting></para>
  4456. <para>The <literal>JdbcDaoImpl</literal> will only respond to requests
  4457. for <literal>NamedEntityObjectIdentity</literal>s. It converts such
  4458. identities into a single <literal>String</literal>, comprising
  4459. the<literal> NamedEntityObjectIdentity.getClassname()</literal> +
  4460. <literal>":"</literal> +
  4461. <literal>NamedEntityObjectIdentity.getId()</literal>. This yields the
  4462. type of <literal>object_identity</literal> values shown above. As
  4463. indicated by the sample data, each database row corresponds to a
  4464. single <literal>BasicAclEntry</literal>. As stated earlier and
  4465. demonstrated by <literal>corp.DomainObject:2</literal> in the above
  4466. sample data, each domain object instance will often have multiple
  4467. <literal>BasicAclEntry</literal>[]s.</para>
  4468. <para>As <literal>JdbcDaoImpl</literal> is required to return concrete
  4469. <literal>BasicAclEntry</literal> classes, it needs to know which
  4470. <literal>BasicAclEntry</literal> implementation it is to create and
  4471. populate. This is the role of the <literal>acl_class</literal> column.
  4472. <literal>JdbcDaoImpl</literal> will create the indicated class and set
  4473. its <literal>mask</literal>, <literal>recipient</literal>,
  4474. <literal>aclObjectIdentity</literal> and
  4475. <literal>aclObjectParentIdentity</literal> properties.</para>
  4476. <para>As you can probably tell from the sample data, the
  4477. <literal>parent_object_identity</literal> value can either be null or
  4478. in the same format as the <literal>object_identity</literal>. If
  4479. non-null, <literal>JdbcDaoImpl</literal> will create a
  4480. <literal>NamedEntityObjectIdentity</literal> to place inside the
  4481. returned <literal>BasicAclEntry</literal> class.</para>
  4482. <para>Returning to the <literal>BasicAclProvider</literal>, before it
  4483. can poll the <literal>BasicAclDao</literal> implementation it needs to
  4484. convert the domain object instance it was passed into an
  4485. <literal>AclObjectIdentity</literal>.
  4486. <literal>BasicAclProvider</literal> has a <literal>protected
  4487. AclObjectIdentity obtainIdentity(Object domainInstance)</literal>
  4488. method that is responsible for this. As a protected method, it enables
  4489. subclasses to easily override. The normal implementation checks
  4490. whether the passed domain object instance implements the
  4491. <literal>AclObjectIdentityAware</literal> interface, which is merely a
  4492. getter for an <literal>AclObjectIdentity</literal>. If the domain
  4493. object does implement this interface, that is the identity returned.
  4494. If the domain object does not implement this interface, the method
  4495. will attempt to create an <literal>AclObjectIdentity</literal> by
  4496. passing the domain object instance to the constructor of a class
  4497. defined by the
  4498. <literal>BasicAclProvider.getDefaultAclObjectIdentity()</literal>
  4499. method. By default the defined class is
  4500. <literal>NamedEntityObjectIdentity</literal>, which was described in
  4501. more detail above. Therefore, you will need to either (i) provide a
  4502. <literal>getId()</literal> method on your domain objects, (ii)
  4503. implement <literal>AclObjectIdentityAware</literal> on your domain
  4504. objects, (iii) provide an alternative
  4505. <literal>AclObjectIdentity</literal> implementation that will accept
  4506. your domain object in its constructor, or (iv) override the
  4507. <literal>obtainIdentity(Object)</literal> method.</para>
  4508. <para>Once the <literal>AclObjectIdentity</literal> of the domain
  4509. object instance is determined, the <literal>BasicAclProvider</literal>
  4510. will poll the DAO to obtain its <literal>BasicAclEntry</literal>[]s.
  4511. If any of the entries returned by the DAO indicate there is a parent,
  4512. that parent will be polled, and the process will repeat until there is
  4513. no further parent. The permissions assigned to a
  4514. <literal>recipient</literal> closest to the domain object instance
  4515. will always take priority and override any inherited permissions. From
  4516. the sample data above, the following inherited permissions would
  4517. apply:</para>
  4518. <para><programlisting>--- Mask integer 0 = no permissions
  4519. --- Mask integer 1 = administer
  4520. --- Mask integer 2 = read
  4521. --- Mask integer 6 = read and write permissions
  4522. --- Mask integer 14 = read and write and create permissions
  4523. ---------------------------------------------------------------------
  4524. --- *** INHERITED RIGHTS FOR DIFFERENT INSTANCES AND RECIPIENTS ***
  4525. --- INSTANCE RECIPIENT PERMISSION(S) (COMMENT #INSTANCE)
  4526. ---------------------------------------------------------------------
  4527. --- 1 ROLE_SUPERVISOR Administer
  4528. --- 2 ROLE_SUPERVISOR None (overrides parent #1)
  4529. --- marissa Read
  4530. --- 3 ROLE_SUPERVISOR Administer (from parent #1)
  4531. --- scott Read, Write, Create
  4532. --- 4 ROLE_SUPERVISOR Administer (from parent #1)
  4533. --- 5 ROLE_SUPERVISOR Administer (from parent #3)
  4534. --- scott Read, Write, Create (from parent #3)
  4535. --- 6 ROLE_SUPERVISOR Administer (from parent #3)
  4536. --- scott Administer (overrides parent #3)</programlisting></para>
  4537. <para>So the above explains how a domain object instance has its
  4538. <literal>AclObjectIdentity</literal> discovered, and the
  4539. <literal>BasicAclDao</literal> will be polled successively until an
  4540. array of inherited permissions is constructed for the domain object
  4541. instance. The final step is to determine the
  4542. <literal>BasicAclEntry</literal>[]s that are actually applicable to a
  4543. given <literal>Authentication</literal> object.</para>
  4544. <para>As you would recall, the <literal>AclManager</literal> (and all
  4545. delegates, up to and including <literal>BasicAclProvider</literal>)
  4546. provides a method which returns only those
  4547. <literal>BasicAclEntry</literal>[]s applying to a passed
  4548. <literal>Authentication</literal> object.
  4549. <literal>BasicAclProvider</literal> delivers this functionality by
  4550. delegating the filtering operation to an
  4551. <literal>EffectiveAclsResolver</literal> implementation. The default
  4552. implementation,
  4553. <literal>GrantedAuthorityEffectiveAclsResolver</literal>, will iterate
  4554. through the <literal>BasicAclEntry</literal>[]s and include only those
  4555. where the <literal>recipient</literal> is equal to either the
  4556. <literal>Authentication</literal>'s <literal>principal</literal> or
  4557. any of the <literal>Authentication</literal>'s
  4558. <literal>GrantedAuthority</literal>[]s. Please refer to the JavaDocs
  4559. for more information.</para>
  4560. <mediaobject>
  4561. <imageobject role="html">
  4562. <imagedata align="center" fileref="images/Permissions.gif"
  4563. format="GIF" />
  4564. </imageobject>
  4565. <caption>
  4566. <para>Figure 8: ACL Instantiation Approach</para>
  4567. </caption>
  4568. </mediaobject>
  4569. </sect2>
  4570. <sect2 id="acls-conclusion">
  4571. <title>Conclusion</title>
  4572. <para>Acegi Security's instance-specific ACL packages shield you from
  4573. much of the complexity of developing your own ACL approach. The
  4574. interfaces and classes detailed above provide a scalable, customisable
  4575. ACL solution that is decoupled from your application code. Whilst the
  4576. reference documentation may suggest complexity, the basic
  4577. implementation is able to support most typical applications
  4578. out-of-the-box.</para>
  4579. </sect2>
  4580. </sect1>
  4581. <sect1 id="security-filters">
  4582. <title>Filters</title>
  4583. <sect2 id="security-filters-overview">
  4584. <title>Overview</title>
  4585. <para>The Acegi Security System for Spring uses filters extensively.
  4586. Each filter is covered in detail in a respective section of this
  4587. document. This section includes information that applies to all
  4588. filters.</para>
  4589. </sect2>
  4590. <sect2 id="security-filters-filtertobeanproxy">
  4591. <title>FilterToBeanProxy</title>
  4592. <para>Most filters are configured using the
  4593. <literal>FilterToBeanProxy</literal>. An example configuration from
  4594. <literal>web.xml</literal> follows:</para>
  4595. <para><programlisting>
  4596. &lt;filter&gt;
  4597. &lt;filter-name&gt;Acegi HTTP Request Security Filter&lt;/filter-name&gt;
  4598. &lt;filter-class&gt;org.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
  4599. &lt;init-param&gt;
  4600. &lt;param-name&gt;targetClass&lt;/param-name&gt;
  4601. &lt;param-value&gt;org.acegisecurity.ClassThatImplementsFilter&lt;/param-value&gt;
  4602. &lt;/init-param&gt;
  4603. &lt;/filter&gt;
  4604. </programlisting></para>
  4605. <para>Notice that the filter in <literal>web.xml</literal> is actually
  4606. a <literal>FilterToBeanProxy</literal>, and not the filter that will
  4607. actually implements the logic of the filter. What
  4608. <literal>FilterToBeanProxy</literal> does is delegate the
  4609. <literal>Filter</literal>'s methods through to a bean which is
  4610. obtained from the Spring application context. This enables the bean to
  4611. benefit from the Spring application context lifecycle support and
  4612. configuration flexibility. The bean must implement
  4613. <literal>javax.servlet.Filter</literal>.</para>
  4614. <para>The <literal>FilterToBeanProxy</literal> only requires a single
  4615. initialization parameter, <literal>targetClass</literal> or
  4616. <literal>targetBean</literal>. The <literal>targetClass</literal>
  4617. parameter locates the first object in the application context of the
  4618. specified class, whilst <literal>targetBean</literal> locates the
  4619. object by bean name. Like standard Spring web applications, the
  4620. <literal>FilterToBeanProxy</literal> accesses the application context
  4621. via<literal>
  4622. WebApplicationContextUtils.getWebApplicationContext(ServletContext)</literal>,
  4623. so you should configure a <literal>ContextLoaderListener</literal> in
  4624. <literal>web.xml</literal>.</para>
  4625. <para>There is a lifecycle issue to consider when hosting
  4626. <literal>Filter</literal>s in an IoC container instead of a servlet
  4627. container. Specifically, which container should be responsible for
  4628. calling the <literal>Filter</literal>'s "startup" and "shutdown"
  4629. methods? It is noted that the order of initialization and destruction
  4630. of a <literal>Filter</literal> can vary by servlet container, and this
  4631. can cause problems if one <literal>Filter</literal> depends on
  4632. configuration settings established by an earlier initialized
  4633. <literal>Filter</literal>. The Spring IoC container on the other hand
  4634. has more comprehensive lifecycle/IoC interfaces (such as
  4635. <literal>InitializingBean</literal>,
  4636. <literal>DisposableBean</literal>, <literal>BeanNameAware</literal>,
  4637. <literal>ApplicationContextAware</literal> and many others) as well as
  4638. a well-understood interface contract, predictable method invocation
  4639. ordering, autowiring support, and even options to avoid implementing
  4640. Spring interfaces (eg the <literal>destroy-method</literal> attribute
  4641. in Spring XML). For this reason we recommend the use of Spring
  4642. lifecycle services instead of servlet container lifecycle services
  4643. wherever possible. By default <literal>FilterToBeanProxy</literal>
  4644. will not delegate <literal>init(FilterConfig)</literal> and
  4645. <literal>destroy()</literal> methods through to the proxied bean. If
  4646. you do require such invocations to be delegated, set the
  4647. <literal>lifecycle</literal> initialization parameter to
  4648. <literal>servlet-container-managed</literal>.</para>
  4649. </sect2>
  4650. <sect2 id="security-filters-filterchainproxy">
  4651. <title>FilterChainProxy</title>
  4652. <para>We strongly recommend to use <literal>FilterChainProxy</literal>
  4653. instead of adding multiple filters to
  4654. <literal>web.xml</literal>.</para>
  4655. <para>Whilst <literal>FilterToBeanProxy</literal> is a very useful
  4656. class, the problem is that the lines of code required for
  4657. <literal>&lt;filter&gt;</literal> and
  4658. <literal>&lt;filter-mapping&gt;</literal> entries in
  4659. <literal>web.xml</literal> explodes when using more than a few
  4660. filters. To overcome this issue, Acegi Security provides a
  4661. <literal>FilterChainProxy</literal> class. It is wired using a
  4662. <literal>FilterToBeanProxy</literal> (just like in the example above),
  4663. but the target class is
  4664. <literal>org.acegisecurity.util.FilterChainProxy</literal>. The filter
  4665. chain is then declared in the application context, using code such as
  4666. this:</para>
  4667. <para><programlisting>
  4668. &lt;bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy"&gt;
  4669. &lt;property name="filterInvocationDefinitionSource"&gt;
  4670. &lt;value&gt;
  4671. CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
  4672. PATTERN_TYPE_APACHE_ANT
  4673. /webServices/**=httpSessionContextIntegrationFilterWithASCFalse,basicProcessingFilter,exceptionTranslationFilter,filterSecurityInterceptor
  4674. /**=httpSessionContextIntegrationFilterWithASCTrue,authenticationProcessingFilter,exceptionTranslationFilter,filterSecurityInterceptor
  4675. &lt;/value&gt;
  4676. &lt;/property&gt;
  4677. &lt;/bean&gt;
  4678. </programlisting></para>
  4679. <para>You may notice similarities with the way
  4680. <literal>FilterSecurityInterceptor</literal> is declared. Both regular
  4681. expressions and Ant Paths are supported, and the most specific URIs
  4682. appear first. At runtime the <literal>FilterChainProxy</literal> will
  4683. locate the first URI pattern that matches the current web request.
  4684. Each of the corresponding configuration attributes represent the name
  4685. of a bean defined in the application context. The filters will then be
  4686. invoked in the order they are specified, with standard
  4687. <literal>FilterChain</literal> behaviour being respected (a
  4688. <literal>Filter</literal> can elect not to proceed with the chain if
  4689. it wishes to end processing).</para>
  4690. <para>As you can see, <literal>FilterChainProxy</literal> requires the
  4691. duplication of filter names for different request patterns (in the
  4692. above example, <literal>exceptionTranslationFilter</literal> and
  4693. <literal>filterSecurityInterceptor</literal> are duplicated). This
  4694. design decision was made to enable <literal>FilterChainProxy</literal>
  4695. to specify different <literal>Filter</literal> invocation orders for
  4696. different URI patterns, and also to improve both the expressiveness
  4697. (in terms of regular expressions, Ant Paths, and any custom
  4698. <literal>FilterInvocationDefinitionSource</literal> implementations)
  4699. and clarity of which <literal>Filter</literal>s should be
  4700. invoked.</para>
  4701. <para>You may have noticed we have declared two
  4702. <literal>HttpSessionContextIntegrationFilter</literal>s in the filter
  4703. chain (<literal>ASC</literal> is short for
  4704. <literal>allowSessionCreation</literal>, a property of
  4705. <literal>HttpSessionContextIntegrationFilter</literal>). As web
  4706. services will never present a <literal>jsessionid</literal> on future
  4707. requests, creating <literal>HttpSession</literal>s for such user
  4708. agents would be wasteful. If you had a high-volume application which
  4709. required maximum scalability, we recommend you use the approach shown
  4710. above. For smaller applications, using a single
  4711. <literal>HttpSessionContextIntegrationFilter</literal> (with its
  4712. default <literal>allowSessionCreation</literal> as
  4713. <literal>true</literal>) would likely be sufficient.</para>
  4714. <para>In relation to lifecycle issues, the
  4715. <literal>FilterChainProxy</literal> will always delegate
  4716. <literal>init(FilterConfig)</literal> and <literal>destroy()</literal>
  4717. methods through to the underlaying <literal>Filter</literal>s if such
  4718. methods are called against <literal>FilterChainProxy</literal> itself.
  4719. In this case, <literal>FilterChainProxy</literal> guarantees to only
  4720. initialize and destroy each <literal>Filter</literal> once,
  4721. irrespective of how many times it is declared by the
  4722. <literal>FilterInvocationDefinitionSource</literal>. You control the
  4723. overall choice as to whether these methods are called or not via the
  4724. <literal>lifecycle</literal> initialization parameter of the
  4725. <literal>FilterToBeanProxy</literal> that proxies
  4726. <literal>FilterChainProxy</literal>. As discussed above, by default
  4727. any servlet container lifecycle invocations are not delegated through
  4728. to <literal>FilterChainProxy</literal>.</para>
  4729. </sect2>
  4730. <sect2 id="security-filters-order">
  4731. <title>Filter Ordering</title>
  4732. <para>The order that filters are defined in <literal>web.xml</literal>
  4733. is important. NB: THE FILTER ORDER CHANGED FROM VERSION 0.8.0.</para>
  4734. <para>Irrespective of which filters you are actually using, the order
  4735. of the <literal>&lt;filter-mapping&gt;</literal>s should be as
  4736. follows:</para>
  4737. <orderedlist>
  4738. <listitem>
  4739. <para><literal>ChannelProcessingFilter</literal>, because it might
  4740. need to redirect to a different protocol</para>
  4741. </listitem>
  4742. <listitem>
  4743. <para><literal>ConcurrentSessionFilter</literal>, because it
  4744. doesn't use any <literal>SecurityContextHolder</literal>
  4745. functionality but needs to update the
  4746. <literal>SessionRegistry</literal> to reflect ongoing requests
  4747. from the principal</para>
  4748. </listitem>
  4749. <listitem>
  4750. <para><literal>HttpSessionContextIntegrationFilter</literal>, so a
  4751. <literal>Context</literal> can be setup in the
  4752. <literal>SecurityContextHolder</literal> at the beginning of a web
  4753. request, and any changes to the Context can be copied to the
  4754. <literal>HttpSession</literal> when the web request ends (ready
  4755. for use with the next web request)</para>
  4756. </listitem>
  4757. <listitem>
  4758. <para>Authentication processing mechanisms -
  4759. <literal>AuthenticationProcessingFilter</literal>,
  4760. <literal>CasProcessingFilter</literal>,
  4761. <literal>BasicProcessingFilter, HttpRequestIntegrationFilter,
  4762. JbossIntegrationFilter</literal> etc - so that the
  4763. <literal>SecurityContextHolder</literal> can be modified to
  4764. contain a valid <literal>Authentication</literal> request
  4765. token</para>
  4766. </listitem>
  4767. <listitem>
  4768. <para>The <literal>ContextHolderAwareRequestFilter</literal>, if
  4769. you are using it to install an Acegi Security aware
  4770. <literal>HttpServletRequestWrapper</literal> into your servlet
  4771. container</para>
  4772. </listitem>
  4773. <listitem>
  4774. <para><literal>RememberMeProcessingFilter</literal>, so that if no
  4775. earlier authentication processing mechanism updated the
  4776. <literal>SecurityContextHolder</literal>, and the request presents
  4777. a cookie that enables remember-me services to take place, a
  4778. suitable remembered
  4779. <literal><literal>Authentication</literal></literal> object will
  4780. be put there</para>
  4781. </listitem>
  4782. <listitem>
  4783. <para><literal>AnonymousProcessingFilter</literal>, so that if no
  4784. earlier authentication processing mechanism updated the
  4785. <literal>SecurityContextHolder</literal>, an anonymous
  4786. <literal>Authentication</literal> object will be put there</para>
  4787. </listitem>
  4788. <listitem>
  4789. <para><literal>ExceptionTranslationFilter</literal>, catch any
  4790. Acegi Security exceptions so that an either an HTTP error response
  4791. can be returned or an appropriate
  4792. <literal>AuthenticationEntryPoint</literal> can be launched</para>
  4793. </listitem>
  4794. <listitem>
  4795. <para><literal>FilterSecurityInterceptor</literal>, to protect web
  4796. URIs</para>
  4797. </listitem>
  4798. </orderedlist>
  4799. <para>All of the above filters use
  4800. <literal>FilterToBeanProxy</literal> or
  4801. <literal>FilterChainProxy</literal>, which is discussed in the
  4802. previous sections. It is recommended that a single
  4803. <literal>FilterToBeanProxy</literal> proxy through to a single
  4804. <literal>FilterChainProxy</literal> for each application, with that
  4805. <literal>FilterChainProxy</literal> defining all of the Acegi Security
  4806. <literal>Filter</literal>s.</para>
  4807. <para>If you're using SiteMesh, ensure the Acegi Security filters
  4808. execute before the SiteMesh filters are called. This enables the
  4809. <literal>SecurityContextHolder</literal> to be populated in time for
  4810. use by SiteMesh decorators.</para>
  4811. </sect2>
  4812. </sect1>
  4813. <sect1 id="security-sample">
  4814. <title>Contacts Sample Application</title>
  4815. <para>Included with the Acegi Security System for Spring is a very
  4816. simple application that can demonstrate the basic security facilities
  4817. provided by the system (and confirm your Container Adapter is properly
  4818. configured if you're using one).</para>
  4819. <para>If you build from CVS, the Contacts sample application includes
  4820. three deployable versions:
  4821. <literal>acegi-security-sample-contacts-filter.war</literal> is
  4822. configured with the HTTP Session Authentication approach. The
  4823. <literal><literal>acegi-security-sample-contacts-ca.war</literal></literal>
  4824. is configured to use a Container Adapter. Finally,
  4825. <literal>acegi-security-sample-contacts-cas.war</literal> is designed to
  4826. work with a JA-SIG CAS server. If you're just wanting to see how the
  4827. sample application works, please use
  4828. <literal><literal>acegi-security-sample-contacts-filter.war</literal></literal>
  4829. as it does not require special configuration of your container. This is
  4830. also the artifact included in ofiical release ZIPs.</para>
  4831. <para>To deploy, simply copy the relevant WAR file from the Acegi
  4832. Security System for Spring distribution into your container’s
  4833. <literal>webapps</literal> directory.</para>
  4834. <para>After starting your container, check the application can load.
  4835. Visit
  4836. <literal>http://localhost:</literal><literal><literal>8080/</literal>acegi-security-sample-contacts-filter</literal>
  4837. (or whichever URL is appropriate for your web container and the WAR you
  4838. deployed). A random contact should be displayed. Click "Refresh" several
  4839. times and you will see different contacts. The business method that
  4840. provides this random contact is not secured.</para>
  4841. <para>Next, click "Debug". You will be prompted to authenticate, and a
  4842. series of usernames and passwords are suggested on that page. Simply
  4843. authenticate with any of these and view the resulting page. It should
  4844. contain a success message similar to the following:</para>
  4845. <blockquote>
  4846. <para>Context on SecurityContextHolder is of type:
  4847. org.acegisecurity.context.SecurityContextImpl</para>
  4848. <para>The Context implements SecurityContext.</para>
  4849. <para>Authentication object is of type:
  4850. org.acegisecurity.adapters.PrincipalAcegiUserToken</para>
  4851. <para>Authentication object as a String:
  4852. org.acegisecurity.adapters.PrincipalAcegiUserToken@e9a7c2: Username:
  4853. marissa; Password: [PROTECTED]; Authenticated: true; Granted
  4854. Authorities: ROLE_TELLER, ROLE_SUPERVISOR</para>
  4855. <para>Authentication object holds the following granted
  4856. authorities:</para>
  4857. <para>ROLE_TELLER (getAuthority(): ROLE_TELLER)</para>
  4858. <para>ROLE_SUPERVISOR (getAuthority(): ROLE_SUPERVISOR)</para>
  4859. <para>SUCCESS! Your [container adapter|web filter] appears to be
  4860. properly configured!</para>
  4861. </blockquote>
  4862. <para>If you receive a different message, and deployed
  4863. <literal>acegi-security-sample-contacts-ca.war</literal>, check you have
  4864. properly configured your Container Adapter as described elsewhere in
  4865. this reference guide.</para>
  4866. <para>Once you successfully receive the above message, return to the
  4867. sample application's home page and click "Manage". You can then try out
  4868. the application. Notice that only the contacts available to the
  4869. currently logged on user are displayed, and only users with
  4870. <literal>ROLE_SUPERVISOR</literal> are granted access to delete their
  4871. contacts. Behind the scenes, the
  4872. <literal>MethodSecurityInterceptor</literal> is securing the business
  4873. objects. If you're using
  4874. <literal><literal>acegi-security-sample-contacts-filter.war</literal></literal>
  4875. or <literal>acegi-security-sample-contacts-cas.war</literal>, the
  4876. <literal>FilterSecurityInterceptor</literal> is also securing the HTTP
  4877. requests. If using either of these WARs, be sure to try visiting
  4878. <literal>http://localhost:8080/contacts/secure/super</literal>, which
  4879. will demonstrate access being denied by the
  4880. <literal>FilterSecurityInterceptor</literal>. Note the sample
  4881. application enables you to modify the access control lists associated
  4882. with different contacts. Be sure to give this a try and understand how
  4883. it works by reviewing the sample application's application context XML
  4884. files.</para>
  4885. <para>The Contacts sample application also include a
  4886. <literal>client</literal> directory. Inside you will find a small
  4887. application that queries the backend business objects using several web
  4888. services protocols. This demonstrates how to use the Acegi Security
  4889. System for Spring for authentication with Spring remoting protocols. To
  4890. try this client, ensure your servlet container is still running the
  4891. Contacts sample application, and then execute <literal>client marissa
  4892. koala</literal>. The command-line parameters respectively represent the
  4893. username to use, and the password to use. Note that you may need to edit
  4894. <literal>client.properties</literal> to use a different target
  4895. URL.</para>
  4896. <para>Please note the sample application's <literal>client</literal>
  4897. does not currently support CAS. You can still give it a try, though, if
  4898. you're ambitious: try <literal>client _cas_stateless_
  4899. YOUR-SERVICE-TICKET-ID</literal>.</para>
  4900. </sect1>
  4901. <sect1 id="security-become-involved">
  4902. <title>Become Involved</title>
  4903. <para>We welcome you to become involved in the Acegi Security System for
  4904. Spring project. There are many ways of contributing, including reading
  4905. the mailing list and responding to questions from other people, writing
  4906. new code, improving existing code, assisting with documentation, or
  4907. simply making suggestions. Please read our project policies web page
  4908. that is available on the Acegi Security home page. This explains the
  4909. path to become a committer, and the administration approaches we use
  4910. with the project.</para>
  4911. <para>SourceForge provides CVS services for the project, allowing
  4912. anybody to access the latest code. If you wish to contribute new code,
  4913. please observe the following requirements. These exist to maintain the
  4914. quality and consistency of the project:</para>
  4915. <itemizedlist>
  4916. <listitem>
  4917. <para>Use a suitable IDE Jalopy plug-in to convert your code into
  4918. the project's consistent style</para>
  4919. </listitem>
  4920. <listitem>
  4921. <para>Ensure your code does not break any unit tests (run the Maven
  4922. <literal>test:test</literal> goal)</para>
  4923. </listitem>
  4924. <listitem>
  4925. <para>If you have added new code, please provide suitable unit tests
  4926. (use the Maven <literal>clover:html-report</literal> to view
  4927. coverage)</para>
  4928. </listitem>
  4929. <listitem>
  4930. <para>Join the acegisecurity-developer and acegisecurity-cvs mailing
  4931. lists so you're in the loop</para>
  4932. </listitem>
  4933. <listitem>
  4934. <para>Use CamelCase</para>
  4935. </listitem>
  4936. <listitem>
  4937. <para>Add code contributions to JIRA</para>
  4938. </listitem>
  4939. <listitem>
  4940. <para>Add a CVS <literal>$Id: index.xml,v 1.3 2004/04/02 21:12:25
  4941. fbos Exp $</literal> tag to the JavaDocs for any new class you
  4942. create</para>
  4943. </listitem>
  4944. </itemizedlist>
  4945. </sect1>
  4946. <sect1 id="security-further">
  4947. <title>Further Information</title>
  4948. <para>Questions and comments on the Acegi Security System for Spring are
  4949. welcome. Please use the Spring Community Forum web site at <ulink
  4950. url="http://forum.springframework.org"></ulink>. You're also welcome to
  4951. join the acegisecurity-developer mailing list. Our project home page
  4952. (where you can obtain the latest release of the project and access to
  4953. CVS, mailing lists, forums etc) is at <ulink
  4954. url="http://acegisecurity.org"></ulink>.</para>
  4955. </sect1>
  4956. </chapter>
  4957. </book>