From e5fcf1ebcf53e9be4385f04438694648c00bbd5e Mon Sep 17 00:00:00 2001 From: Josh Cummings Date: Tue, 18 Apr 2023 18:13:50 -0600 Subject: [PATCH] Revisit Request and Method Security Docs Issue gh-13088 --- .../servlet/authorization/methodsecurity.odg | Bin 0 -> 38248 bytes .../servlet/authorization/methodsecurity.png | Bin 0 -> 186701 bytes docs/modules/ROOT/nav.adoc | 2 - .../migration/servlet/authorization.adoc | 2 +- .../ROOT/pages/servlet/architecture.adoc | 2 +- .../authentication/passwords/basic.adoc | 2 +- .../authentication/passwords/form.adoc | 2 +- .../servlet/authorization/architecture.adoc | 68 +- .../authorize-http-requests.adoc | 895 +++++++--- .../authorization/authorize-requests.adoc | 183 -- .../pages/servlet/authorization/index.adoc | 7 +- .../authorization/method-security.adoc | 1539 +++++++++++------ .../servlet/authorization/secure-objects.adoc | 143 -- .../servlet/oauth2/resource-server/index.adoc | 2 +- .../pages/servlet/saml2/login/overview.adoc | 2 +- 15 files changed, 1794 insertions(+), 1055 deletions(-) create mode 100644 docs/modules/ROOT/assets/images/servlet/authorization/methodsecurity.odg create mode 100644 docs/modules/ROOT/assets/images/servlet/authorization/methodsecurity.png delete mode 100644 docs/modules/ROOT/pages/servlet/authorization/authorize-requests.adoc delete mode 100644 docs/modules/ROOT/pages/servlet/authorization/secure-objects.adoc diff --git a/docs/modules/ROOT/assets/images/servlet/authorization/methodsecurity.odg b/docs/modules/ROOT/assets/images/servlet/authorization/methodsecurity.odg new file mode 100644 index 0000000000000000000000000000000000000000..8b5ffa68013dfd3af1d9bd7baef81fed2d713a1b GIT binary patch literal 38248 zcmcG#bBt%fw=eo_+qP{?+nBbyr)}G|ZQHhO+qP|U-u&*(xyegT&ddGdRd&^0sbtk! zm8x9}_1W@LAfTuK03-l_o0b137leL@1^@v3r~c~#SesiLJGt8#>)Y8`nH%amncLbh zxY!uc+v+=-JJQ?Q8QU1y8ai7W+c?piI_TS(nHxIF|Gx(OH^%=dnExnYTN@K|Q)h?& zHIySWgOjbTm4Utk!~Y$ZiIuIslkxv8*FQC#|7Tg)|BZ%rwsy{T|6%Iwu+z6Ow)!9B z{dd#UH#9W1GXA%ow*R#pkdTo7YcKtq+5aif|0qW%cPnE@dN*sUV{Ki>O*UlTUb%h+ z3iee94N}qZ1O{0OUvlf)geH{M)%G4YLga)sdC<@zT5jC~{M*lM3QpRexI7X0Jn2cB zgDDPl7oe-3IyFEf+4EQDrnA-d9&N0+1E<|=mVa=fUywpW7w*@`q^2j=+s&|UPU0{z z^qr`9z%({Ra5jc3(+r&k=QsmLJfZ`q8k(pF6K(=3Mb}f5(PaK9M41&qmgfXOnXOUsH1{O=x??CnbL%@}w(4YBf?f^yh%9 z_+jO7lO_W2a4KP@xV5b{J2y-e{8`3(M!=Y_VceE$Yz`^kmy9%Ttk`gvD~z-e7iDc8 z*K`o45nE{tjpkwo=Uy6XvI>be1*Og^m!JPNgl4Z)o&8hxC!Wr>bL) z$h3%O;=`5e7GSQkBklN*SPmUQ{tAw#q+5awsrp6SCOn~kh;tWtoE2tAdtJFyQ?Dd+ zu+5>d z;KbSUn4KnUkVds zR48?~eY{soN%p>rhOfg|XCVVz+dTw@hkh~f*xA*0i7kbV288E_lO#G77YboCA&%N` zQ`Jftb4vMElxm&(O3K_b&A8%M5{IuC;EMDdXvNkNy91vK#D%3^SR^*T%{3MdQgYAWSw;C4JDhYg$V^8MIo46RWRTYXe%F((iEf9hBuNZ9fnXucpakVkOf@T zz;gM_|6{J*%}1N8cLi6KKZ6(P;6v_tkDFrA@wF^*VN zLqk*!*qI9>xfB1>big+xvbLF|P@j*5vtGCKLs=eWTg;<$`I5BYII;%;Cy`D>0q3~T zTBt(Kz93l*@9Bq1SAT&G=COIyjaBln;#p`i@2g2 z5^pXMtV<}nP;ik#D9ipTJZn$&aA;01Ier;SJ#x~#R@tg`}5=NxwEjX$C| z&5>-(SaZRr(gb<}-!AiBAoFupQE{8SW{EEIe>pCV_9O`S! zf>#G<`88wpxRZ`m@q?3tll`8lDZ?!=!8Eh)TMK()VK#OIxwYbd`UnaV!H2XjiLYj;74s(!5YL!@M?ZLV_6m$s7maCm zNR|;?V^TR6t4O$Z*Oyn#q#q_Hf{5#6FD}|qFGivf%w5rK z=hYd>9dBj5(k{?2 zws$ll+ymMX`i*rpgUacAj|Ro0@f~KPSq45F=S$o{o-SVN5Xm*OeqvN z(yD_cj1Q%)ByWaLLy`N#FcD+^AO_1RLa42|^*jqyLCY3)fHH`a3c8KeykOW(ff39F zO1(*o3YCwQ2DKq_mJ+ry4TPp?+#vpNpr^V}fnw(u@}zbL$ltQ*y2$Oc59iKdLX{TG z-90t6T`%F-nc(4Y`I!~Om-s}hwznSKuiM_gRMSf4BK7irO!3HEqE3<&W1fR*{ikna zJcu|IYR(`RqGz*)Ku}gyT@8NH=*$M$WVrYCwm~3TsMj642(eNKz1$(AJ%q=OU4Dj% zj$Xs&o+3rews3@Y(*KGQv!27{&trtoy8FI)<@n&=|?ULY|d+{%U~M7M>a zgp~d)exroqDk!*QLIQBEF$pVlzFelz?5-z-b80?zy*4OTho62(RC&qFOWHl4hGKJ| zS1H0)3f3Hx0IUZi%=@+!htgE4H11{OBERg19+M!9AUqh0J%3{86LL{fLOZ zIH&fMn|6lS26DguH>l6n4Cbd)Q6<k1wjU9J1@IWNsD>_V!~tG?-=9pvrDTgxqL z64?9}dI7NsyKyqOv!yBQ3e(3tS2pa1Jpb-(!7c)3@WF&`X}+GjB$r3F6R5BSo{%Je zvWxDtlf6c1Ez=4{T8=H$5}|6OzNVUDf#{Db4_Q>It03Ye1lmJ zB!B&2E>jdURMTaf&#t{~Q!8&GRyp-Y!&J?<$wiab^Bj#_xuaX&5GGuD>@FG{QF;12 zmKpug8KrA-z%FaBCFh$q8Y*x)Kd^Ii$1*u@4O8uNaiVfzKWW zTDb`lJf`0SmFA_sJ$nixrzE*yrED7SVS+H^&M7E^#9aJX%>4HpH-ns}-&8$a40a_o z^zr9A_L%uPod~H~VjlO%gE8;PU;Z?S`6;s|&&*2@Uan9h@jIX5tV54#&rOE);IN_hiVY!0ipUway($W)}hGupN<*>}g8?*5$ zZ(beem>#6W6rl6|(XA}P`!fl#eXd=UCfeJZH6!O+3+&TtsHv|4WlLfbpX?np8K3sg zIJ=0=!%WK9lVd|Y?^0YGOPwaIU7ltl_9)Ol%9-$`EEd|eujAY_F5MMT+tHmtH$H=oDFOG7vD3m5=P5$0VzNRz zbRChWD6Xg()=I-PA^1mb?+!{;d|8s`8zAQpN$3m=TwG#9yg!nERGLCnO?EuJeE65& zmUJ+k&#s0>A1nz7F6f|Wn-FdsWOk;6T=nj_%2SePf(O)=UmNf|k~0+})r0$iyZ*XG zBz!I}+eWq)G;`QqhDDqH@_TjJ6ARdV65`@r!Q1kH(TnntY{S;_MX+<{9eDl(YV+YI z(}K%sgJ}D$(e`%eIpS8|y2aBk6X+H@wc113e^;lRYGMiA@O(iPv&)kur%<+j6Psmv zefsIJ^y#Lus%l7Ds~L6lti+0Zk3KaM(X+(iT5>+g|E+QM+Jv4mQwUe1>g&-)?p+gX zh2OmY{1N0fJ+SVy@j0U$tIGZet)3IbOVLWf!$j38|C_TUL+#|f>fGCv+sTkrO%}da z&Le2hFtJC{s-+O!PUS@;sVumJy8qjE_`K z`QMSZo@@9BWcy!mWRdK&8J|0yt2iBtnuk}=rtAuSwcYd1Aqtd{zv$gtH`ryIxq6-) z)w~U%3RQHKfoofX8Ju9PB;x4k>Sc8ae0db09*$X)2EHj%}2JX1Ok>&dL|(LFzCod!KmQSGTPk(-gg)C3lhY z@E|d*HZFLBI5XJ8gtnf0K>Y{`u9{B4 ztu}FxZL95l?<+3_0XegHBIJ(%05m%T0RKDt^4|sSF#iH~Lt7iC|73XnMef(y=Lwr_ z%|E%N^5zNUw4xD!*Bo=#X}1w)M?<;x5!suqFZ+54@q;vC%!CUvhWK3fULFa69a5iY z5oLI_&7#VU4H67OPvhR+9^m8UL?319Mn3C}qbmnQJ$+XG%wQHlb@j2=$BRV$F;lho z9i1VyC$fg;%7&d%nhYb9>YbOQdhm#vW*AdXHGdYubBQ1%&Y|7 z`Ha}BE*c&F%6UmWSe>E6s|4)!+lcM7(_5WG3uuikE~rVlR2TjE!BHaF;h&9 z3*Mcfr}!7TM*l&ot1W+rZWgrg?nx8lQ%{+&6wI=Xzu25X3EV`=dBcef`G;W zI{Hnky2h}HaqdSC$110wo^ow(Us(@aKKW za*!fP)J<734cV5M|LSajp?RY6G`lt3hHdSpPpafq(Iq->6Z)+<(dYdQ9slN2a?Hh0 zLR&q-Gh2|lwZ2}{V3DzvT|C;XDW^|XW#No2nvcwiWdkJvZMZK99Ug`RzC+;Aa%(zQ zQmpB^spR?d7sONLW9#)*AWFh(+<8IS@2r^7%lB2;phVj?uJyoo>9d5DE3SJGAcUvMtXD`Q}#bw>m_M5 zu-f6zN*m@cN|=!t{tw2S*X>gDqB9YJ1v^e?s~I&06dIp4_Z$ue9h4>nMO8>W-)QaU z-MKaQY}y}!j0`$)t;xj9>V+K73e1H`ah&WwQ3l~tZmW;C2bd^wMGsmXue@9gGz}Lv z4~iSl&pbm!69jX~z(k={xaOxr&Iwt4y75r9hl$4~A=K;(-h&~b2$?lMJQOcnVwpuu zKT*&Vm4=kLOGXbj ziw5G3ko<9Pq0e|`B?X>y@8eYw+nhgda^lJr$%tKV|e)2K+zyG|rm;v-pL zTfE)15yAX1=*HZ=z@DhE=d##Xj!Cm|bta+aS{?7Nkj28_#E(9fpo%f`6@cIriww}r zDsj?YP)5%qTO={VPEKf(udg}-eZg)#AWa+0xIpW$g96W>{rHT^DywN!cB>`A9M<`KY4#+sg#fYs!@LCpk}7 zh)=kKF_=DNw6(n=Bg_IJo8uaG!RSk}866J|oeNcS`eO}nO_s&C!Y}GQ@?d+_A>0`W zRLBS*C+ZIj`ZbX&y?x0L#a%Cm^Li?o$sxZRkS)YLSAc5w2ml*L6~A&~%rNz$?)cy83rMMx3aSF6v87FoqT8D>MJ5&%U$NTaDRU4;%-@9vr!X7v@ z>H#5Hhx~Uya;9wa;>yXaG=cM2ug{4&r0@HQ5)VI?PO5mCSxiSFT9S%G&|Z!xf989h z)B*jG0x#_6(zAEnPxxqx>#0p&c#r{YpdD`&)3fK#HnKu(2ByTAH`)O)t4c2wWNl&S zj}_pgF)BoXm`dolairh<^N8FCJTBoyVZ~6Q{te_YM)NdUY2xYD1%I-L2xzM({oz+& zlGhVGC*r7UA%nKA4joW#BnypL-q)l!T~5@{JErV;)xU8+ZbM&oljP*PmA8x!(iaxp zCt|3kYZhy+ge&3~*3{HwB&c-sKE2-Pc%Vuyq^s=Jga36jGBXP&Z%IwNJ`jQ6 zXIiW4XyEp-;M7F0h}MqH+?{1&hH>eTrCi0gQWT-c)GNLCR8MZ>8GgNRVq(0*J_INZ zN?$NV4ZZ5~ZXr-{mt%T6AC&U5u-LFirO>#tC~dk{ zi45eqZ&?w(FLyr}EniMVNWwEi_##CRfeiG9Iq?bxZ08fks&3hU6tFZ_#qm*8Wt$Q- z5{KhI_vZXP-Th15zt6Q#Xkcx|Lu6+oA<+&;4r;b(N0)X-C_Bu!#jrWM7;qQ%dJ+u2|6Ol*IFh$ zoZqk$kEF529r&G-)cm9IbKfKy3e-2mT3nlcH?Vck{saXc5Ldq|nN{S(!Mt>nKxat0 z8I!&SHd(nF9srQFGV82O2T#u=c~pfZ8u+6=e$CWz*?JD?5tMag?x#gbcx%*D z!J_0ua#X5diY&F3ctP}r43c+Myoq_Od+{kJ3lQUzY*S_1 z-LL5Us6(f{;Q_(z751#&ppU8qah=iMPxsLTh*TckE?pM0De1^28w&q{0*{TR0&&^u1{B8hc{=wH5H&FW-1mzj zZL54?a_b}4!HvLHo8+yD%eR%N>Ul0e>w7FNk`#vP9DVbaXk}5cK*Ey!RX1xO809!o zw48KO>uD1&LxWiy4V%LuVRs%-N!Qg(K&qeA+MPa&+&!s97f-wPp=s=$^~p#zm~Cv{ zV}%!fAjf5|SLaq%=lm#-xNcHSl!1GgupEZD!7-o1|h(K=YHX%Nwr`}Q_PpB)QKtvdAl%i%2#PIH1sy)cHPube8rt(u`DRA z{_}u3$ZN$oe>fdGRL`j*|gojPb=V;$3%al|0Qd;>^tK*4+uAs>Ki0o+5B@^|CrPj6zn-sW)O z0IdA}`;qF)0#eRYZqSXusNV=6mP-Jjt+#b$W2gWiW4$}-RYU_;E}^I;IioZqA;l1! z-nBD>&bC$tw<_5a?1pZb$J;i`Gz-x!xcJ@(^X5oTkj`lvmtOL_&wcdiozXPr9RyY2 zM(zxZOb4O_oAB4q_N{`8KR%tceajx4)N|LNY*$0a3hCAqJ6GX=os32%)Z<`wy~x-YJ;a z4MbH^;}_cVv24S)hRQV?k^E~Zv)mtK@};|v?XaO8yribLsSM(WLIGkjD+B{S7Qu3L zRrX14*HE66+YiMPE`!R1VHoj(iJI0d_X}KXDC3o{lc^mrQ1{Hwyi#6g)V{tw34?S-_66^XLz^OIJbUp9me(( z@`qmgsh^%nXpqBtntYhhV0O0w2`vem!uZ7Yvk2U!ZsbpZ`uoZ*^)Px%;tNE3jNrSr z3svPJRF?g%02b202)Dept5(fcf^qzFZUSZcxoN)aLKWk|x>z~A7JR4ZDqOh1*y-CN zCe>&k1bX&8T~z|)($b(gc4Y-=(U3?q$WFR&4c6X2`IADN^|rp6kQmXa`S`GKl;fj| z{}6-|^VpDfhLV6^6ix7vN!LBrTfF5yHo<_X2EU*7?)hc9NDt~0*3jM;IQr6}G_ zTwRSdRle1nvaj3BqW7pCnL@ToXV%c&+LCA2xSk>F61+Z+i#0cc4=QV2Q2S@}&M5gQ zMACN$Im|~DQJn~u;}OP?MHOE&R_=%jcE2aM3MrhzOS!4=i2vd|NIMe)joMshbIvA3 z1QMK%gInsLVW{vNIa`hK37YAk&qpb;4-GbOUxF*)Q<@Fc>XGC zm|?1c-8!Ux31dCkMW%#IpP~3VRWwm9Ij9+fKq?@(%_7t!o##E3{Tx(0@ z#b_)w_5pahlMutE)Qg{`g!V%9#VgvCmx>VLa#gH;^GNo2d{CRefyj+Tdy0~ajea05 z@CaoA@8Y-a_M+N zwu%KcR|>)ux@q zBiSS-F(~N($mfW%5@U6t=0J&cUikyWThziRQB(MWnvTe+49Z%dn+9VkDrg$@dW!H z#E7wzlevxQ|H6!HYgjrSaG-zp^cF;BRA-b|vxXEc`d=^_qv-Hv;t zHMk$G-Zm4R!vZDL-!HA42m{o)PA@J#F3vV~eRMyc7Lj2jI6CQ)_-KOV(m1!sraI}O zrcZ`t_Fp%8d+yhxINB~8C?1$#7)arT&xrZ^?Z_)PC$kI3_eIZ5yFL%(`VS<;3!V%_saG+cjsd}ScFxZUqtG=Fq;NPnqTC{qs~T{x~T z&h%_JzPzl8!EIK%7_8lVRwB03F6A8VbHZBex;U=;XvHCZ+DCb9{2DcC1!HXQAa#32 z<_#7;{NXYYGV0Q+=o>o{+kU?-Rsxw^J}I#4+nnH=Tchm;ws7Nv^kIxCF@ z9Tp@+7Za(-CD#OM&+Tv;%j=fu7=c8yB!sk2dnePs-V>?YXBsw0fK zJ0ChW$VjdB=ki?xoR9)%5z^<;+m$PVF{C7meR2!|=vpnL&sqYI-u zeGJ)l8|o-}PquJ0mBJg8mGT}+md-5Q%82l4WX}}rW{ecoV{5t}4bOd)#Lgib*;N0) zdChKoUWNrmMo2!F2%OVJBq+rgkF096W-&QN%#cBtybyxs_BRM?{?;$JY?V{~ z(ZHSee>l_(m&um3G#egwDMD(%Wc2hSPdVlNf*>ZzK zFbB`Q2J z9BId8h-YiB3%@jYao9CwNORfuLc!wz+}IFLEs#f3p6~~7;TNNBi1*>uF}%2x5m3^b zt&z~u6O{ZmV|+b&tHL?+{G#*M0@iCk=405NXi_*kN{u@;|8+>9R!3?HPjV78KQ8Rm zVqmFdy2zp1XXHRJ7uPsecyOO_c+?m+MM}8vP%cbyCWCxJ+Tsd&O$sxL+s<<#&SCK6 zqZ3Pr44x>TRhuiF5czEn9wL&Z*&$(xE>`0oKPiZO#CVDSn;F?{YA1=?^@Gp2nFOi{ zvMCDSy<20}M&Fa2i-8GjN-4!p&!=6|h z3YjaId>Ab?6(qevQGb-&G0QKx7TL~zA`N7?lNFRQ(~T#^UcDo}!kOvJaXOtG!5(#G za><>&=P6&i^v>UsHm1@#={lMSq&mFcwe7!5_A2@dz01K?npDrv@4CBE5R?MpZ>!t4 zZx%arGq`(j)_ffO*N(=mlL2D2PZyOcud>O!zpy~wz@0b12{Q1&t~?tw6C0d+EBc<3 zmmAPmSaUw#(n-#5M=njNE4h}P3g>kLyir@D!S81Ct!eQ54;ofpq>`F75 zN_LvhRf%D~7Vet3m8i}?hSIR6!)@5e5tNEqS+NiEHy9;lEoJNro0>EZFZ+QFMx;Jb z9fMNVvV_Tv!sc-Cp8;P+pCOBW%T%fER?#F7FRibVby#_Fsd0-yu^<>ndRbo5R}fD@ ztUNbgg~6i-nXO|HqdP2B-x&WflXpdWyVu|VKsn`qnaTeG>H3$ni=^oT0RO4~!PF|7 zIa?dp=$l(PGC2JgNpELk8ZIv@1_zD(AM7QZgt&+z008`t1p0&o`S*&(S&jYI@hvZ{ zED8z=3I&S-hlGI&3xxrThKU4=j*bovLk5RVf(lQBj!lM%%Su2~tO^i)WK}kl#O3lp4LQBd^$i>M_!_L8uh#>@z?~TVKK}jn@ z$u361rNToj^ov`Vja!M9LytjFjz&<8OGtu4T!l^ELI@XDmK<4_jm44$!-bzvmP%5K z)!2kZ-IB{jQixMgoYzZ`NL*Y@SXxC=LH&=6kh-FTs;a7}q~UK>6JbqfWlduh4JR=} z4-ErzEkjp*RcRwFC3hhYO9M3rGi_5-QzJ`fTYDP|2RCOcBM(P&H+MG#LO)dUKzyc1 z{9kcIbiw4mA}DwgS$HCu`Qm7VQu)LJ*?y;RX$5d8=CI4<@u(E=>W2$U`-?~=ODYA4 zD`u)_2P>;(if9xnY3GZYg#ETkl61(@HVXV>k*(|)rRtt4X;32LQmAH9reI#D=o?cm11mOZ0=lX>eb=wTIK51;N$15?U$tyRO1m4 z?iHM98dz)|+-jQG=^Rq#8r0z(->DNjYLzr=oxA5)vg+A*708PdCybXWMOycVvRj`q zRMb7l)2`UXbV!?e$&BgAjdRCY^ugZ(ZS^%rf=7=wSDbNUx1lp9eqLrwpg? z@UY;J%;>n7$b_`G=!m5F=;Y+&ps>P_(3YswqOjD4_?Y(8%+mObrkuRY?EK=)!lt5( z*s`Lm!otF$ik8ZTj)v-@uGXsd_BOwm{?OFXl+2-jS0OP43rR&IX=Mw!4I6>oFZo&h zrDfwq)$`R2!{yCu_0^NjEfXyrD`lN~L49wXeM6o7o3;Ii?W0G1@d1OKjW5-4uU%#R z-Am&G9rL4IPb00v!^1ywM?i&G=>Q`@Txlk4m2Ba;V{OJ|cCcPneB3)^?Qd%K(a z7wgB*&&%Wc+o$&jn+{v=-Oc0U{q@h!&%dwW@87>|yx(^KfX*KY5kY0Q zjq7et0Zo-2h8`vGnJ=zl#~~yuvR*UZndO!h{8@1bP0Z~23+1Ae?nP1omL|4o0N-z> zbuP^83dlS>ECK?oS9+TekT#4f4tpv4`nI3;2Ou-0wZVx993*_sedxRO%c85)BAnERON$o-BNMTF@^a zQI|m(^bM*`nXMe@$TJQgsNzS~$|XZitPFi;CxZ!$rsqrrKte&v!NkS^sPm6Sulr?% zf~u)N$AuA2%xRso$A2a!9{Qa4{p(}%!xt1X%z^XXGy|4OhKsdJ61I+CADzz7BpF{d}1Nl>i63d)%mM zJ20YfsSPObT8ll$*tX#l`$E~Hs@!{R1GQcYFzoY~yJaq5==aR~#t4Desw6UKjlxMI z7UNW>$KxAQ{VDgO(zgkcVGb=Z(8a4f>`_1CPR1XAf!STsDGsiSx6+kf&Z;Zr-3L~z zIPWe$h%kcW$=68%Y<<|fbIg(FXrw3)Yv8O7>+0iX$)wi=F(WYI)O1KMalHM~Uh=4f z*F=#*_q0iyK|L&tcDtkfOXCD7=irUw-9k5CR{wyPURC&O^w4+Xozcy$m)c0}qfzeJ z?^wiiOD!OeCkHts#O~VL z3$FG^z{)`w>FabJstjsFJh9(KF@UEr%C)$wor=G*QP}ULxv5a>V$NjUsn%+0&fnPC zMdB^H`aL2rdxTujvNXzd&V>wx1(F4II%ukZ(WDUUcVM2tJn3wbD^_s(2zvfH@%hk^ zHU_9edp%@!3#3N1ySnza5F)JzOov7tu%Qyt%90AD1v{jhr6|xAznSB9(cT!qB2K%0 z+**5OY4D_Ga?Q!~q{&Wiz-`XTYTUkQ5-oIk#Kx+_SR;kS7sAR?NYx;>F9Kt=D9h~XXv9^ijDZP@8StoC-NT z8U$F_*4EWufpy+|I;SZtT6_CUM73w$Y>3|J1sZl_Cq^lz;P6C8^do4U4tqA3NSsHX zd4C9@ywhI=YV7rn=v!W;_)>0rm2R}y8@k^qN06u?!jATp*KhOfsAioZ&7iI;_zeX!SKl2UrNPV1HenI9K|*2E{-lEpXt# zoDb-zop4S&jU4%9Mdwu*@`@I|Wz# zyNc_johA2%1yjc5KVNu!>U^n(XDa7K#w14DCRronas)Qm8!yB^3&@E}iEVCc=8}dG z6fE^InpjJZ(v~h&eX?}eCEN;g8VN<_WFYd`D-?5-oaH@+c1!8pMMac23fL>cN>ZR@ z$&b3vgt=@qMmc(55jIr_aC5F7ks~U9O}x@}vQ{xp)@k>B!cVxnP*m+z zuyl3M9(2mGUm_A3+hBG2?+uG?U$nxW1;eRYoh9}!W%xqio zH`fMQVI08W6Y*rQ&_y8#d21`{Cf7LQ{7q#gi%j}OA~_f3hggzcqnk}OHOV(JL#Xb} z>W#3W5jL2($>`is@Vr5^2`O7zHBe7(df@X_^r!0X(OZDnZdFFSB)Q5L$V>VpW4p=h z27<&ivp~;D4{oUFS5R7NS2?L)xW%*bLY*nLblNFQsI82kLGAlsQ1(gfMh(#XFc&(b z`~JwQXfD!@)IJpb;VgrC7&_U3U!oVdMmA_uH8IDVytz(V4WAxyvC@d!%vmO4GfZKX z600>pR!$zJyGC(8nK_@Lb+q+SLfWuml0&^`z>WrXqz+Te^A4?}&pS8CXKLh>Gr5^W z(R`c=ZHR*KjMh%mZ>uC}6=n@#!$9|=1`J7;7>wwUtZZ;+dD!RGX4{r0rh7&X4fKo|s73G_k6H61K7b(;qu%gO<#H(d+prM)QdFe4g z2YZDJghd3KV~#~jh?L3uL4gt1s}V{bmg*z(q0xvSK$j)v6X(P+AR1x`QBz8yguygu zqVWiVhZKX)LAM$A!nsD-$Zj2##qQs@5SLhnIj{b)86GqqBSAw*G>#q025qOt$B)8{ zjaZ@>8D)K{jjV>o0Y454CHuWA#Wxtu`A#>A+R4oZtXl-k5dy9ay;twye>~!3c+Y6T zQW+nl;O_OQQTEj*FU3AqRo(;T^MRF48JiSXg6d55N=2m<3svt$fQ_Dbw>A>E>G-%qTYkHghBqhlM)erwJ5zk7Mxk*`h4wi&Ra#;5itQjdKF4`j zN7LG$KD}A0odO?}-gNf`AtqaeUUu7_NRvCBz<$6SFV;BGKhBC|bHESfV@Yi?O8X>kYvOC;Z_kDLB=)&r(g6Ny zzy96Y^_o4~FB(6^?AYpXPoTC2MX7|238DmfRrT?E>coV(=(xk^qK=d-A?YF)&?D^S zL+SXGc>FHDC2U!!7;5pps(v}+TF41ku1 zvA{aI%Z7Vs5Sa?upM{!#X|$tx9v+RIK@Db zR;aw7X*t#ctKt5kEt+YU&t(KT!ud}>`^FC;9cF=epYsu9S>>Fy~s1Td>-0X-BGe(5c8PlYEPX4hPyr3p0F{2 zD*ha`1MK?eV3&Py-8Hn$3-IB|vIJ1GmkylVdy8B22K&yT6waGgJ&W}W694^3_`cGP zl4Vqfy4U-2$9b!-s=G0y+p3@cRoH2asw7`aRfE*JG(U z&TISrMDOuQn&0^cXt`V#n=}6U;a-AL?!v zkrbliOj3h#u&5mSRShUvE(Xk~%tNa!e*-KN0r^&7OI7mjRbjwcTsY{}yH3DFezaR~&5efCc-fn%r4tuw62>#}(?)Cl^6aq`TS80X|wPgjn`!(vy zaH3kS9se+=O18QoB<+V({J?k%t^~;KMGY|fQ$V1nFh`u9NfEQ`ds;Rj1CZW(X1v$; z4@Fl*J$^K;2c5KoBR_$u;~b4Kz~Ymecsn|b3@*S5GzhE)fMN);?frAIA>olX+z-O2 z7UL9;i3Jk1!(=ee1rqZZ79U9ygzf5Ax0n)v(y~^imG(Gn*jlHGiNATYXXe%fc$Q}#`-&9BG#U?Vk4 zgWYs4NJL2D^}DVucMeh7LhaIXWLM1M(e5!RGs+6CH-NWG{938oDJCZu!v_;l8`V(4 z%1KHjXXj%W?s{^=(!BCm9QCsT&jmxQ}<$!WhBH&P7fIw5XU zXCow-nZ}TYnNG(t6tgnBIj)6%4`M`-p>VK%e>doqCuBy&BNcJEA|x6DE2!^T+5(yY zKO0(ffN&e}66VaMoJfW|HVMwlvs4S33~`si3;E~lKJ&Z>ITg&5ja~nyFa~w0=*%No zP0D0wZpRNxUj?VsS?V?PQh=^g{00#Dn4|i8QUM4B5}7Osw-*+oWm=w$P1G12KSgwY z)M(<_^jYCy$Td8I!3#NS`%L;4uYmot`L#n`;0)W{Y;C!J$%xccFQ-^giZQsnN@~Du z=VfVvFIYp2YS1cLgoF)pgvgr6I$?(%<8?`dw|8Pt`pqpE@L0i=p~baP0@Kz&s}X@g zK6@Tg;`9{)FbPonQv3v>@&j0jLZB3+rDf3jAbjc}4Ta2w@H5B}3kVg&jXx{mLW{$L zgor|*9U+2*k`S09f_P|Eg6@M1?9ijQVi*KOF@NO)Mlkfv2|)|`WeEYM#Wg|nnZUG? zDykI(0E%a#U%|ht3UW%;V#eIW2G(BHRG=S~| ziiOjDs4_^_j!Iv}Eu=;i@ZQ9PTQrq2wB31)uSV!nj$U{V~oA1kWsNgvl zwjR8W*Z*oMVW}yZCb~}pXr>Rtl=yY?a=aH53{xO3KQUPW(m-qCFMkoXfGSYNqp#!P z(D{V4A*=$FDwWa=H8n|q21H!fnwZGUE-*7eHDd*F)CJVa*(aed?Eg)@vlQUk zN6U!+@}mF&zRb^xAh!b%KsbwecWi?<^+!!1Q~+&*)^|DpI!MRT8@JQ>iKE>)1gY|* zv6<-un1dR%{twpqoVY>PI6glCQs{CZoXbjp|8UN>0ZaiZ^3RZlVih$7_hO*)ux!W_ zIvZfhv~(mQNTT0_k?T4QF^7#eLji`g^`TaP(EyDy$4@vh5y;WSnQ(;L^cxLff3S(3 zo54g+13){lSm~g3%7inq%tED6DOT4s0iJ0C;<+*LbXN8lD|;e3K+Qa1H8IKb32yCJ3!#Xf&@sUXL!-8LaqR&5E2$1NcUat)Z@Zm=v`YpT< zy`uf(aVPtvfWV)Co1p+cvxLo81rRmKZv<@|r$etdk!umo&?o>wS*`lovann4-#NSZ zcYgG)r(}2B8g~DCGcx?)$Mo)BKl-C5-_Gyfdg}*&{P6qkxc|CN1$b(!_Q`Ed6Rm_1EUZp=3xEKzSgF7Voh4{9 z`4m8pll_RE<4{MM5GyfKzmddEPwpNX!cCRjhsnW|=yNxL0yw@6jRFwV+}5-L+<*Uj zw|;QT2e<6F|IhdDy!FFdciazT{N4NC+j;-}{|btJ$Gabaa^Cr`AAxxAPX`15x!&9P zhx>Qjf6Jf3-uwOsJMX{s$M4+_;z6E|XaxXu!Yve8*j9it(0+g?V^ZR7p9)Lb6G=Xh znE3Fu@RPCUv>U2!AHBWynQenyW!zggfdYi63P^OY&A<;o{PTw&{h6}gKV-~!@DFG0 z{trKN8TlWw3myGuHi35RLGG13lF8yv0p@K6>T4T7<4t91B%K;90jL9x8B&^nM?;W9 zwb%KVUKs@-dWV;Up3B2Q!9oh)q^p41+5G^2_|vMm7Z3!ji~<;STHRcWw{tIQ?>y=m ziPyDwpZvTdzs^}pfrHT>kRM=piD_;FLi z!iA$n)M{--iY}${Kzy<82UYtt^~t*A_~Nqgy=9fUr1%uwlg071WfAInuDT{6QCX9m zm{b!LuiY14Ta%>SR~!`|009C}fGJahCgchblqz5l+0EVH)hXZ{b@}RDQ;I&0Y^qG+ z{5sSG7}9?p2m!cT6YC?i(Ul1m>(tSeQMF~8)K64I)P&dW+It|jKB_Wm?-SgF-Bi}7 z;(ePAY^VsYj!JoQYgvpoHZC5-1wjGmegNGXy%+E`$3Y(0L?m$U!K-)2ZRi<|BvZKD z9^wIR{5?#LFOctQBa)(!ju2abL;Cajd5T5P5}>BOUKgDlQ@9dJsZ@~d*k8{ zY^4aW_rUE364lWMBDK+bwYvGvPx%&90D|rbT;}lrxgj)2~~81fT#;iU68g4Lu08UZbR5 zHKm~jm3m%0MT7NHA#RM)=fzY?CPBl#CW}3k$*gt#)qNFUG#GCrGbJY{0~=7iuafAm zCAF%l6ml>r#YR>qX)2iqtZ*7x^u@a#cXT|8if}qVIPv3mJj*cmQSq z>Dc(#m}z|G2vk3VP>0qd2uHuba8&j!;lzE`Lx3^!&BotMvPQ zm*p+<>r()F81t0ZOUz8v8_lSZr}V;ZT#nuhRi<#O^fuoN^t-TpL~)S zlR_GKO%4evdR4@+%U$cN<hTt8q96Wb zr{edieBj|zGyZ_B0PHXkV24P+%fjd&Na9@_Q1o?x^I_D9QNEd-ft2^VfcgPeMgc-* z1df6>Yv_%@9{m?;Wvz<(3ffN z>}@y7a>lT}?7lo~vcSe`RiL?@_PpMK&atKom{^2kt#u&o%ep27_Kn0Qm>lTrz{G?C zo0J@}i3maKm;o1C4S87Kr7~~0>yY2+xtk; z(%jDDiEtDUppMrH2!Qq#4WpA1P|0KVLUc0quq_SH1E`Cji?m?{Bq^Crot9wsY#a7v z`NfVV8=5=7lXpx@P)CLhTV4eqVi#4dnpVaJAWexOFMnDAG}Uee=*5gegGAPA6wA%o z9cXK&*w|Z#8H^o;M|#Zz;*4ISOwct@hjsS06w32?^86gLMC3SxUNM`^c}8J#-ekvc z-oaj;@XA1uu&b*>&}uZM8dD{`z4@X6RG#0QhswIK*4|E`)YzMknd{Ji6<|>|Ko5c_ zmudqn=3am)*_6n*u>@*6k~p4d@^Pc?Et5uVN4cIf|0|Vi<~p>5#v|bXHUOvsK268G zX9WbNJ#Y53ei$|NAJ1#fK-z-|FBqAFXiQ3&1UfI~YAwu|Cvf&Gg3D$DBrj%);ib0% z2qmszoz|+gs&TD5%sM+2(*PWm=GrzeM}R#O0>^sowSHYgie~Wya5$-sAa!+hdH_>+ z&GkxvZ11-KNCiGj3Uqp~02ClO@YlzC;m;rX1Ot17VQR_!0NUN5lkp|ZDB<+20#*zK z3oAfUzy$b@rM@+6bjkMuh|$myAVs-^DuAG?0AK`SD?348P!(XwZw<35mwGQClnStv zIfWdo5m*(d0$?aMN0iSCVO#;sD`G|%^Ep=lHo(3hyf$u83b2@a0rv3_Du8N9RX~qk zHKPhR^A3ZvGgfBjN_FF`Pi6*Ze9}CgGu~kkIO9@)!i5!Jf1u^?A4^sMTTpBO`!}J$ z(rf^x8K|!EQGn96wo>3`f{nY%`rJ!fn^)#iCh_W3S9Y+w3LKks)t!S4xUTuOK6nZ+ z-#n0k-B21$T5>A@*Z>#ZQ?Lfj%~s@e@XuI^4Zt)5t2_!I5DG!j(3n90Hty;SFiAd{ zywg11tA5}nfPCR9AbHUpa@Tzu(W+T$PavfL7XvYVnCbQdb+aLIEJ*>_W?+@4AK;g- z{j$_=SuG1(1mL~Ba1{`6E8rjVATTbBCoT0}fPK_zY7NCS>>{85nkCr)Gx`Bmh5%?$ z5EUQ@tpN4X6+o-}T`1a52bZP*Of%4J1oBf;UkoJyd~JYWDZtVRuyh;1KGdLoI}`+< zY=9-S0vv85kgft!CC6S|^9tY$f&yrkcrSp^CTTQsR~5jQ3H;Xvhh;LcCq5d@!Y^lejFL@E*omXEe^)0Xy1!tf4i73fsGnclVe#NI~ z+g?8730(CG_)~zO+5oFS0q}9XR^?WJW_uo`uJi~Q9tu`W1Q-F<*5PJLIUOs+glKvy z?d1z5B!=OpCMoseE*@XV97<&s;^&z7FOT3P~1uB7d1>95|ox^3NwtEHfsSGw)Q%Xb6M)e@@B_fA{s z?eClgM}kv<+;o6B48**8+K&PR&=HgrXfu#8_x`un;tu{JFaqG3CH4d04apjn+Xnb1 zZy1%CuP8*59m9gYc5~`PORwN!N3Wz+!4nf1W?>-y3{k~GpmJ>hR_*`4*`j_v!`ttVD$X6ondwKnR>)zS6 zed9aZ?%H(c%gFQFUU+Harsq#>-13W;kr(cL<)w}H{*SZkwnv;fyM5!cr85;EfR3P~ z>uJq7eFN9o5cE}mMHqoV0UF#!V3sYH5MC+7Qkyz>qAbENnQ!UN$GUp!1g#3}Akl2; zu!{*n6DaN`%LTlp9i5aIEFFeaY+@KQXJevPbEjR5WAcvHIuR}#Lz_BsFQeZ`c)_p% zfCPB;1MpI%KmptYxLWeq#*HQa)b_};+ka6SafVa++})2ndt%F@k=r?EIi-)>dG_kn zHzQwISNi;YSJ$82c;?N!+agaO_icQ3+p{I>O1@jV?S=JcN=r(%|M1R|^`-Z|9C4!@8(OJy0K}H#1~-ViLtc4JaJ)Dhd?SK1kLTu3XwI( zg0?DhyLl55`lsV9y%oUr1F#Apeer2G0nTnOEm?P(Q+n?&9@$AI;ibDv!_VG+=HmF_dfU1 z#*%ey_r7xbi4xA~?_PcQ`Ik06TGBRC0Rk8lnv|$a)CB0%iJ%>}TN|(4?Gx=efpV|% zNfo`N*4iXrr>k7zy#Rbf?=b?6sc1%rsMjdNI(zHTrrr*r!Pw1jGImK$nau_PAH?#F zSZK<@BSa_ilN7 zwC(L*l-$03%R7&5IkElfwzDs6y07H16Qx^9xBTL<6Q{RqIrH+y=k7dx?=K!bac0Y= zS4!@?`rL^UPyb*Wr2stF?cjyR1e$OY0an+R+51~@liihL++@;u9}<|e;!CvwycNLj zU<&qqo1TF&Jd7Pa!J9F5hQ4(svSEIQXYhj53aFu*fi4B`Gy~h{1y}(qXLXCRRI=L1&j=8G^cnW>Iq!Zy#R-|0*EBX{1ITeyMlSkssQ6FqX246 zA#e370H^|h5vX)`1RayUwi5ROc&l0g7Hb21p0m8j%E`&iJ-g&q06i?+)fFsV5d{DQ zSj`HshVFH0^u>Py0rCGO?Rk z2|k&>{L2XUtX4xo7!l;Y8+c3#9ED#}?w7}0F7wzg zrEUj8na6;~y`AlRvd&1LPIc^p3r!@^T30{lYb zJx}=ZLhHI0P|&|j3P3Dn+MOlL4}d3`lE%U6&w0m>(V@{~+9m0W^~HlT*OZ}@L3-=g z6%V~Jx}++=`@s+%4;7}SYWjWVb6-v(XfXCB$n`b@9p=C=X68OTYz`Q~>Iqyka5!f? z7{WVr^r%|z`?7##R)9q{1Bd_eNnq}ihaUP%pn3oDu{}ul0@e6=XfT&)21!4QluJoMO6P2i=d?_cOu6Z6kKs&(BA zq7=XxFadB=$8{8I;P9^irW;rRT&)1M3J?f|M~@xV=)FqH|NO9OuO#(6EKx5oU9<*U zR7a3r^V`2H3jr?adj^5i4>1m3?7e`sR0Z^SJs5%k0stFeX1UXWeH*m8nD~CGT$6M^ z@Vo;^9bO-!^;^c;XLJc_MkVH&eO&APaHu120w|Y>0Dg=5hE@RI=K@#-@cXad^PQBM z@OyMm#8p1QNr_I3tJIY}kf^PXOAJ?Xw224es`k}@@_sTdNvGZwudI)YSMP}^PS8}x z#n-D7pN!Y~oiW<20B;9w0}wdATnaGL1|V;EBhWP>h;0U9Gyy!V0Po`36TkI|IPO#2 z>Zr09ZFJI8n`$D|yLLaYw}Mm8(MBabx#_9+nhpE7+US!HBvmAp702xb`J!sVtDf0Z zA66BcKK}S)-@<(GFP}X0Z|{3WELH(-WFydbL=dY0Y9GON zkzh|!^ycKPPsAi9Rz&Ket14p3Vsy{k6J4wh0|Wr!San3g-aXVCE9c|e?)Xu}&q2h; zfBEG7zkG7XLremb>64F{d_MS}fB^a=?#)#Nc#jCegsDfp`vJWFvwM>Fa4WbK8=i`< zh^V9pppDuaec*}M1X=-VDmLk2IqHfHNm0rtHpRt9@7}zrETSe{xp{YNVtoXlk6&ZZ zZ3E=%mZkupu%mt+b=$v1J-FeMJMQ?-$3KdA5P6^T3E;#X4}Bc=@pm4)?ftMjezg9M z+dhf9<2$$AcE|e>58m-H=e8LP_@q540zqO30H@m#gEz1dIAcT*s{npY|9UlmQdeK5 z)m12KwAy-|x}ru0{MFiOUA0zQqf>)meHk$Osw+U67C1G?2Qq;S^-8~Qi*YN!slZzS zehKi&9q<3kC;$BO_c?cb=b;}x_??HMK(Rmc9V+FHf1?O+$3vgo_VcKpe-ifZ|NQR{ zKKTB3ANs9v>QSxG6e+fw*{ma=C7|^qU z^Ah0w+aCOvkE8zm{qKD8{`;Jd|M{WY{_XuRK!J}R{5MeCoR8ms|DXRo>gTsnT%ZZ? z|NQ7*KKc2_-}%Ik4PYu>^nIM(H(qOZthp+H9T9|iwE_Zo2T+h+9<``efL|Nnq4(ea z%Y*;^mj`eA7f=QK=ng=L+dg^!j(>jellP;5*xv!7e{|dXx83&8U+(z$p@%-EV*c&p zJ3a}h6%Z&M-<`Dg$=k=)6ajok1hK6Et)IVre=u}lc87qw6(H9wwH4q~kPF!Sb0z-I zrPTI+MS$(ogM4poX@Jj&AU_Ha(EGj?T~p{?3c$-$M}O={N-W+giLA zQ03hU(9A5#fa-z%>z4yvzuMafBvzaNA2%?4z^>k4X7ANEJdbPOAP7ebNbpmi-sJ0a zD|Iix-3kyeRe-*K{*vtv{OzKyM86%v+Us~ce102X8G8Z)tWDQ}vQGd6`0EnNV<_}h zfNMN}*S&yRjYh3uR%Yi8(Qnvo(E54%u9|tDFB{e1$?28Z>n**mnDfEv2UvLmkUv9^ zFQR}7EX4}cuRs;xJtBy*0UkR#1BZOPbm-8rqlXRw@1aA-z(Obe!jp-KICNiN_-BNHRQOi*};V~wB^r$PA z^-_53*o=5OGjlw1(xV;%Tz5afx&O(aoLb76-6G*WMSFYul6w8EkNnfRyV{pj9{Lri z0=zqd1auWJFF^VI3~V2zcSmX8F*?XZ(7vCs9HEjPW%dkFn4o)ud0r`Uz5M_x_C4@Q zu&9;ldNuITm6ckhSr|$+m6NI0luG&xAj-D%pL405#zQMm1u!Fme)o3%+i$=9yWjrq zcc1?5)4wtc0K0wbchvGJ9q~Jm32ff_>)Uj;x5}v_fDgpcJ`hW#07o4{EpL^7`a72c z$1(Ar{_eML|Mu-daM8lw{OxjmfomxpA+B*^Iifjk7E5O!&7eU;ZoB3aGBBu4T%< zrmDs-sC2JjZ4Eet_EmWwQZ*~a3srP$htrs%6Ryz< z&Sdmpirr56#!cZ=W+!9 z@0Hh+p^-V6+Xv2bxnJMYKle9B$eRc&&Ge8S>FHbr*68D5p>su3i>|Ssj_`J~ z4rH@>qG%%M=qUPHfKfXA<-wjFNPrb<1$flZMlW8t=GxLJwwWounLP*02-tkCfcrc0 zTY`WDSgBS3!3=;RoK7dj2YL_`Ga|~pbJ8BC!!<^V1smhz4Hav#U0Gafn%o6KH_ z%|72pgbJ{{MgU2GY5;7&jwGC<%drt&j-GNGEQD98bA}^kJLk-dt_W8ooedITrEGxJ z52yf;08jxS0iXgv0zd_T1b_+v32-B$DxRB&!xF!F37|oc7+BypF#(9MB}{1t32*}- z9vOuNelrt5wK6q;eR>sP^%KDUWx=U}GX=}ADR}jNEZ3>e$S=h=U7k(uoL}k7)k6Su^%LMCx>oUx|1V@RH9-OdZm641tyu!}`Ts^5Wj-W8 zz!>i-;N4&ZP^$Jr$icp#_dS>~Io77Qfl%R5B3))my*d$SObz<^P#X-xk6vP-6SW}TP4|AA#U3N)!S3A~R zWXuM+i_oS{MIP4NnU|q3@N$e6foOWHlgKOREJs`GWEP9C$)2Cq*^&08J$q7Nlw!@s za!~x8-T6jgi=r!SVk}MGS%ezuvZ-^)I$KbAT~}c)Q7-Q6&K9+FdcBqjy^zd7l4cV? z&DsEcd6==h)!5Z>#N5=KMbz=G9nMY#j0z+tuwqZbRahL79j^3-o6 zs3qHc`O89cyF4#v7@a(nHTv)FAr?L$;`sV(kweTW5IB4^MGvZ;B=B3yAWHPha$j60-a=tysCb*z5l=BRQO-4bwT{xZDsu1B> zHi1C_exL~nIK1v+o?X(VDCpo#=HVcNIX~AX8|KS0EX?n^+N*$`p0~Yz(yTG?lSwB# z`r30X5wzqL@_YXEVXlak{DQj5YOGI#V+ z3Sh-r%A1A(os8gLcn~BA%`L{Xu3p2~K_aio*l9d$STVcVPj76e$ zwi)PH-3l-`!~3WTU2OF&ucB7qoKLE==|Y2e%v&~8|;6+kI~>TRa4kjL~xVyIV;evgpHxSbI| zJ^h!y%@!(~cV^~nJf8*>bG3r5u6CZ+DOP6G6L?)l;4B4L;{@>70ILHztGx;s zynwAy2Jr23*Z|76p#oe-70^?Ft;zB~=yyN>tpLBzIzl;mleHj@xEAl2>%kG<#T&vQ40>IzE+U&J&aj!ESyZGdpYiar0jKdakK1;LLc1HY#F8}ja;WnTEN~H=o z4R9*8O1Y3@a%sF`;wzP^>u{P`TbI+W{vlze9-sk(`W}5xj~@8Ij@p9=deu{#834&_ z3bVK(n9~gUEIoRa-siA|;5s?GWzOjSc<%Tf{pcJMpil}x&9&xL_?mfFjZZn!Yb6q| zQYtm9qrG!(G+w9i-GWusum;8inoOf3<0Ipyans27IJFxepY+mwllm;#_f zo;|YzTiirX&IP=q5eSk(N3!|m+u$z0jhfAiiDg1I(;Tw|+*AZ`hI&{y;htv;Y^_u7 znX{&@(OcV;_YSvt^5X35TsS_Ol9ZyHVv=lAu6eg`+Z-F$S-fWJV#6dP05CE`eL=!O zIH)N?oWMhE=y_foP6spT3rMG8Np><9lHM?J%{K`Mn*U6i)`Gp zDFx}#uCI!z8buO&!iJT}NJIUm+8ArX)?(z6lO$r#F$7qNPkMY6%@6VA4MTuyi0aAR zWZXG2x>3D}-17z*dp==5S$)qS$4-O~k^6R&yJ8Zf8p3;s=tj~Rdy+XS^b3vFE}1Sw%!bbVEPq+@6zUtZH;aVoc-L6ajj|W8y#U-;j8_{i&F} zVVB6kNOGkVU|gj<0tv88y<<2|j@qXjkodkPg6epcF>gLIm3AFg9#(~K|v^SaihOq*3U!7>OV>+|1CG8;AWb75^nEQ%yJJ3E!pE18L-)?Lz$0o9f zRG}b!Ol;1w8myVe&Bol`UfGf1E(O1@(4dx+oyZh5n=N9Z zxmVGbCy?ZJ^CqMd*}Mr!UuMQw&cH#(aIXR_Ao30pSW`#tFwfj=7&vYz&k$J^G7&B$ z1X-5c0d!Jg@9mtf6E_)#({apDG?{tWcGw~!6y`#^d+rmc0HN)z#7#pQj{*!d*{MhP z)1;zlA*ceTQ>P_j91!4}%w{3hS7^_aq+KZ#=H(7x(~=1ZHX$)*qJ6!f+yy|=n=K09 zX==~y#`=mR624S!6G(Hd*|vj(FlQ{EnjTk6{y-q1Pzr>yQI&7vv82<%uRb%~H8#*eEC%?vrFuF_!K=Nw0+0 zCutrK^AcD0C%bQK`)9nQ{e0of-~(dP03bIXKm z7**uwjv0o<188$^uW(WT39w=|fJP;q(HVpJOk4`K)Z{JH6OkCtHR~vkedHe#chz}W z^>)m4EPVtI!+6XI-7^F5sI#$8SNeO%^5!OhzIbnCNQVSDC?jxIKLF3q^Zs+S^29Q) zV#M;i^YIolcfw6h00iNLbU*-Q11Oi)6Uc)dK|xex4iX>wW}xN>5B3DE5+oqn5cgM7 z{Qy$f6}(!YiXcL)0H6xc91r+zy=z%Eq#JH-0^rFj&redxnO3z=mFj^z=H|Gf1tzTPg#USx+xiB)d@|NHKkmS%(C))wBCilkFxafF3jf zL(2d_02BL!K0PCV38$a?rykh%>*$4=2*BhDQkz5si7}bxJ}NMW&ovwpxq1Ho)OIwa z449%G@dvAk+EP2{tTV`%4LYVa|P%6F~3&0fyGz1ES0NiEj=940-(lMoo|atBL@lz(~~( zEvr-d2;iF20Q|-#Ku;(u016|J0IP}sp%|s1_v!;4Uvm=$-QZO~NV?}d8Zff<-XLy* z3J^RE7+-_4#1K#cg24d$8vXx61qfm-up<9|y!+D9aQ;$I;JCRJfT{&XSH%7^>lTJq zt<|~%)mpCr*^s_(W7p zjE4dho|LDQ3ll(Nzu6UFWhMwAOqa9^7LGbhqtlfo>YgZmip$mh;M^0%+F0!#ZemS1 zw=7W`$BoxL@MKJJJx8lMP+P|3R#qf%AYANKACRIzk<#d?qEjIJzn>Sskw4SH@9qE-u@&Z>ui4I4b49?PW2vSSZV4 zo{3RM)b2^F*iam$+!d9ii>g|~3J^L1^sEE{Mh4F>TsZY%YMoXWo3Ke6o*bP52#{1C zUcA06Ouf0XjGM4q7n>Y)t|GQ3T%#)ktf<&r2w&; z)CZ7aZFv0VtcY4;%-hlz|}=pJsDFS z9nYN^_?UaVesYuhBgB2mwvg_+U8RXfezTOTT#HIfj9A#b{|%?I zsyghh5Kk3JIL7towfcpP006M1JX+ubjRG|lr=>jo+Ip?dol0$VS}FoWQ;WKv%C?Z1 zsne@hfB=t>-)??ul*`>u#wBmQ#}U_n@8Rwy`eWiZGqZM)uOpfmM2{fDOSsA)X9U#l zdsO5Dm!=-z?sn*6V@{G4TyD=Gmz(IQ;l|RF2o7_$l_9_0gS;480yu#J{7tu9=%2Bl zH|I(yKq5)*`)R^Y_2DC%_v2xgV^tNK^xWF`{X{fNfb~dY7;-5J`SnsR^HfCS(*!kR zT;o%ZkYyvAKf_Z-5lzay2Ob`6Bx2tfrHzc=A`zNIO%$@;5n2Ioj_A)XY@siq@B@Zs zMHGOH`*m!5Wu+xnMMhnU{o=swm6biQ=cxJJC^){0Jglu8jY595q9X6%Jmv@yK-yo1IRz&p;iF>->$1T`~1kffW zyOOv#D0q&{h1BW-T3zg@du8;krk)Xjjv6u@t>da8&1*`&Dcx?^?r1H6W; zk3iO63c-~wf0q-*L0$`SXCP$+Qmp{}{0rl}{W@k@(Dmy*2hZbHZ%2^vwQaw(hU7}t z-~Qya%c1TEcCZQ{6QzsNmj!{H_S7ow2^a)!g@3NGQa6GE7Gk-*@U6};KT(Z_SJ>HG|Qpm=B|!( zs{xl@Ea%C_FmvaGB-d=bP(YNs2%v|zgIDBkAk`1>g|fPuohJq(nu`Ydr1p;9b|X*# ztWRdl$0iGGyw*A_zYEXnGj@(NwevDWcC59oRe^q4*QCI{kytS6a90O**xt_j=GYON z$S!CdyMT))FXUn7OGSd|)NeBRgcQdN-fW!8}KB-ljk$NRBYnW%uyI79dWuWL3@@%xZ{YrVNMBa_b(+RAruC)&EqDg@^ z^|tdSGcf_0YaYNRGqWrr9Bb+jO8L@kt5}+4%%4s*|4L|=S^;UgiiFb=z^qoqM5c%k z+g!5*uU-NqhjXIrA-NJ>yf;M~dIcEKpVw4Zxd>p!`heIyV9OS1AFsNT{anA~qn1GSo&O z)e&@F?Ir*-FQo7MZS*au;2p)O`7;ikUuBkliQ#3P+YQ~&^^!%Uhi6Hsee6Q>|7|-u4g1q^s7+l3h zU>&LyeMal4_G{ znU!@)*SeS8KB-F7u&y?u((U(kT58=r!=(hF%|ML^YSd_|ycA$%5E25Iw8W?%H}dU> zCuEFJS&HC$o%;UN&03tC61aL4mfNvG> zPHE`iVt_0p3J}8QF7|9$0i5IB%|N;uf2Zwg$bfkiVEGA9RT)ABurBvp zFF{cN$_Q*!c@sc*=+HY?SAYOe0aio-2)Z8t*Z?j9@Q%Iq;))O;6wN@&2AH@K0`##q z!15}2gtdhrG(KrK)J zc_;{QoFp|~Hh@#F@zDZ;9N+7&k=mf2w@4584oo2S1;qv+yleoT;FxrU2p|iE5opqn z4&{b|09if?Fco!AV#Il`iB$IWI86@l+j}trpe!OWF4FD^6F#W~^EO)MZ_DgX2FD2W zwgLFZq_02iA;77hY(L{$UZ=O8KIR+oXer|zN?lWHVJyPk+n-msf|pn=@nGtQ0sDV6PEk_fxB zYxg~-ST1*DoEy8_p^oLAb0%=PjV5j!*BYnNZAyqZ??{MwGSWdQKoEwH&^>|fW*|=} zIrh?Puek_N$~p7qeQl?%o-H|h_SKTBr_a7x`sSS_XRemKTGDpvbm`TzkG^vChwERt zT5|U4>5@&)y?pnnGgsT*E&zcO@04tM{`5O-r%!-fZ@zOj;>>Aq2nd`idA0Pp=Stk= z-xks;U`(e}9>+rPhMXflt$>85sqIsbkOvyH+PwXZ4{q%{aiAqz%8?_Op?|d<6Qpfb@?Xh2I*ICQ%{hDJ}M^I&d zG8jgns};cX1cEByH7^3hYc{ zr;0AjZv#B@FlB%4*-zGN`kF)PBFX5U!FA5CAtyxuM|9(^_^K+9vn=wBN)z=+Qrtdc03ome2wdNw)cnd-NL>@4m^1Q(^eV~|@kDu2lv=ymWqk@XJx?T%X2^IVDKASV zKr>`rg;x|gQlShJNl+>VtXPgT8|!KpWutsqHkvM$N&MOXqv89NF~6?4eK79VfB@P^ zGU~1Vb&l|nYaHvYhwH;GmEALxXr-$FfCoM!E4V$eZ)P5%U*7Uc%nN7keeUIrCpc$gUU~WMt1)NpefHFeZO@l{w>0v^eJ?zB_v!nd z+j4?)dR@uAuWWhl?eCU`0|Gn-l%vf}09KJhqX3mkjjIYcXw4ZwWoCIVSO-K_nMF96 ze?bh^w2S4u3|tIiG6=afub?A$Kz><_=UVfO#v-{u-eH#J4$F-Nm*w4uiTug@zK$#l zHd%BaV>=$KS`>Shf;_Xt24zuo}{WAaa1Q!&j#tv zQ+aEKNM~(QE$O5pr&5x~$oixd>$jCjm5%D6@k(;=9H~vIT_3ETKfS6|xx@`*>bZ$AMDu>EYw^Ciz;J+b|j(qGU;So&z&)w3^@KKlG~rEflZ z`jxBCm6SaCXvv8)ZI89R{OAi{xBX1%_7|Qz@rxH;K3)3g_L8fQmY#hD9NFfv0YW$^ z)HI~^Q~?FH7DsBU0!6`!9k+M)Nt!L4sjXnWSco3B<>H-YnGI_#FX-qT>+H=P;B^&t zb>!y@(8+GBvk1dF&7A`o7PPtDP?#|${ua$1Yij3Br!s?SmbD+i8JiThmkgc)j8X$a zst(hioX;46v+e~v@+{aydRhc+^ZI~)p1TP?Nt6QcLR1AfapfBtKmdku=0fSkx&oub zC^t&Fq}H?|p**dt9IS;G+hu0OVM|(3h7C28=XcAy#ravbw8{Lg_MGgrT%%di)Gh69 z?#Rd&6OykA4Ru*#e7mHzL*9aV5kRwi_X56U-YpfJyMY8fCa|iKZ3Td4pqCBcTcD-O z&<)V$df9L&ssP)d#|FTfF;rZL$y+2~mGWdQd8n+VNg!*f6XdqEfVN^@OWwgcR3??m zuqI&o$rbq$kkFFdB#`7|@>Vg36=zuF3QXD}sY4I9)(Nt*u_nPXD}Zx^91ZT>KqoUM z&{YLUj(N2LLIBzb-| z&7}Zw`%Ob(jYLhQl^m_q*AnUxQfVXAl|$rEajm1CbB-kOu!s>;gu_%-2@>?RgZf&P zsd5CQs~ox*JZz-aN~(v0bvMxA8V|r@JAz*KX9EPi+m(#n!HrRJOp(s%%3w9(xaOy3K5`o&OJ0d((+E(Av4 z5U>G`hoB>n=Td+gKMD}RMc#6TbK_%lh}{GT@C6xtX;(~qOhatUe$yz`#fOKRV(KIG z>m1*P4{^_tWsi`zH1@A2k`trf&_zy#S+$$An`j%r5ey^H;r(0yr~>F#K-*Q9^HXLl zd?M!kw|gDnbui;`DL^Qy02`$MvJi9y&!+%!C&`4}Wb_x#p>d9N5OKtQdM&IcVZUS4 zK5p7~?>OCEcTiK?);|e|Ktw=@lu*4~L{X~J)dZvoQiOm41`q?68cYZfP)R6?Kq6d_ zB2_8UL9qftkfumC0tp~IMY`}*0@Cz5+!@9)KJWMbcr$O_I+K~5$yvWyd+oi}NhWKr zUn^=4`SfGiGx2Vjya>{$`Ukq@v%;*;>}iu$4l;m*WTd}23@hdveS|Ps;;ajtO-XXw z$?7;+o9J}v&=t%wG6q&IymXskHz_XM2BQjU<-Ppl;?i_UMcY90AW4Iw?Ugvc6m6g0 ziOFc?(lW)saD^lEVY8NIIsaLBMiU=30`YoIwYg;kL)?E}Gam^2Kq1mDJixuOY$<-K zh9sLs21zL7itW|u-j$Fel(7Ob63hsGxffY(haB!!XE-YFFOFZnKWP6Se zv=(*0Ft;sk73DWH79c7kbFDk47<;`k-;KAG*@Z{F@*dJ16`zdlVDgXV7`c*1B!l0d zqh$u@(50EE3qct61u zlqsPJT->#jvHe5uD@gg_>obg&dn$Vvo)?$J--KnhEv~#VUyDU@MCt{t?h!_luiSw+ zS$VqaZ#m|mUbE0}Y$EF%`B?7Rk-Rdyq64$ZwEi9uSfTVNtFKuv&|$IiVDLK7PJone zH9*4s&GGv_vPlU`D?1vpWIm>hIw@>}*{LV4e` z>uAiSr_&^`>kENrha!cV)_4VKRVk=YCFI*`Npm!WUNoLARCc*yIV%Em8#3nATs)Zh$X3`VDO6Acw zUMaQ$@bYn5$Yl5ODZ`=qf0|RO4m^2FX#I4JKkgl>qrN8##vKLaeE$eoijb`}FuvN? zxp%C&OO91f4(Tq#W1_)d49CyAEl_*fdNf;NjV;3uRfXv4_!Z)l0^2VtU~31G@WU3~ z92&@*MZu-PYkX~KF=Co_KG$EUN&{o=i@RGNe^}L4O6AZW;=hzb28tiKM`pedm~^(y z@0s6)EX?AQICiDm=#O3EPwolwxpY-4c%fC5prwc;M3NxAbyia$;gZUJLUp zi_)U#Q}<@>3MScv-I9&NGm6IX*ZJCw&m5L}OAZS>oJV;zlNj;QiC&ljb%9c1fpyq3 zdTmvMk`~&h{sGkLbi;Z{P;wjYd2p}dUs(}W&j!04@0&EOluGF zU>&lbGV@MyR7DO?a*DFW;q3y*w@c2oyUmOEMvmFYVnp7Nc#?E7LQbWQJcw&rlJ4&G z6VSqOjwwHWu2mA9eel7j;*@mq_Z7(Nr-;^*!VVb%w2*$w=MUkxEt_UEL~s_? zBKC5J;!oZ;6~VyEm0~$}2&No30&#&?s^w(EwB{`#?k^#sf9ATiJ+$;GRwxIL!52pt zMKj(FR%_==*+SU=VC}wGOnp6f>y^xdBh@Dz1v4cc)Wns*D#i*GcY$a3Ll>vl0(pZS zAR#8?Yu02zX9O8dW^%1%ty?yw_?BHAZ|Ns&2cSN^E%@A$Y?grW9=gu3(3NT}+D^IF zV*aBzix}$L7F+)qToLFSZ7b;;W&<&?w0kg$K98%?!H}%=KzkfA`Na&vF~y z4gT4wXO_V42vNjx(n4Q}&=u%ilRJ*As28UyeCeX~N-4{)#qFo(28d^7pS~)^o~22# z+m2?pdXN?dR4Eg(k^}se;YOn*;Yk5eq zH_AaiEv9%qj#=e$o`I@!Y0S3qcFV=^^Hk~|qO=!|78iSs7JGSvmsd%{C6=9yY@4H* zvF%GnZ+VO4v$Gyh#%=UmJKBdg^QnZ5xNtk1U37TsU^`oZOqPrNEOk5mN0 zRUV%Et-jZ_GE$+*EFO)rr{YTHTmKis|^Q#V_z+aU~+yIa|?< za~i?c>DSklL~PN^!52Ueh%=-3)Vh0Mi9?0`YRsW?=E+7ucKxKGoGy*L{-t*9Cb1nZ zBr)JRMVO1d^7;A7#nIF#rqf*iDrMwpvzy6?`hYqoPoJ-mQ!m<|qT;t_ zi!K6-e~icdvc>l=Km1R02mf!w{2y?DS;H6pgF8)n3;g_?z+Ur!siDQua($QZf6cbd z4c_I84RGC{+NRnbznZQh@Oa7oC|HDjnBye<*rA2H=n_A>>HWJFBZ)ALdmZwt^WNL? zn8z7LuYs=lj`nmhn<43%KsNM*YJ=JCf1dZ)lEK{;Y@=hD-sLwwWG~Hodqf?Y%BvPY zzc)xJw>N5o&;72z@sedED%X0`&fFCflv62xa)B-)TgPxo4|sCxfPQo@sjs?~oBEoE z9qD5=xvG7=PUQG+dwea|8vijWc{2)egR94(e-0MW*lK7^=o@yJdioe_P95e=P6#bW zOM2s8(wtJF%QfM%4qE&M&z|9rJna)N;6%Z4F*oS2?k9)t$9<{pyCKs>IBRLi@yTQ6 zO;A~OogYzsKK`I;efECLnCi!bmL9Ja4fg=ZPBKIyBjIa$f%{5Vx5!-g(PAOQ{ z!E8Ncm7^H5hu5m0L%${_Hz61H2A(w9d|_ zRfVQ2VtDb1Q>mOJ%1)MT*Hl6A`{X?xPupIf(HvJdJLrE}XJ!ahg*51YU{rr+mCW|W zah0S(TF*I_%7>`L^$M=(u1O)M-X2vS7O$;v>|SXKORiLw>@xUrL4$ygk_z<ZYp0Equql5%Eo?68Yz@Q!(A?lKTCh9bZasFoOgWXAO5k0f5c9$qe!{=5{!^myR3S zqV}6w7%BU@`gyuz34d|8mn9zeYE%)3TGEc{d37R8!?5Yu&2FK*tyXUn)Mc(lUJNI! zw#i#K9h12x(a;rF*+N<-*qN5nm66x$Xk z>#GEFYu!(})+x%65s5VQd{E@4D0#e}@1-Gsu@>Wd?x?1H!;22TL}GQj;R+;f>cu)P66%o?sM{{INf3eS6mi zbIVt;28RYXKX*?LBHlH?6X!=zQx3r4e9pMymH+=Jmw$rd?t^m;!2UZZkAH&Vi}fS^ zoh{;Drvr{Y{shGz=TG$CfcoW}B)-E@1Xtik&-mkU9(XK)@OKtTe}{zq36iI;s|S{# ztnV4%>*`PVrCHxk@8(ay2m!7E#J@G_dmPqJa5fg+-_;N6^Gkcache3qA^hkjS2s7T z4;I`{xUb8-|zg{D{E)p^UOVSjpqrH zk`RQ4!GZw-0)iJ7`XvJd1a1Qa1nL6?0r+P5lA;9&WC>OH7q6UC>ggJ|8mj77pi2f- zJ5ga`7zzp<9msl}lbV;MwYS@)w2PV+jxLExRWNd6q@#ecr+XS2nl@4D?WYfqoEh8w z@lkr$`*B=!@fj~9KB%neugJ&-RmKG?J~s=kfw_4#OpmKjNY~pyen~)Z2y{xzopSWR z*eAsv#E>lOECxn7A4NqrGHAFgd{Bgbp9F#f^A3SN{}>LKIH;Mo;H0Bb=aa}MB{W=8n=b$|GO>w? zg>#OB{V5gP`OK0LO$e`{UPK9B^aA*r3t>fEwCNl~2Coh**&7yXvrkabL%L`KBLN5h za`Og37Zm~^7#BS|D_2+UzQFaki*}NTWe;PdJ+6Q}3uoH>SoOy1OX6qSqUh@=HohMQ zwhAQ_w2BCcKpHA3GCav$*><4?;XB-cMf<-S^1%GZ8NJ1Dcuq!Z432D0I4JdKWOBDx zzI%T6)JK^&7DO?S9jP043woLS$zBo0>OWGEw22J zOP`Vj{QGumo_5RSh#I!&MjUfnrTRCzQT%y?ZO~Q%l@`*&nh+&SYOmSCn%Vs{2w0AW zhPL(0^r4dKFucDPCiIgM2n7;uf=j? z`LrEAIff!NwyZ}Mx6T*9pSw4`*8 z^u+r6$)a8uzudhUcZTL}TX^XKzl%$=i1f`M7IsibuOg;S3b*_7z41)`*>@9amzi9ucsaPo1Q1i2m^{f`HQWDQDRNiM6NOqnY?8apEDg;OxWh_yne) z-_hLFq>6gtB4}vXNi?Q1BJqn9l(;4SAS#g}aYMt#<&R40E&I!|0{&?Vq$@uQ!R+kp zw$X4w|AF2UL~NJHPm0`VD%-y$TlZ)14TH7D?#@LYZ}d^Ngiwgfh|b%83itCsOdR~w zzK9TiT3T$U++3c2o~HJEW3h9t7lgVznnRR0^e6I#m~+XC2QRARmvBhZv)b<+Nn@n- z7?=SkBeS(XHGo8s1%VJ>K?DNF0qguDuie5uN5#6C6k;o{{nJYvBJwT2^0;ojZ>Bhc zx-@k_S;RzVl|t7d8L0rl<p_=6d1cj-Rac{hVR6zwI5HDyipue-I4qOia0kemrU?*!1`+9?N(k z$!pWtzQxN^@?}7B4p-aM@S?>n{iYi)%~V~+=n`-PDVqOeP}mXDbL2TcrM95~P2o*N(B{+_t0PR1YT|K!ebY!JiI=%GI3qN_leUluKvpXh>)V} z60!DIxnBPefGSrreWO}cxboT*;$bHFz+o}tyg7T-<6S|mL6LMpbxfn!S+dntzq651HeALz zP5>tCyw^a1WoD@^2$$f5KW<6>&xWEEt)-KM%FEu9Q+xg1wE)2gJ5}>V?RLANQwLGB zI!S;&k-Yyg7#oT|Lh7D(4 zO#e^K%8NurN%yNhxU0nCxuO_ptK2`{=NRy!pr8rewj`2CTKT)f-~=C!@FgMVFrcu z)ouf4N11%f>S`GN(t0H>tvBxeaEm|F&<>2B(v+Z#AWuX*2fQdU{nDpukLSU^g}E`5 zdFu5o@*Ajc}8SmDDn!X7=838R_`jXEwp-b{ELOp4L?NXU8xs@L)yEO^RitG4 z*J)&p%JMan4ac2f8d>?+CF7@2pU(t>?b87w@#$xV)ST5ZkCk2Evc273=o+eqLPNh< zkPpHY#31v{DT@J1imP*s^_D8=u}g}k4H%d@9?4w{ZV)G*0*s}8#2 zz?sfA)C+clJajFJ)It$X@FNYHR95Z1toV0`=~3|ig0A#`ss^RBO#_-HXGZ`$yRbS~ zbW`CA4Dy~zzwxF{qleWOt7#(b+0KqlQMInInUWHy7@~Hvq*z9Y&tEtGBLToM-(dq; zZW5fzcU^Ne5$FJ_CD505OyJU90*tj51{_;ND!VUe`U)y4SdwL^e4imB82mGY0S*E_ zJY0{DQ}u$gsMv~8Xz6cQ!uT#<(d1jxu3_kN-u4f1bV z_V@VP{qZdQN3YfqIy<812u%2DE39vds_(?k&Sc5Q#wJP{;mosru@XsAipf_E^S`l% z|DS+ApMASxTWa{EqFe{V5|`DT<$vUyFH6yHb-C}3F};eMo~8`W^_$9)t`D=fzdye>Qy^)7lTz>T_WU&61CPz@Hq-9@^0J4532?;S zIzJxOQ%yB^T(cE4ErwUrWS8hHCj>C&SCQA%l;G6^XnenUpPrO&WR4B^ee)L96|6DL z!(s$*_zm(O9HFxK`g(iilq2o#_uc#+k?tFx!%^9DXMC-TwkSKxrbXsvKGTfe4P4tBq4_l~2u% z7asfq0wk6_v4CVo;(KtmW2r6X%CYQaOJb&$J|S&DC^)sb_>~>JyR8+fJ$UxaPtl-Z zyxJm*ubsLL3o7g_bI5NLCOpHeZl7S3`kz(>u;{cpo3fFc^wO_`Apssm$28}n&0Kxs z3MHQmU-;c4G5aZqt~rP~G~SjA9etiKU_K}2cv00I>&KwAW)j$E6)^<-A3O_%1ehwk z#wZB`-7Vwwt?%(6l75dSLQJ7F=piprTuQO;>@x(Ki1dM9OaANei^ zU`fc}|5>6ab_O?7049{13dLS`YG_K5n7jr5{n8DBkD1rUWiaWp%a`zjr2(eQVuRy5 z>+s;cWkLXlp`=AqKv$-pKh39|#G(ABFv28&7x{4G4O06{@r%8Q>RbLmSouQL9d||!}bydg@|#o%I_gY{)D_DRZ417>6OLFSt5s*c;@jsb9f#~ z_RoA+2c32@J>?au!SglJ`tG0I5m;7=uf{(}ene;kh5 zu>4aB;A=uT?*G}LUVO_xG5hU)#Y-}Bc$9zE4X7`V%hu%un7XTx+3=#zUsg!slZF)Y zjWbbkA^8g3ZcpbPj>A$KdV^Nexn49z1~*H-vy=KsJ?&T}Cc#0F$l2j^w7`Ch8FQ&W`h`5P3Ri9^}p2XIUUv z2+4WrA9to^!>i?oiJ!U}2K#G3!Ld<8iXKQ}md?%_xG|qW3W)-V))!XMQPaD4e@9_q zT9K`y{MT04XZ0Z`@|W8}AxZ96j9<2~cih~snTJw;b=*bro2;`X5I=51g(-bM9oP`rM1iK>JU#+rby=5vsR8pG-OYH9EOmFe&5hn`IO~J~sxgPhkb$pS4*AXo~SC z3?~ng2(JR#1WXXVgt^~?$GO4=c8YQf3RpI6nn*#sz2KXWo1?x|?PsdxseK~&_NC`9 zB!z^9r9Yko{M??j{7uN%8UdJv&#i^vVhbQQjMX#>wZ+JWxQ|f4=TiM&>Jv z1#eTZzlQJBlpt;4k8kgxmN9NM!YEkjwQ44f=fcxnaa{C&4Sk_*!li;1CSz_t%Yr2 zcucoV{sdfI{4I+;OiNgBlT@}Qh~2)Le!9!Wcx&KRh=&F7}u zZ3{x}m(>>OAA0~@vaD+#%~=3pVCO1KW0VBOf}bXz+WG6tq8F>*c31CO+DnBZ+TmV9 zEthuWOO(1YwfVEeWd-S`XMi+RkRM&!0!;yBSz80}(hW4d4*|IwPu*oksJIveNg`|W zQT^%)5)_yjUW8zB;qY5ELqOrq9~VshhCqNA-hchIgJ11dMv-4rgqM5e?KnTB!`F8= z`(|H)rn+7M=&;2T2dQ=pFgCiG5i1$l_V#Q$n2=AIOGd2I>8~R<)|*4TGQD_4Ue#>V zPz(9YUXW>R!NiT#ox$7gky8C0of~v0 zNFBxgr0Xr`VwDNeZE6)te48tLh(zmEB4G-9ej{I0xI4HEe*`$>opKgC?%(ZJGM`kT%73XT!?;_Q%QSR3GsQDVu!|QX>;$7yC{uq z5wv$_g@-1*zF6!?DCqE-Js$1~%OTu?U&U(C9xUNriz{6*1O~hZc&)8b2Cx@BGMl`SwPrr z6BbB$-t(J#!} z6pa}!G|dO(&jQhfw|^aul)pS4OETIUX-uIIOLFl0wKq$$zF<71Q7qmyLEMM05VD<%%z=_<|+>v7`KA|9#rVd@q*nA%2 z58>;ZqnQHgg$hlcjj^$^k!TW8g)+4!8)fT-gy`tv_h(%n6qY;NbLy_Ko|7#D!VxS? ztYA;pcRakP3-{j!CUlh7FOEC3nx3Q07Cd&-+qxMGB9mhwf{b~1l*nOfYv+E7 z2LYpofYRi!dz1G0u2Zh_C4JcInRa)c$8WFK+Tj%zR(7>2n;RKeA+CDHZl~eq!Ete@ z#;rdOcixyz{7Um-4j&*?ZNd*E8vd1aAV4FJW7ah^iI)CrkCTkuzVgMs!xt6eZ!STR z4?y25yajzwuw9OFlm$I>>l79C)YcCq0BIEEA{3K z>us(F-!Uh4u0(EaD#`HhS0?%J1a44vRU{fzU>_alwSbagArWw>>57t~H*;Q})eB|M ze_04PIE;WN+B4F*CU))rjF86F+VBa;{Puim!qo`QxOj!W-V4fTriq_=#w1`1y)|7` zfYenE0;+!cGXWb>HQaqjS~MxI7^X}`!FO3JjJ$td72$$MWSX##}m`t_UZsM)*QW0 zJ-Tv%bXY%=c9$L3pGRb%fph;owI)_Eh*@J5Ton!sppXP$+BNsBCP`qlZcMSll};F} z6>P6?c37DhnXQomq)R9Kw1NOf={+OGpR#P<-UAF$UmIv`Ub-2a@Y8P&egTTV9oEC- zLw;2<+e$ha(9IiyNfwZEF8F}mjG7@CQh(+wIiI)tu!J@@V-J{Lq=kHQ6eg2pZRDJ6 zXxFCMhZnL92)lx+SVTE8or_XAo%9sNoFc>u$_<3t(jy@3tVurTfdN1jNLH@M5LnFd zbonLzkBSWqh}@lP6KoA6BX{zP&h^rE>2ctHJymh!ZrfC8DNE9>sH_KzgT8f)FseL_ zK>ds|v?U{DkGO%yOVo>6jDvfJX*lh>Uwjd{S{oxW&TUfX{12~k375+~1+jGZNRssY zG_0T4uEdjL!#f~(<)Ab94G_R-2!S82;L_1Cd9f8F&cmYFjN?qo^~%!RG2f_6RDKQ^ zQo}s17No%=pW%xAScP_>znK zV>-(Ir6V~tv+M4Z;Sp8bTebvia#G?e#wwiCRWGE*Gs#ffhrYFXY(irr>sp)ZL-+>Z zWB2mXDrQ>4)5<71&I?<8*Dcn;K9R?ruCQ9Zb9x-O+1?()UIW!Enfc4S+N<2A4Hd~XnO@kS*odoY(b=*)5w5fZDx7i(@fbFEbJ>%4y%fO=lX=XWS zbmkTWM}>?(#e=VDNsJ60)~T%o#Zk2d&d0wU`%w|(4!_uv$H7=p9#xQR|EB<7EZrJB z9pcqQvY^n0s<0?^_3GePPsBlm?dr;w^`n6HfVWQ1qClJ0USV?P@F=FdniWPUrXvL2 zbKbBVDR>|8gGY=mJ-ca#FP^6#@W*}NlDc>ZmFCsC6sOY_1@f~Ulea~hNjKjVSH!N7 z>EhB)QHFSy7 z)#W(U2hPJ{wT7mDn&IDE>{c-9;df2-x?VJ`_|w{AT%S0pv|JPFyo8}X0IzT?N!xGV zx78>`bd)ewT{D0XaD|C7KoB@AZz8JucV>%#sSeFkxze&^!S~0Fh%Ja0%smx|8mP+i zw%v}XkD5qNm??)1k=ecqQk_C#4=e!-ngCajRcs|TxG`1kwK?dK`%ZHn46#Yq2)MJ> z7NN{C$_-a>Ti76*y&uqAL!a_&VHMXM*EyJ_d-= zxo;?5G3zaTR5#KL`&Lv~hT(EJh;g_*UKZBYGR{>mOOSq*8@y9O4REkmYJA0?d{zDf zy`@oUvDQ&}QfZo{pItsICM+bjK%QoV7KA8Ft|wVD4IG-`S5o)-9G1HQl+ zSrVK-xE_ORMl)Od~nnP5o9QI|Kri&?9NTi{9tu+wj1f( z`7{V~Sj~t@OJV{r3ymjO2N+EAeJP~v$zZ~L%)>HyF`URt>OxJ8ujq@bR~0=tp9Q;G z$2F#pY~o~@p?YC{0W>T#f=};ZTjhbV+Ex9;i@b&>?IE;Dw;ik9BjuqSgKs*uxYv+g zPo*>0)>4QR>kWC`;2Z5k$B(?BzP`QXu@sgTXn(%n%9bHL+WJy*Qx_O0zdHh>Kp}mQ zQ$Pa@m?yIiekxV(Fp6cc;0H9>`JUhtU8{%ZW5P`_)8C{$Vo#N6fG*FCx)cYZ=lU#6 z;G_F5kwJjtswQ^_4?$`tm}1byDMdcnzQ!Jz_bmWTCee9rL$ltnodo(~TcT|3+;L}W z>%quED)q<}6%=6EmBTXc_Q>2m+27?SJO+lWlxq^$SK}5+i_ldj;HoW2S&17duXS7_ zcRLR+EktgdR8$%(dYp;LPG*-g!yVUQTfF3g@GIkntEEEG)cwj3HM2ilET-V(#HC2L z-9DArHVyCf(0?JpXj?luh~PlfS`LV+tnR=p#7OGQ{!yoW**`%aulqiJ(FT8zr-M^v zM+f)pJm-|!4w=wKUsJGUU5GJ|B>>8Qc~3~oht{3k^mTJzk^YSOaGoyES^_ImHV2}% zsNaW@K0#QbZ|OqQ+#%$CMHn9biBk>cd5TSVMn}#S#jHxP~z@!%sD3;bcRTZ0C?5rFv zM@qX*?Jyh@!~ga%|W4DjlxCo$l4yi^w!NX)oG+6C}g5CS!m9JbsvluBxOB<)e8{*#+)DUJ*X6kh{-mCj*1Q}U>*FoyWpI`I(Ho0i-p>)5z%Iqt6L`@4 zQhewVh(zE%xqvC(z;?IAwd}aN1);vWc@mth$!22e;(Tt?MNb*Y}3K3zhgUmIGnfj#~GpOEn1i+?-l> z$8&-ZhY;uby4f_a;yDpxek`c<+kvwClIj& zu%R&8@VhKt*ttRK`M9A761H}%2I4!69h`kvo+>rnyYk-p$vw6cUK&fy$KE{bA`QFZ zAgagy1U{G?TxU~Nexo813iJb)=iGbv&9(1B6rYh|9Pqe#2`EW3LiPNxmv@_Kh-u`E z@eiv#?N}$XX+<8V%P?53V(ZK_QT4*=BNQPnG5P&fT5c520OamaR95Rb#oMG^0=#mQ z*t&?$DbNH5Wi(hL4Wd(Sil+Tu(XK6BOD$_225Z$G^W_zv>ci%dH>^ds5ow4yRTl3# zV)NcT^os*X6os~Dc~zVU{ytWO?7FfvXN>uMWf3Ss?cM8nqz??U%nGXKpOR6|DN7>S z9c#3lC?9KRw9-;f`{CT&IIHWqog3LNbLVNNT6u@*f#xRA<4kcwv^-Wf;rQS0hA-Zm z_4Wu=OKmLp)4OGz;$i}6XMBh9|E3Dp#{hJKRb;-42 zi?rLRJhiOr?Y{?W%r+Tl71JJHheGfgK&(2v!C8XZF!4%tJK1~>F%|Bs{B?zP zqDDDJKa@Ah9g{mDpaGKFj2zqcOGF7N)g2Y|rsa6#OOf1YUt_=R_cL3KA{aa4sJQt2 zrYfuB=L-A~9nQ9_jXyD&0v_sHhCsq;*CLH?u3t6Z#I}P)fh1C$5kGEOP(Hk58@w^U z_k?gBSR=r^V#~_Z7*4FWdVaiH3kwSi;2na)qL-?+IGphf(Fre$NRmNo9BD^S#^G^0 zINeBvG=KE-&a3<3NMCR69`Dgvx@Z=f&Hy(vPkQsyZr_aRtM`x_ZJ8y+(ExTYa*dO# zoNxB2Ki*$1oB{nWtfPYYQe|5u)DP_`#$doUn!$MLlUb)1@D!leD)Oz0N2eDGACP7H z|F#JkXH5W!9xU4+{V?82=cY3#a%~?IZgsK<@Gi(auJt+-|=f7BmD85 zvSM7v;EjHqu^eQ+SowwW^$Vy+Q!=3>bTIh!yQu9{pkHtj4Mqq$?5MqEvL+k4e~uy8 z3v(@`{dKIo0nBKsGg^193S8Gtq%CeRJHqzjETh(I?mSZIx73=j!Aamy0{G{plH zW?a9=h)lcll+{i=VyLYN6f^Z{r^Fp02K$P4xRJwqgp`$g0!*7L8j>yaF#o*L-Vy}A zB*Tj!rM4NB+lYLC=9>3it!DfK80jv16`;$o&hre_ z!1F4iBLx@0+O$%q3vY!v3*vHX38uQA;p0i`A1lJic3%cpo)`n?U znh|1sg%o?zfV%-So%;IYJ$jiv~B3 z4ICN70AHvP9`RHwjywD$${W7M_=14*Qmye!>fT5~1*_BLCdRacg_c&Pyt28dswhdj z!&q^K=38Yc@nEEjHt_&PK5a4x)31TI!QrAycA|`54hEdPF&kL3Ntt;9Hl=JRP4V%} zU0--QTa|T3$n?=Xm4(730~U8RUq%kDdTDQ6tuA13+Bd<2z-#5=5@Q?2nMs~iNsSwQ z#>E07+OM9{W$jF0gjCWT&XvCwzp4$^i<?4u%GGSqeEnNgrv|Bx$lFq_=rX zBpfYh`x4v(CTzOMn1I-{5hQ%`*clV5%V1k;O&bM3K(J2F_FY?6JFw_$ZD)}9!sc*7 zDs6lp00GU};h=P}S~po!bk$YNK_EVD{9AdBI95-Lvu1LjSV~1h4P&c>vE83Qcyjhw zz}AUp0&|ylx3VY&?LR9H@x*f_!NQl9q7)^eLQK+$v&D`rR8!&^@!yBOj@_!*56q1x z@4q7dwTy6 zgf^hL05M#>_tA72+KEy?UjR(#$u9n1^?Tf3otxsfu69j{71tACWtR^)`?U2F5HAH@ zRPt8}2pJsVm5#1SPH3`0ium69V~OD5!*($l49rsK^@qzx5@;XR0W)+vM8t@F{i?FA zH=GDJr-Mc|b@r%{5kCoH1OBg~2$dZg0ShbVyUG${`OvddWa5Uod{UPYoHOEOD}tD+ ziLMG$@?kU~jU&TPX9?O0+!+S~Pjifev_5`}R}rYWiGEdElO+d3L>_+IonGnn&Kjc$ z84zhFUSm8HU7F7WMn(1|#gUYo3-)@M6*N66qQ8+6V63w--~>22C*>izrUHK^&JGap zOXAvjz9W!?ih3`)rK65i;K0tfC_yG(*W9;tyih7R4bo03S=s<52Q%(@H zt|t^5@;}Ib|w*xi{XuHJ*aqHSfIU5H|+a2vO^PswqU#>l_g|J0s}N^ z&EEFh0d0_n-wfOYKpOr~Sq1PY7+4Te6Vc!v>#xWI#ASd&a{7G)sK#$EM6}6CY#!Yvxoe*kRG2gwss=ONd7k@YAII|a2xhdiWce8tpfbir- zx4x>NVXmS-_T<}^V#-=oO0Vy4FBxQOC5jbTF@EPwwg(WA22diV*f|g^t1bGDIRahK zl6QWs8PLk?2>0h4h-nLO{?e59U63Chl@I+Xr=;L^)YzTtx+}l*g}NeG5;oH%#{fRD=40^wT!?Jev3Jwl9LOd&z744VO|v>;iiBH z8-q+1$)d2!PdpnFFW*p(F2_B*K~TTc`gL$%g}lFG@_yVyRNnVjd~-1=&TXax#W}(3 zsdC(?4w$veGQ`dy+R>*Mz31n~#fGK@X`HNK7sS!zfMjC5zh6My4^vsv(;R5Gh7*dose_d|aJe;M396iX;#KWYREEkyLT#0;mmH`vnMduHFh{0+Z=SJ#q_S?p=Eug{ZP`2BV+gjI9 zQA+I?;T|k$eJH7pC*}*5iT>;8-%`XtEE)F{lPu|zmY=l@shr``5sxstWg-fw#tWu{ zB-?Gva#!Sf4UwIXQY~wdLg57tvYUY!OY-0hxjad06DcOSGi}KDN%F@@wk{~xAvRv zp&F3;yx(|WkIKi2EMs2O;wD|C>EV?x%alrA&Jo*rr89H&f$B`0@k1a1pc(G z-fPmIDg;e!2QYAIA79j57W_-m#f%zl?!nbMa8nKADp2OMo&W@EtcrslbUzIeeL7)GCUd=LdG6`#R2I^l?%afNns!vpafF zd&$rbD6ziY<9Q%*DX;)T^!bpKxbkj>Vqa3w!JDv@!E@|0j+%riM?!z#dMH-si^k4s zugv3V@xg?mcVB&Q`GDz*SJpo=!SWD;@?}q7vdTs7Abm}MQLd-}tF)~KB|DKs5-aJ6 zbyn|^4m{t6oN7`LYMp5{f#L9G!3d`a42X z18;%Pim#Os+a%SAaDUudm*>6trD!IgnxdH;icWJRw$acGCh#Om*#E)Zv|-)s{9r98 ziSOBR*!W8wcucF%^!QtnV$IwBY;lil!Z`KX?2=rbxIv!_PnB|&j(?*zmB`o+{lnKQ z4*RUrXveGzivh*9*)C&K)`G3m^P?2A7yUoi7$Hq{5-zBt&dJi^e?L80A)*F6=SnvJQ}S zy<`OzZv=CXHBuQknA=c0?as}7t&;dSHIesw_;g6v5rTAj)(jDH?xyiN9W&Xj4B>3s zsXLGFwRmQP++V-G&A_)BH1hsLMhTcWgutb`X8S6t+@&uye9(IMh{Lu6es(Ym9K78b zji%mZxNknyPOtS?N;4^!LGoVJw-Zn1_Xq#-`_laxJClE&Z@1RS9zmf@4-E6D+2hR- z3Rd~X^*DC~EC(d&6Ps#06*aXlv*kKx$~QYU90|gV^=fSH$*az^z_S*OcGNXWu6>bt zAq}e0qZu5Fk2{u7{2xH6IA>YHH71=CV*W@K3sxWd0*lS|ERXMxaRde5gU{y;&(kco zu<9i7kLL>*bzaug*KM(z>q}wYj!k{tTlz2G&51W*jkId2J%ph?PQh)55U{dl72rr>WNq9 z@7>q)h;m9KpBr~5R0Qk2HZJVW?kr5_a&s|6{Blm4bziC4x4dC!c-|u- zNUSu!00L)bzS+DIiZf$Oh#y|j0Y|nTf7%8wCd+WB_iz)08w{))4~J^ccJTCmiZ+Y0 zP1@dm#X36pL;cGD;jTZ6lV6>8d_Im8Gc$O@OHJ>L|IrYgb3JA0@|5iBZEvGz0AE5m ze&!KK2FOTm=EUjs^2Mtjgr_gZIwoCaeRU&rLwC9Z@h)}5Gr#&?coFLgYx4_m=s72< zS#6@$z7*{FT18x)*l&8ZMqDV+W~GCr@X>_?pTW36aVR(A9|nV!x(VqobreSF>M06i z^p)mEp4;0`z_=#Z?X=E+&=7t5z8IMp{qZc!o1K-xkU_k?CdS8BR;h)CI3%t zG*fQV%gWO|i1^@W^i(s1oLSgIQ?(!=*9EMrleA9tri`ZEpgxestX`rPs8QU6?X$C8 z%m7+_1_Oj=0_t5eO+i<5w(Hb?Vv4~vlCNU>p5(BuhFr^sTE>Delk8qQAnEc?tO~Qn zz(OGIFK>(5oLcFqp(QjP0=2nHLIRabvo)m@aQx#wg8|F^MnKM3arYks7p=KMn#Pue zu^(L1Bar##PBC0+(PtZWcfLU-ft{mFYy*NG&mb!_{=>B&!LO;*h{MCfm;w_d*wJ2G zm2DH7i;cA$lK4MVa{JW4WlA(|vtS%0&yXAiq@|^WFHY$nycIL^cj8cd*$4Z#63i1rk1!|g5>+28>(FvFthXt}wsoH;? zK4uIlTZj-_tpvhocr1DxKsI&P7ZMioepn}AwPQrAALD|!NN4s5@;&C;S$@te z>-XDj)O)-nMMA)Lfl$;;@T?gEB!`{WgF;@?#1dW0`s0&DK|j8O;o?U?N+h1PNGa+}Wm^JJoh* z`|5rvEi-k>LIWmQ&wPTkt&ct3vChI@y7YU26S67XYah+eS2ymEruM(T2);bXuIaCz z_2xP!KZ(1#T$w#sX>iZAqh?mJhGZAM2|>FXPglto1Wx!OmmH-3HW3hFIYYZWS7d%L99xeK&ABr?QR4p*{nYGpc^)+shD>TU+V~ex#>{D)ulNzhWq;&aL zMq*fbZiBiaw1He)u$czMn{et|amPuxU8k8|ThtJ_k>>da{*;_*65OAAS1 zUh{8E7S~dmD1DNXXYGq9K>{GNDC1^TE|KjTh!cMb=l5MXw0*I$FFik07VnhR$+PRC z4Z*>)NVR)K%lYL-8k7=y(-+odBVZObaJ;p5DA5I;0DKvHDOfH@itUX=7%_pQG>^T< z$#4{d68tv1zD!S-Q>Nq$OhVZdlDlIL_vxZ#N-j=?vFH7y4i&|k>5&yEckp`4p)b;8 zA2x<8sbA~`CdfvGe2H5uLRx&lxZEII<|p))&#&ak1k~SWy4zm0AGJPOQTXt^$HxSp zXl^c7`Hj9E+fbT)v|4b2oMAszL@-WV?JkR2lZ9jt|L8dK0kWj4)BvnL*W`5XNEKeQ zBK+9!(Ow<&eUjj4*a>coQIJYP#j`v*bL8DqoiyyfOZ&>JI=feIc%?0!;OOBzlJj?Z zK-A3v^cw+wkikRFF)qWM@f*qBE46g|Nl4_KZ4Kj4>foE5z30K{HyVD~#{Jc{t(zBS zc9J4*A=qgp!+D8hCby$0d$%daz1U1a0}e?Z{Azo(n>2k?*FJt*Ov7;vET#MvEet4x zHQO_3$&g?QBlP@a4VR!}q1XYBUBSfBR0g}vEKOlG7%T@|Tf?VU;S&|6YR|kZFw8F- ztyHubiyV&|VXg;nLMX+s(fqUh@YtTYeFfNe#T3%ydw2|dg|o5!VFvoGL!+MQh4gJh z--2an;+}rr+**17Y9ae_w1*H+>mBdVi^p6c^;%&*CEhLK&v&8>)>67J5e&3cTot&M?Gq`4%nDZOn8rvy6|F8)z8pf|RTG&U_h^hm@lxLftpWnb*F>xPi zOBb?qTp3e!7`17;*m|X=8WtOr`J%Kke{;sAw|dkh8+bM;uamo{K}vI&_EbN%VxZpk z))=B`lnC<}8xZV20So5KmA)^` z+ZRvSZc$%BHU_PqoX;-i;9D$oq#==>y*Kn5< zRR8@QmC!QPvP3}_eSQ&Nocd7PwtVw#vEgBS-Wuhb>@Hh;bu9JHczZu&2AE?c)r?N> z@{A+G7=C&8}%VK zR3fFx@G9+ORiTGU7Y6B{ThwnqD0ajF+oAGcxk>(A?zrLi=L#>YOQIP8X&v{@mn(?c zVNA1N!f+J61*N@1dew8_Q&n!n`T6Jtt_vy$f^a646N^&B*@txiAQlg1&tOcp2vSRB z10^rQLx=`CUQ+WyQM1qa-p4CTer;>N#Yz8obf5k~Pi7+@D_`vygzD!x@A)OwY-V1D z*swvBb?r zF5F{2aC&v~;b_l}nJ-6Bw@DJh*ERV=7lD@TR>v)%Fjl73VrBJSq-dd{{<-3JgI9jJ zX3IK1z21iVVH-sAD2(e3!9^8Svzc+D)BY%s$9&AhPvgbB(?xpMa64qhWcv~6iHD2u zbkq{#jHA`^InWylEN9d2HA^6x3uWV;cS-ilQHVSlA3NO#h8E(#9d8;_ZEoZ@iqgy~ z3?^vB^vkiaWY52W%M^+7ySfBmtJDqau^*0B>k73O0|5 zwO=cC9IE`VE_!xrkIc&{L)OeuL9;Zcj&l+i_&js_$mN8ft6{|k3JnpX;gt;vRztv_*p{flIHg`PZYwwP8_`j%W$_yJf+IeM^|nR=4X#=W`*Mf; z4jqiR8OhUn@w{X2wytsz4+5NetNBd!)Y?6L48I%;ZR+&}cS8it#%cr$ZcFVPRs*#z zSN7i=6lY#le>d0 zoqT?@hzy1qGg(Uj70-{Kwrls2Gs+a~nD=$&t@JZ@OW-VuKf5053KAUgjy#GDKb8)n zjbzHrl$=lR8|Tr*G;w2&qXHC6He41bJRH{<8j}}g!s3c#o80V;BO?DifTSx_W+;V&Jv@F z&T%^%x7j|mBm82zm+5#!cO^z~%{3^d&*$5IaGt4R=$X@QK1^I3)w`Xx?!#X6HyT;h zN~eb`Wl+^wC#2_dmA0uJ^s|s*FnP%Zb6n}|-MTys*0bWXH66uBbi$>ccLk{z;Sg;do$^eAmo^65uvHssxs38zq}bNy}{y{ zT|vl?v_>!fD8<0!9?t?vcu!;HfdgHi$;aiqf-{lx(B zY|F;969xVla*MML!N6z7V`Y}xD~bHO=(h`{vySJchhT5}i1=JO4Ai){HzB0g;YZW4 zaE}WOwc0Y>()5p#nLMQ>miy{S;ZQ@_>Mr%73u3+~7YIY^6b4w)rl=Tpj0u{|7@z4unb$X%6TQ6bQe^vl zpEWodJp-zIf#*AWs0^Vk(bw-JTdAN81@lJLS7$sYj?_;080N%Dy%Rz*E*I7lL3SJq z)M=(#Gpv^zXCEm{miLJO&eQ6haV6;YWeSawjb69o=V6U6+bI2!^Jx7b@-|_1>1@u{?%C`S&*B zsd0PM=xQf`)e%q^4?SjpYbvNPRTA1JK~zGNZUhF9M!Jz^Xz32= z?oOqoVd!q8yIVmzhwkp~hVP8O=Xsy^{o=Yl|KO6t%!z&W-gm8gEi4aXG2u7o0)gZ* z>zC;@p2kmVk;DBr9~%q76R)2!oX8DCn0VS18@O$hDAJxO-$&ELk#K%}6M=^F2X$1zi1-TDc>FS6#%~SCiD@An? zgbVZ{H+yx+lD(=Lb9j85TiM%ggWSAjlv8hezUlq8UVw_$PW|lvVK@RZG8k@DiA#TA zA=nn~@|SeJJ6E4RgFDWip0aA)B~1&G&kjW0b8l{s9l;$}s4F5wN|6yPV`fZOsf`a` zC6L_ynn=^`(HB<$l3S6}TsF?FQW%4dOAye`aaDmmA0nXH=K}*|;&j^vwpH&1-yNG4 zn12>;X>pu)9V-=5NN>Fz2T`+CAnJ&3nSSxj^FQ6N@$Q07SM&v@R3u=+wjfwP!QUTk z7!0Qn4h#70cZt%cUgf!jxE%` z(wc^zUIrUl9U~79!B%{pUs#xjNi(@B4_(_eXOg&?7{TDR8`u_lN=y9|S{>$g_WNeh z6v?f0y|qnijO@F$^yWz6*qXWQtJJC7rUiM$6#YaEFT;LDv;-wXPw%7QB0+=)kB7ps z9LMiyEM=c<6VRwPwugF*z}thT+v z7wybbr20Z@5lo{&`=7^ry#WGpn^^LKx^l=8x1RXOjb+rPbQDZmZmD+xRMT>_vSJXpiFjy+w_tEnkUjeGi?oPYVoVH%V}m~C%GtH+;deeSgO{dE>pj(TfdHQG97PbRVmEyVLCCv=ttPOM6W z?d;u)eC1y|7sR!S^g157z6{H^3D-pWpAc6YGt4}dfr91?XAfJjYo$^O`*J$FzaBYk zp`bg>r)xkgVe8>vBcZ6tL~f@5m!3SVS?f4~ZGDuq$VXCJRO*hBGTzlm*XC+IJ^N_( z;@hTz2joJjvM1ka=*FND0?%pL}A(aBWBo@b` z^P$J#d$j$YNHt%XbWulhJO6X$MA~l#yr%C-5Gn-am~=k}7|g?pN&S^ehTqlv*_{;2 z$Vw$;t>N`}#xCOAjdu?pE>}(W3!7KGIn%$WS}=Vas)(^2bXa}>d+Sy#`i#xDAMn(9Ep)lop%$qV1Xeq#pwrkzvBLser5)#0SKhl}zUL+qoP zdjcF;R~X+%@G1m5`sVg_>f>SK`$FXH^B6@-IKmn~;+K!Lum*CH7&zY-X`jXI6GAm* z^I%IPU)4Zjy>NH0tHriu{hm)oS1KT02B)^_u!fmeW1R7tlvl^dqx>>}uscsOAePol zOj+gUst@#?)Bec$;)M_8>iW`J$WJ%FQi6(UDe}D&w8WAIFGk6THkO!ruP=jN#?wLy zc~w})V7b@fhN~7GT4zVJz6kXrl)J3xC7bfX*i$X+t(JA-rC1~!w+X!KW&c9gbKKx9 zHl&2r`DJe_Oxrx?7q}-$QrwldVcKFp|0GZxO@#nbXnGsTXUTwB{}uPxMf0-EqT(4O zTAuZJ%pakZG8t~77VLR2Q!D_`KP`Qp*(aSU5yn`{RvP|KQ)%z-Y4NjHFEa)+KDPet z^Yo)eN@@fSPEig2^>_fwC{-O*8eW=H+!Gp+(@r=yQs=#er`ng1Djx`)-4zm zRAe+tZLzy-LTd}7hg`}^>WBpcI?*eN@iE; zv=ka)5qa`RY0de_I_ThtcwLbrLHSzu46;MR^7DK`&kX11rIVG1n0%FDZ?Saeu?$=3 zp7r(BS(|ruVoq}aGQLxa+Vfc{Iy3%t{y3(uyT^6J{Ct~Q{X`Kh`b=S;6NWfy%~qQg zk~d|`w0_q9ET!fqXPWMwr~KGQ-4yu|)9ul_+qkAe@j)Hp$yQl)HKi|T6#6Wthp#M& z&kWssb9wO1^D??x%LP`2nXFmo4WDOc$j?Lvy1QAmbi7SBb@kMZ7-EI;vqp`K{qWWB zl&-v1a{p=RJjc%;8`*TnWTj5&8wC-=_7(}jO*T7jnVH%ragTtZPVb0fsTDYU_?=MH z;Y0R^W8|dG#KcV6eQxvq(h>!3tEf;R$)^KiY3sIT{=jU-SL!OZ) z`|f#zr#G%`z9Lhx)dc-Dv{zcF5jn}8jaoYY@nE9{Asa!Po4h5oP_JYgJzfSSKX2$q zKaom{K1 zlPGWcYEe}iRrQLMul2Z-#@6y+nSF{-6s5r{<-7=I;$g+@!QlvV=q)y}$Z_$Guyq(w z*ulcxlfBhLo8vMVTo*QS^f@B<$!xBtba3q~;`7J$BYoJGPOaIZ?AXA1j>C=#G(-at zL}JflC9?#W!(nE{@!(Z>o6Gh{#i%nezxmk&f4Q55M`gIr*Y5#wR$2azVeNTza}B6? zpKev>+_0?eOMI-@TyAb6E=!u(t!FsLE>@~8f31w>3FcLf4CEPo7K{JJzB!cC+>q3| z>%5b@+ce@TuYdEPs&vV7mg>WKQ-e>YaI#9#MT!3Kw<+V{g!+lD&vZ;vR-?>L zI_bHltt=jQD@gjyzTT<@yEv59JCE^myA%D`Q&~F4EV%7q@4uss6okgGsAF=xY*UoH zWRibh%I{?;HQQ<0RL1Kz#i!J6fUn3JVKUS6sC1}i?tuH4pSS|mz51B>64wf9JspN; zrl`3XOZ_?O?n|>i6^(C_rH6IvrPby3?v54Zunytz{Y7Bcuaza~vHBO}jwRGVtY+LU zj@y%Sj`PziuS$wAtnpp163J8QmK+NkZ+;&yP?m-tBZaW4OcmixHJU$ZJQZu+%6i%# zJX?6+rg)oPdCxz*tV+W>w)_6#V4(S#N3b@#V5|=U881{y1xKz;%h$~Ms8#u&uIwTKh0^q?%x5Izq?Eko`1DI5 zGLwb|GjGR=6Q#JDd_N;6 zz&>|j{b|Kr4n#T6AT_%3*ZF=?sL|cobWu(}J4l<*KhCMRqu2=R@QqBE57JabG~v@< zD%>~|WD@X2RyO5WUR%cMLd7J+0;ncLahbjza6bR}lr-i&Qj+b=sgveP%?0w4d-+T9 z?78-?vE0PbPuMnuI9?#RU`!Y2Q2N!p$H`Ln_r2`s2?mIfvGew#$yyo>QqLttp^>j6 z!d&R8!0pVdRkM8>EFc!0m?)04?J9;9*LSD>uJCm|u4!Z(4%}?OX7JmWnG!*RJ}gq} zarjA%j&@U@(@oMwr;MkP2{@iibSGU5RqO3`BpeZ4g2PaOuJk+<@Df3+2de4)LaXdU z?b}7_T$!@;dcSX^YRvEX*`OQ+*=_X}J90%^5OA}YJK2knI?&WA-Gl?Yp6V|c zB20`-hI->9tkCCtkHf`{+H`lj()$V-EpJdcq}0z@^Fup?Un|KS9i_lOO%ZIjxnyPu z3A~P_Ny;6_V!4>ekKA<&#lHx}d8IV1Se%s&i31n{S=~o739+q&k=Jqq<>q6q+J~V1}%eqkfllvGqfXZJVuLPQbWE)Tag zt?0SJpWF-?|Fe)oLYLdy zTRt{6wkfYgAw>?IW{>^5w{u5$M2TPHh}<#Z=YJ>fW7?2)Y8kDfU&dML7%g}$&m9bW z6W}dW+qsEV=z0B6d$`nQEeNU4dAdB9Gm=hb3q$i%{>Vk^M@d*}ya(2c%`?(Wi!(Df z+P(-Vix5Kq1J5kLr0qa*cfLEZhq&{!^z_L7#i7C+;-#cCQC*<$^APj^G}IogY-}h= zRt`*8=%a4$?ELY%KK>Iex4_&U3~b_ro{B?FHV^_ph4^KIMI^P~9& zdoy4x0Doe9Tq=pfcJ)d8DV9dX?dJM=S|ToyQSUbq9bHK$fbVCkcRot1GVlQU0IX)` z=G-5zPda?|n+!aFo&bKw9q6C1b8Fzg6!HBVkzRy^sn=~!j~es!PyR^Qw=d!06{BgH zT~F5+c6WEF7<5`KPPa$1*&rtXBj}XbWbqE+`}bciu20rFKx>4AgiDUwBP;YfO8~f* z;M?bR&;u}QN3+Eu_=InVfu>l-j~{#FD+d6k!MYHue5N#B_sM-&XEFKO-T97vf!oEd z7YPZ;=1R$|E$-AlJe&kFm`UFw~+3|O2dBIUKa(0 zv2qfjfE3V!SOgK_$-|v9S#LFf1h@Ra9)wE7V{&zSu_p>S0p2E;rIi)Y>eiOZ12k9C z6SSsLYjIPpR%J8{V|WC{mrsjn5ej88S#JMk41NNLiA2T3#P*`SD59wnn2m=hpx#%9 z3vZ7WTkK=*z_9+0n*Pf05(#;inWAde2f23x|f)Tb}+C-h4=ZY^OBFLI{M7k!C*mtuZ}EHTS(c1nf3& zA-Gj#n+A_h!3jr4Tc7K#y-Rs~Wml8XGH!4cweaw2ogZ7!yO!JeFkyq}3b-litRr9Q zfPjFV;2&=?`y@(*OSc7!y;nPfGC?y`xMC1N5Qzwy9ugL2^=2+M^N?(fJvQ!P7_IS zw7BzV_zd7Qld@={5JU0G2#}-r3q?1ruCA^q*x5y(Yu%x^_HvNOTQOmXYSEYMfHK(e zXm+dlZF;o;kSJI%81y-JN(7P)ijwRTbmIZ*g3;tduo<-Jz-|)-3R_jc=h1ATLB^Gq z5P%M*#;`xGBqo${k1|LTVi3EC0Pceb)9=9OTACrkhd@VowYvtEs6+&0YNAn7VWp*3 znqE_bBbh?7;%E&owb<8hDep+t^78j6n3$mTv}O2^p4f{<60m{Yf{Tj_3*{CsRUHg_ z4F?jPZ9w;=3VD~x+zN1N&~Xhreo6#P$;7ZQz0RoZ2fsc9@UjG@?Zo)_s>qeGUY2c6 zfSJFW=-YI;UI#lw5A7$& z3K;7L$o|iB7YGLAJlZeDVNkHw1>$1{qeV4H0A=?)feNTv=zCiserjHG6v}1VEvk)1 znFc%sj$lYEL~k@K_Ij!mFxg9#tb*igz^l5Kh3G)%KD^NYx1GDllc_)f`k(8ToPb<| zgz7+%N6KFD9VYUiufXm1fy+Y1d&r-n*USF-q%6c5%4$d6=yb44-O>i~>U|V13jz6) z-!br}jrYW!N9UwEglPizcg(`fj1-G3dE09nrH##LweAfd>J4^IazsmW(m{c_=Iat& zR|j)fSvelBMYP!=`e}EKB*2*;fcXKMq46BTa9oJ=vr^MyhdB1SFGLQPSueG!N!Er{ zjsk?YR9WU7vJPY9x7@$;(~^=3X{agLa4DE08Ek^zqLCNmLn|J@k{f3ojo@zJ zq6=bTfX5*@C7;jRJ~x^Ijho3GD+a-jMv?s5{$59MO<|f4-6)w#@yJ={oPJ=;CX@NS zA8+p`$qP2(@e8DB3ck>Ujgx}34o`9>^#tZ3$CU@9<(odS%i}{F8oHyCB3@bw$?q|- zgXsq6#Y<$M8$_}Yci1s^7Iv`Z*u3~xX$VG)C`9|l(l>?WrKN_vIU74fH5$a88)abb zwMWYC4g2&RJG;Dws=U4`9yoZjj$R(WA;VJK?9-O0nYDzOjRaZmSMUo>JTNU*H43-{ zIxkMA2$ohfjooM@;SUynVkFfwF~L!KUxptO5BO5YHy)?)AZfraQE{Ln&&kQb`I(z* z*mhq`TKg^VT_KJtt+Eg+YmLL`5|&35w_q&tO-gvvr5pC;7B=HI&ceI`XGroUoA*#o5K)RA1K7>gl+FSUwZl)5pFQ z8>X0;nAP6?E|Ils`K5|K-sU1#WBlTfx^m3k*dB7rh*H&xuMItjP%QILzG6Tg;@6Ky zU4yCo_ns>sYBIdHx3@ihF%Z2bQ8O_yVIh~*o1U4`l6RneoykNZGcCdUHYv5eL|k^? z<91(xA+;!nqUSZW4N+2mVRH!P<3SZ7dL_|!N8Xfy903+&}h9kNy`}=DJJjj)17YaawnUV)LCA?87 zWn+7w@Hz9+G#~s%jzU@51h@d^pLc?>ZyI)DtndLYUknmXr3@;J91M<@ogbKtWh#U& zwhnw2^`{N(H;7rKUE-lZlB^%i`0hyv9^RB{x9r9wCicb|F4}Jm)$A@bu~XQMriaHh z^C&h(OT}Eg!EQin$XSpvH{Y{f_jb(|0m34m=KcLcEhw#BU=z@QeI*Cupi;z*6fRvi z%zq7VuVMItqp_nm#0HyR63nn6G5Id&t%uUdrF6fF;gF(_ryPi`Ck>j*B4Q8&Iy@I! z?r1D64|o`OH0y0v@@veeh~kKh4Gk}NuRH+Sz$lt1?!P-KO_44TeHKRv)0^&TC@Ha` zz#WdVdh=Rb)~ChxJFeoU|`D~&3aP1{;uj*+3bFG$Y5x=0b_5H6A?_C z2d2>rtdLmh+w|_Ovl+om#%`YVqu1a~tQvaYJphi*zWaJlR1~S$?d5^{m!W!qhz#K9 zC5Mq>%ZbQ!bR8GfhHDG%IulxwJgNLqgCir;m4D_|OQ(CoPlu?P2C|zAetdEXj;D+& zDlJX>or@BS&z;0a*^$MtA;`+gO8jL@gU#J{B;yiC)FgX>2~YqCGgtUokX9KHh_MM7mG7zv3m`>=yHy7HxAx-rvGP2&2KI#T*4- zDFgh6Fj6GN_mK>351PBFHw-yLegmD9Gi$uzbb(yXb=dXueqr%?c3WoU?#i;$_U!MV z=vk)&3Qbn-#I0yz*>NQTml{xUrn(sC=b1}s{{AB6Kl}k)M1JM(Jj_R3APH}#*nFA! z=wP}eWd4y0L6HZD&L4qm69Csv{Cn*$p@fqrSD9a_uBaCdCHw)^69dblUf5{9WIsbVg|3K*#V;}yY@8#B;RPJaoz3FKaTC(uXl3oagQq0956^z9y zV9fsaMIZ=^U=`(Ge^YR$Atzq)`cpHne8K#GK5fcqF?vFzQ-2Tf8Tqy3~sHiVXj5A+#r&EBM?HgWnG6sj3>b;?JnMHqe z9S}CxyhhbvGE6XG;VDU36ljP+FBppmUWZVAfTf{hV*ysgcm^Fd*YoW!_)%igNi42v z$^w7uX%07TnpSSRhuuREJwx=s{Dw8R13j$MuJKB=y@yVtKf##&VE)|A1SW^a>(oZM zPmo+pPBzk^?iRctS&xyJ-8@uvMq9CPVS2g@o&{^J)F!v4tF5x7eF)UGaCcS-&2o>! z&FP5wSfalX>!^Tzh(Nr3rcurvOaIFutxlIlUEp)6M zm`f3^RGa?Jr+C>$g#uIpTep!jE6G(zuTIvwOR#BG%fopfp}-OxIm#FCMX>%GP~4XR z#HZBkEa?^IGu64=#D0#0MBSg(YHfB7Cx1s`DqZGowO&32F=p!N<;E_MG++a@ShA=tDoxt!iN})vU}}+cxZ$ zJ<#U)A{!(@Ghu1pK){wfNHgdNko|*MElmy|mv^tbqPOq}?XL3YAj#*#2~qol)Z5uw zU@+BKra+*q#4O#4`-|?|HfegYx!UqpjUhdFq+P3$hgs@%|FT_%6QZ$8iG<%WXnBVJV}%(hC+27CR*ixcI?{b}r%cZ_$fLyz7x zrRI9;I@+u{l#_NaOz42>6c?JEK#*CRCm}B{m=))PaC+&qJM=5JSqco zF{6`O`4Zsk&bG*EWYPiCHYryV@LM-9G{nsRyA=Lml~uBn&}0$<|c9+ouXs0MO@C0s#6{Iz*S6z;MhF2yZFMa4-OF+JV;(rNt#BZF(h|etqGZ zL7Ldu@#gDOv0RS39`yfg5tcw)vk2QFqA9)tai|If>-+bGa@(NIAas>ZhNBk}Let*2 zeNU=ovU91ok>f0vgRxwti&Pi4lk&r3<2^GQ4_FU1r>kbrzr803TdxRm=f*DDYD*Qu z(vYmdvt|!Tr=vY_B9sgOj@IfS%=*ErBnaujta2%;^(`~NyISQq??-^2g~MW6HL*9k z6BnXlq5XI~v6W{k__lwjVk0oIf3lcprgufu%d*j^^W`4Fbd4vp!Mx7h^YX?hKBh}S zX=+q9U#)C(D-BL8Et#eAN{{Ys?1R(E)+=KaOE#xHTc}R%pKJCd;!^8c*V!Lodl3y` zLD-X79*`w`6=T85;anxHgIoF*s<+aEpZ+kMSWcK_oxC!3)@F9r+Ph2H-hasFkbhRD^I9L%{iAQd3BYl zY=P7rj=E9SnxD|L`U}EHV9dte1m;Lu-hZjssf*g%KhubG`^XtmsE|$#4IR?#^iku$ z+>6-K`Z|?;YY(s!=mGCi%aePG>H71kW5u`SJj+c0e3;IVfEb7>tim%37=4fKAu92>1XxeU#gTX4@@$hV0peUF5l|^qA zP>i}rs0WxM8E<)Ts~t=ZsKBcd<*Y2w7?HKkAkFtcYObd$4eek2&_8^9e9VHw0Z4#U zsqo>|(Nfs&jt*(z-(jJlt?^27e+!$0*s=t~DR0|9JS^Oz*5}APFSCDo9?u$|t|bj| ztCJx-B5tueM)Rb|!LBLI`f~n1fTWd>fd7djb&b>Q{5>BO;}JE>KL779Y07^Re;D$bvAxjgFb0F!%rg{s~JpZF=yU$@jV+`e(UL~?GwLWhHwCm z`X!i-;G7SmqTlWx-57d4#mcofli;?q5fHRaWC-}yt$T}ff0t9s zZpiHG9_GXQK$KDK2Y2h-_}Oj3g8S9E&4`=lsb`jg=!j?4nJn3?l$pXr2}`Z1;nH-! zAmyht>2HiQtYCo>QM#qtO8u5$YcIXxGN-(=oCs?zXU9>!=)8CEiY>O5PD5PFe2G#K zo>%3Qf$+0E;6OyO4(wXG^lL8C4#8%luw5z@V&46c-%^9J&6S7r?6c$Jck|n2vDjeJ z>7z;S0~x;bDK`t|jyvc9A>wx(TWx87u#$9)xm1@l{NH|oxd!5nL zr4@I>!J7`O6;Te|xlj1Vs*z1InhtJa*0AQABu{;`gc3GlJ878Z67Z5D$^B(xl1T<=zfkkqg+b2d9nN}2;De9 z%7S@M*~@Y?j`!_=R>l2NF^K+GP9QSAhsV(KtKL;m!7?{DsYC`US21IT0&YD0(k`7E zv|{XjIVN2f2R7t!;1G$oFV#o&wIOY@tDM5@ezrtdm`xu8IJT+p^&PWPJd?Mfhj#=pK-s!4mo6V9GuPxYGbdG3sBJ%|B?K zAEzmA&6nlK`2d5k`{;-K1VC+#3^^P6*reB&%B9-QYWC6w8L#8*_+#Kb3D>2e3M~)ZZ1pD5~eQp z8hm|sHwQ#Ye$>oBV7YF)4%5*3@D#7~Ise{daA8t=^wS5$MVT}n&UNpnyCvbMClp+! z^_;9Vf&AjvYfI+o%_}oPOdcNJ`cK!8bX~ulEuQaJeEpniS5_kPKQNgLDv4=XG1S*; zMM}a#T4bC@c(@sPc}a-xXow`FrIq@bLm)&dI?++8DJ}{^>B-2rbzi-2hc{7YWoKPX ztcJOa?FV9_y1>|dUJ;ns*gt6w-{&xoHL!>=Y2UuIM58V=Gpz*K5fk4#|M&~VBHhot zTbOi2j_EK60~7saKJkl$H&qvaJx?N#kg{BAeei_FDlq~teX<7$pO=Rxsj0qR6Beh& z=3-;ZI$TL-I~pV>2PkyQzSUyWUHD|g$0^7ck-p_c0>gC9&*{m18CEoYfeoJ_fe;-X z&3ZZn!U&V?B`V8|VxN)xgd>PR?#+zG!vBrexO3z|=c}uzfohu!!%;Rq#n6y~5%sR7 z62kF{u@GFe6MssTyL@t1vXCw{Qp`+y^my_R!<*EUm>jABUMB0D@e++XuISCTJtOS} zA(t^qXz~9tlc3$nk~?rt>Az!O*d*@@*klrKs)Gn5ixMu@RkJ@t8rQ}!) zdvunmaU-hf%kn3o`5~pxq&9PqnkV9i(}^h1>+>8JVhiND%`|Jdqp<%}4CQNSv9|9? zCe>T2pOSwIppS7lgL5z{KkY7i;{;hrmwq23IFy)2UzX0|dDLO8)mf3Bly}5m<6R#_ z9sARWA=e=4%R&nJDXWjUYyjLp=+Kro0iTxU{RnSXi|fBU0U+mKM5o>CQq!{vl>02HiZXylCQ%zylRYS}x|Ba7SoymItSCzngtAWLC(e>kY)dyX~U6ZbAx*0zcNID46_6IfG@R7gDlYgD<5 zYlWP_|NdXvENI01UNI|T#(r|Pusp0a`A|=f90hEJ1LGFg6Cno^n(H;Hat#iDnOV8& zwtMY^BcO~Hp}$DctfBxH;bCmBdxmgs>Ao{GIfvA{?7!Ci$~qP56@vKEBXH7^*8xYP zVcpQ=87^a;cQSffb^yUAU69Q%5kHq=QKLTN+F&yEYWKZq62vPLCpRy#lwMtowwKiR z85=`ltDwDv4q;w^t(o;!m$O8r^@Gv<+0vv?slJYwf$9jjb+={KxxU5aar~mTYj;Iw zzKmU~X`|f&JO(EnK*zUK7k;@1v53fMSdmx@l;$Srhcjd4_1q|+nkld^Mi@WjX+@vPYZOi2i4<<3#e3n1+;Og=%h~@h zbei7;TT5x8gXz0pCvkAX zsg74SR}x7*hI{-i^KP5dTkiJ5Ds6YwbMcQr&PftO3tUSX zhg-0Yo?=0QJ8=Cd;JsK~pm8=JRxpO8)x}o{{jN$kSNePlm7aLPb39o8L{oicZ>1M@ zrSpBWE=PcVaPBJpePEwgL83^LEfGyXI$!znbX8lg&Bz}9Mfbg<(EV4@fF#q|@Yt$2 zndFBfqZ64o0DH}|gy7cX4m=?7>-P?luTr)sRva55HxsotsUs`PPz(4-+Url1h_7SQ z*K72bY}!0KM0-NMWo8qXHr-^Ij@oAhZ^AM*3-j}hKk93&7H%tG_N@9(bF1R;AmzoD zG50Hk^CQ>R@|z3%tNZCmyUO8`jDe)jluR-y&205YyT7bO>Rz9RE=(DlCNZEad0qd; zIa(%GF68QZW7+t$QR{Yb`ln_an@1YKM&B<3-hrBoJWToJTTBLRs$5b{@B6-l>Yy*O;DWVz)CHjD*}W7+5+E<{Sr%&y_7qaoyf${Ui{l0X&^s#2^3uN2fxaon+v*;x{EyeLcJkl!c2qh zE$887mYCO=#T~6}?hd(YGJK?;!6X%rjJQ1_l7`w8lh-W&++*q`>b=IaN2OKO$PEkL zZ+5;C`hF)n=AyYt`?;uE{o39Nn%-oJhOmKX!}*F+#!2>>w>uI zlnF?4kpESZrN)b3(2WKi{!8O%qg{IR`3FU+0q#nG1&IT==dnELxldN}^$*n4)H}J@ z0Ms%z9ViB&BmmV^x2T)5&B3`0SeAR+`5$Fk*h2*ZDJh_Cf&7mn1q|Ev)$g^F>3`-6 zkigytOwPsev56N9ZnJJ^4674;{KsYkS<>g`f5rF!JH)pxv;Ma}SXgNGSE{Nln?gFN z86-^;`Gg5PG4PcCbxx0eg+7xd8vGQ0yCO6DUi`(Q0dFl974~u;KYH+`i_F?%tW>Dd zwgQVAcu{|Kh`obhy*d9V1H}=^j0443YF~YcRP^VDto5goEj}0y0)W2gxw^ zDS!fi^bGd&jQsfV!v=t21qvA%}x&JmPY1W8FLrn=Qh z1Uct!fn_jl`q{tCmI9cJ<-}>d`On}jNd z$3W7yB!YBRFt#6n+KKH0$iTv$Ay}~fSE=W`Ne&PRc64%T6*JqwVrAgF0d&|xO_C-z z?HVkCv+N>_f0zI>xAwcB5Fi*87zs>4fGY7W2Pl4yq=${4f~BO!`*`^PAsN&8dfPi< zUbk_IEBvqTAu0g8jHG~E^zrWobKbNwQ?)e#sO7C&UjRuOnRpc`V6?P>3$32G{FT%x za(yYmqOHcF{l=^HSW18d5XUTB2Wp*)B=Z0}@fnQL4};|ah6h9i*n`br`+h(3U&*=$ zC?HdS5BfqQzr5CwGg(?uVQb*p<^N7_L*T=^kH$tuyFVUP`W9s9Bf8gqbXAo<%tN0WGYw9E<^K!>z{58>W;6?B^tUjOfXkCKFlmvP`7?Bz35ZT z1IC-(Vw%zV@&0BHoSX~Whvbw6fCgy*YPp*Oj((&uYX$Dp3Z(M^1qCI$kL>U5Z3sUi zzyMi)fC-+2$%6V<>aJKE9T5OMQN4RT4e_HhH4+$?ogFr$W~xOvAjl9()j?&yZMi|j z<~_Zc?UeVmMaTP|22xLY_46%{Z)EkVwT6fa65ja8w}f(&YrIPu@YkhzBCLOF??l2& z{5R#Bb*Xix1i7X(PL64%=R#VTy7DX_$~-|I9Sk0C{O457eJ8C$zr%$Dx@CwOhFgB; zhzPe2oq5S|O4OcH-6lox#T^lQ`pprepAKZ}S-psMoBKh`Eshf6qlHb=bwazXuHujw z_p&%D1jA~hFSZ}nc^90-z{jU;+!cyD2hck6=JNoP5B=snqW2GAX|IwE(qP2&C@CpP z?=3W4ZJdU`0d{Y6@cd@h@g|1&3!`7}LiShwZ>lyX{sqfkyPSSGnEaSy_L?fw%$W$9 zORnz&EKg`J-TD+#*-&)1`kds3rC68X;?dBN%;U8K7V3WY^VUMKPFdmUm)1k>S~{5R zq-etQLzB;?l?q*^gKiZ z=8-Dq=g*%Hu&A$>>nV}h_z{oIV)~?1tEn;0P!m{=@A`;gMa62wq`b_`D9y!ButNpG zzH}V8jlZMwQ_665#(y2Epw+R+^^H{7M>*P2WB4{YF7LKlW%TEXD-(J7iF6o0!M|gi z(N$@pPS~UR=7!0uTBFY>eDQ!v@A24Te$3l;DK);qoQWK+CGnLSlyi!dLPQ)L4sH{~ za4CKVAypxb=aHF$B|)!ExT#TcJX_wNQ|zytxY)HUIG(QeHi2IxH1jqUe-(jTicV>$z?C8X6kJ(4gtfv;deGW#rer=uK zxQ&hUt6`by@ww;f2^9T+KKTQ76Y7it|fMwBphd{tW4Y?Q5Pa7%>#p`KHealM}yF1S0Sc>(+0id0Wo5db18ltOn1|JEMq} z-bHHJC$4_%$Ql&VlW|7Rm@Z^A%z@KPIQUY0+FQXbAu&?ifHGcG3Rg&rM=JPr`El*p zb=tYP^}m&Eem6Qn37fxqk*^?`Jyq%5-7Z^{QSGAt&efMC`L6X6p>g^fJv&h?!QG1& zJ#Aqlzr(fs@^D#L)_!#J*WaRPzuYLsRqqF5NUjyDw(|6=g=`H6&V zh0yG>3disOsZ=48yfLtrAJR9outYAwOY{k9rIvfa=l4>igY3%sT`cX#%Vv?MyW?l5eP$dO;3ZuC>+q*`lfEpWiR8@ZFn zq`LKmH_)~7i;HY-r+pW(FR*z}YI%9O{HI8Kdu#%}(XsFilB~ZEh%jHz7>;gG^)u4g z%0?5;_5}Hpu+@LmUaDH9Jxn;HQf#oSTn%|$Ml;LML#;2(32OnK%@<#;HVN2eNmV}E z>h>OvGB$+-ee5c>{eMcg%=o^OK0pLxy$f8@9IZLssK66+LA$z-^5- z#K`?kx?`>TkuxbhqXD=4WXb&9MKQIXUzd=su2e<8Se8-9t&NESWxi>Cj6M%L=Nq;s zdt5e6M6|62jV6|FYD0~m(L^4d(>BD{vBn=M!S{4HhIHB#*RjMFbBt(7iPX=Z=2WIn zm>Xhr@H71hn;gAv8NEe4ZD*zwf&&Hc`M@I5zj_K%m#ryLZ14KeiCg;=_$qHV@!<~Y zE&@cmEZ*gf`)3Tfx0CVgnKvj1zIVy!%;x#sgV3{`YEo0NL=kF zDDk?tt!1lBvAG_vUBjtza}fI3&I1d0X-~(kD7ziTDkaNTB+BQ{(EMw*sE-^;=!-_x z?ugE>$&jz>_y-Qn)YmUmEHLo9=yzYzh)uvN84bN&``)2DP|tikay0db0XPVy7g;^_ z^M<_feQ>Zi0T!&RLv%=;VF>pb3#Y?P8~_6pOBwufSR3KO%-;)g;0cYK|Nf@L09?51+4^!xj-xhxRTI>_|qTG`(r6*6ufZORP~z`rFXcviwq z^kT^X??2KiM8i+Ft4Ny1*UzK0Ng5_4gsQ$-W+rCSH@iHdIM9Z**A`OCA+sT;FTs`0 z&my39R6#%BVJX{ObUrH|{rW;0X?eq!;dq`Mw|Gy<_fSSu*Gh+QC=~~pu#xb^aD94j z3q2h`Wx@TfE~dTT2S1+wyUvT3TJDp+4UVUID&K`xMV@vee}8ZL>F6`HQn%7FKDSuU z@74ZojQ^BQ+qExntTmsGw)~2n?`KEG^FN4$*KbA{ZGU;Xc+@lJ7wrAs z^i~(xv%UIeYW4>IC-)C@x1gmLy3nMl8Gcb4*S7GjB_y}+NsNSV2_F%;CI&K$CDC=6 zW*9BBWnC^wF@`)OVhcRhdGkCeoPBZWu|5Y4$wthj3vXZ|wSNf+=OxIfsG*>p=XiJj z;Pg9}VaIMzBVkn&J5l~_Q4%8%rXDl3)SNP<1Fj~3K4%Lpc!^A16mYSK)S97Z_E#^k2Dg)N=p3_=y1~_)&Yt>y4=O z)$L5)E?h#b9;kTV8i87rqTEEv5~um3%Eh}o)Z(=o9r=jO@lqAzmP@2d5M6i6uZK&U zk$%jhQ=V~xklQM`WFBEQerGmkfgaGG5(k#)W+oSOD4wVu8|8XmY@ z1<{*^I1g8jm2X>2dL7miARm=pK9@##WhCwR-B;GS&&J{m&B!?F{UCoS&E`xG&bsO)*Nn5wUqJ7vP?1x^0t0YaP^#z-?u0{@m-IQGed+vtav z0mT?5GaHQ8!OXtM36)-;Vmw_03$4&}(c4plm~)Jjem>Rh}#q^;I1^)oS-rlXInSETA>>FR_iPt$&Ga06@mC&xXQS z|FnEh5U)SFDT*^oi6?Fj#}I5PM7FWgAk6oDZr4)X_pr)r3(ykih$5!c?;_FH5Oj7Z zg;mzRA>g$!{aUnNR>lcK!+KVQ>1eqrK4Vu9fkS);dE{wdBkS+2Od~3xe55pr_it*0@M7J^ zJiz+k{NfDeTnhf|^h;&sLb~vSy2`JdSOYW4wu>6#x-@RUy9G?@!^8Q3G<`-#NWTkVp~lx(veL@2Zk#LHuX;0_!n(O1v;>v8 zkyt_#B(q-PzU-Tmn02O`ePodGMQ7U?t8>}n-Zc~!CloOy)=E_B>~)l|7@k2`aSs6) z6*Fjmbr)bSM(eM9K;3QZuYtLR9qSg6IY$OpcPHlST1fEIHcdU}gMubBMKktKL!%u> zcZImm*-8-0y$iG~LC^P2v(0fVL52L^9k21z(5G@5AfaEVNBOZHl#j%h&zHX5ONEEA zJB?_fGUt(Uz)x#a`w<7?-K)^I`c^TYm6i+Y9>&S{RcSR;2@kPrx2BG*#w_KNAE_ox zpsidE+@FvWbXhkZ%g|*i;)9D#F%{n%&lDfSx_58oH;80|_3%X_wkJcU>*T`rX7+eq zGj`nR4|mo(Kn=zaUclj-F71e)cst*B^>@6a>t`aECaUs&7Lqks(}J-rI((PJ>yc0b zUcAEm$p|aON93_`VK2JQB{IaOLzLLqts~3 zcWXC37!N&~V(fWfMY&yMd}CBA+a&iDNjf7vW8FZ-gZ>geNgwBl0OpapNRZ^wg=4gxFUl2r@=hd-KPrO zGA)CtoAkl8_VfUp9vl`b9PVaV-=^E<^*L}!f6)<9+93vW-au=0upN~gN|2^mTAHhe zkmg0J$@CG@B+Qyt!mCBXX=m0$<4&&Kks<-K008Qn007yu!-Z-uQ)SeITa8T!~|9jmVqUC03Q6{^Z#g7^c%0OKOC2VQxggce+F?* z<-PkyUPGk8XgM|-pBi;TV37gEG%ceD-s$JNebKZ}T(;xS%8pVPaUUx9CSC`=Y}l#H z4A83-rc))RQpUVvoK_sG!m-7H%a<;JF}R3YpYV&vo{G%c1Ud?0Yio??4-1xmGBm)A z66o7OlHcs_X_2Qqs=rG4bmx|khjL|>Z)Hz6%E=2KoG4li;ioRH zz}v(RjyJRrTTGYq1TeC5!H+ih#H{!V9BQ^qfKyI?Lp%fjPM4rHk^R0Hcl+ZMJeu68 zuP3<^5gSGlmv2TE3HJ*a6+2C&6)EQ>S=vVGWm=k>cSoj#GC$k_NBF|h@9`3690L{p z&y3#HJKPs1#%%;Z?(Wb5n}fE{kc1?hfziK$ zm86EtAHcrK zLa?!gmVyY|I>ATF{OcY6^1H+t8Q-c@9#ts4!tal0^42C@a|K8)-1G9u;lp>h5T;Ey z?@#NKANj}%JTqp;9-J5vWZYU!#8xhl1l|1*kUm&2qmGoBf=SehT1-6Zi*wha)i+3b z__CuwMSV?|p5hNr9DHt|hG3m#@YOwS)q^Y8=Nn@dBqm?X+_FEK{P4WKarg^kQSReH zO(}eJWsXDht=HID!P=BCpge8on*mqTZTk6C)eTL~+1?8&b3LQV`Oje#m&FjxE4oLG znKoST6aoIgHXCCtBI&(9)GA*1H~v!b7wc3{a=`^H-5kh(4(&CZ2$-?72mdB@XN~rd zJcbOPJ+0aX_!)mhbY;aF z9HR8~n}&Da=Rk_cNFK1z5#vAi@9~7uWDwJol7+$=%5Tq{_bM8pX}_USDlfwVsy%-c zJq)Fq3{B_g^47=DP4zn6{Z{qlwQ^)T{t-CfO>Oc0@oMw2?28#;%1ny8;byA9koR5swjQ|;l$JU}f3*;5p9dZ}##@5BA6X5o^zW`V z;avi9w7P%km;a8ukfRbzKr7zUCH0Ql<>`pe9mz1tavE2yMj)DZI=R^Wun1Wqy$a!* zYlvPckGXW}=AE84gLiFmthG4Yn7Ijuc=Lc$%)JSjTvwMdRP&;ho(ZkWV&|*)OwF&x zJp=v!Q(&-ke^X$HErF9|3nLpE|B%X!OKny(b2`s~!MF*3CloXor1RYtl7bf0ABayx zgo|M{tm;r$jsg0?78E3gN;)mVJwG}CpIpqtOIrdjyJHJ3gkzN&QO*31+y;!BhkC|V z^DL}p+*6t@YQR#!5-NoPr6SOP{kuM5FTmXt3rtEs@N@y;a7!4g0f4vwvz8ZnueJ`H z(@z*us>;cKD2kQA1BRT<_(8Gq8Je!9<>nxal{Ql_m-lcc3JNi8XJZ<)_Mp6@d;XTM z__31wsA%AV*GKD99M1k0?$9-U%j62fW1~xcF`8TlFVScA%(SmsA9zwe9*n zXB>+cd!p!f+_v>T?{=R&OYqXFA7j5WOUp}Ov`rKxp+wg{md|KS<(g?_3%nl@_qZ23 z;fEQ3cyQ>N^lB~F&!oZt6@5%1arK$tXud4o&n?3Hsm2BNyL5n!`(g@x&W=oO$0~d` z{vyj$>-@D@>$Q48swIK2*-aUbe$w%Kg;M(PKw?@P3Ic_F>jw?F#NkV{oHy4F?L_}G^%$ne?h1tkn(ibmV?5^&GM{IRDR&1A0_F;0mnP*Vjq@E>mdO*#VRTaR9SHo1zUco$<~-Uw<%l$BkOh3+v4|> z1E=(|tWQ4?`DFMoU10q^g%H|0Gi34bDarKJMI479>kDYDx86H&XR-w!sDD0?n}X2u zMdb6!T%WzZE#Gc0yLY5R8aLnja_&}b&G?Qv4c45qS$n>)DO{n>(C%1SUY^Ye7mY7h zHxBJ1skv`wBk#@zZx~h@esQ_Vveh0-4c1j9>2czuh4m{={r+PSw2w8%vX%u4g@Ng) z$BJxY$B18s#ksX;=yuCVW0$-ASFQam!8L;{@TDyj2b)JiO7&L^w|=Co=Dw@RTCuZb z77UUXc}UE_QAt-*;)$GIKiUa8*PCf{yHjU)yspXZ)VeeL?KbK`dBG3Cn3gcJ)YiTd z;=#PiSM!(KrteIa91zraNdC08){xh5gWD5u1 z#*bh3w|;O1hC&i}y9ps7A<2s%+h6TX_?eiRy1s3LI{~9Ev(V7cQxqI5VDmKKhKlX$ z!9{3W>*ZI2pvI*eN^Z)73(YuMLb%YQMyiuv=l@X-;AmP8&L49BQic`wU3D52@jYk5 zjm**j`GxVjU~J5A`_4zzbXRioV=Xro@?`ESrKJHNc4s(#vAAh>wN#9@pmE3GW=%tP z@p(yWd3 zN}VK6I6@AGx%4&pZR@vz$1>Kwi;)m#TH9e&{;eUcpO|fAt9mzOY~*;{wcLX9w@%uN z(mVC&w>5HT(J)qia9FizuHVZ52qAAAJdt;}l_|japgESpVV^L(#Adw{9mUh*jVNPT zj#vjkAmWt$0r1hcLz=iwH6XHQUz8g!A*R_g#jUzO?y-e(QwSbP^ZARCp>DCWvVv9c z{;2uepAEMvPDiu{bSnGisC*iLd`=j=Z>kfa?b;_OfO(Y>mM~!b< zvH+h2;9?=b$4@6Qju7*p22uz<;TdTu|Dx~OZ~u__VvsJs>tvwc5yi8St#hR2hN61f zSI|Js2bCok-ULW-YTJm?6J&p_s;fgdS*SVuVOMmb0z7Z#H}Y=zblN!JsS4KW8K0^) zuuGKc9$@nUb87N79G40-=C0JdRb z&M(9OKB30nAF2o-24dE(J1F&$Gm|NZZnGXsu%vitq~l=?-c3%ufY~?92+tK7A_;ug zN@AwLU`BwrpnWn%UDRZg?`(Dg!f`WP$?i3^1xfVx`PRdr>>&Tm>SUY%1DcweV(QkZ z$PHEkw&d02e?$~|_+YQPJst=4_X}SxO{H?XE`%@RvRQ3K0b7pjdTAsmFh2lh)6|T- zyf`_98e~3ydW}{XyTps@Skv27k{Z;WWkD5B$o2r3_(xosOt9w9epoln7WbB8V}kY% z<^y3|zYh4-SB6%5TEY7e`xRZviM1H`Sx& zEX)-8urFEL*|r(pqCc$UO26uH<=JgViNWprEMoLAoaFJ|IbqUVlR{GYltRA$`e0U+ zE#w*i#jv#M{`#Dgl(bkiJuP>fx%0Z4=AL`7x0fCL!_*rw^V970cs&jCahMBwBGQKE z$FX{n9qOkqwVs`E>PS}1g#9DYX!f7SaQ9~t=!a|`S3=Tm^xY}sRk;cdo@`RCYy$p29Pm8ygz{H0p^MV8^-3DZdvC!K^7#tusR(ETooUQ*X2>7y?j+ zk3-m}lQ~1gwjh4;FeZ1r#O>|0jb4@MO2oKzEX*!{1mRVl-uN+hLEaQfFwUD125P2< z52MMpN7idfEfHN1jmI+T+u4N_MgQJCz}iIx3-IH>4Nauv>9P-WG_h|1Vyn)fp&~Q4 zDe<2_b(HW%^wiM{TyVKv=6=2TwJN;qZ~eqMJ}J^?yAO|-GP=}WQMq~{AbMtBW`yu& zgzk>bKI!r8(F@WaM#IV{b@H}oa0jaHX}%C?54I#ZrN#es;?lUbCEo|ZGo-#foVLA^ z)R->bkn~wLFHOyZ-vA8`-;Ty;xtcyllg;(9we;v&%Q4 z@!ifSPBG)m!R$^~2DWVqP{f2uY<>Rk4a>yN@mvCQuS0ZPqX(b(sjNi|--hMK0QLtU zKV5at`-L~wxg7AB)J#TE9dL`$hxVO~fl(UYCvrSJGb-rjXk;xbD!y5g)_ui0KWEV3 zfBW(x%LJt#052R~$fxL+mKvQJ&8~lV`$GfWJ3KIWlU2Cea2#<`EG0ZlFWm>!&<7lM ztK((w4FEDTRa%YAQA8uaqXf=$1wcMQG`l{|CUX6zvQ;i0+P%yLW`5(J0fC2lEI{k2c&T&xcg(%Mfh;e)Q`T1=Fw+yepwQmaC z8F~P6sNTlbHmXpu%&iSD&9)(2^d@xf0~L>G3ZS!I@#b;pT<*?XkIwB^U2mNMO0kw{ zz%)3Ij*c{{{$5IAdO;mBRH2iH)s{tq^>aLdO(*YVPVY4}P#H3mb=&QJAsTcn#I>Ep=9+cJQx1|g0 zDo_=30wIWUSX@G47Kh>YFubJX*uykT%3DOon48xHc%|xOId5)mm;ux(b9r5zq?Eq8 zw;c0!;SXv8m>a=`3y<)^-vDvj6cDP}{jCnFm5>kcw6#bhh;}gWE}4ayQJR-Rj@{SK zPp2lj^GOz1N__j!SGN-Ka>cyjbktp=>eFqeCQFm#sDc2zp97!}&l?dDu|vOI>GKo7 zVa)>iokE}@#Z#X~cM*y|KfT}tZlFS$2UTHMhm2?469;boi z{kMoMj|u>2(W%vlB80(!+u1-gmDB9gK-rDMXfUn~@a9FoxslA-dhc); ze_I0@J+DSsg6v`-%`0^}v9v#3sR7_bO2B_>naFPRHJda1Ij!By%B6Iq84+JG@|6aN z^ry>BAkUOg6M*AEoR=C%u5{d+VyV^H%bH){bf0evn;5)%{eTL9ADY|f~`7dzs;!$TnhLqq6k^-lzP`!hv~I~p1qBn^FHM93=u|Bg7& zv^~rSZG@6$K%1@{SNPf#^9!QUs<^{b>f6t#=d^S92ELU{DG-czIC;*GAhg>#;OK?7 zFGMu!o~_;O)Kf6^vPomQ^@6ul*IlG&8|Mu->gYz!x=NctriIJa7)v2{Ymv_ukJ19E z`_wfD_iaH8wK&sdFBb+mDOYJ9@P?G>}~0OevvWt-l5aha4Yx`41U0F9j5 z^UPImc9?i+I&EDfayIuLtR&%^4t{RKM}_ezP*G8#t9&dj+q*K+rY1#%n!LWcTB!(E zOhAXo0Y2}mEN2YTI{)U#6(VbbmkY2K1)Y;|C+Mr0aYRWUFRFSUS7Q` zIbl?3jZQTfVE7dSZmdrHSVbRA1Byqf9QihH4AtMlqRn!%Hw>U*{1R>+gWV@4 zDmtlKV142?GRIhJ=x& zU$|`B$(#=-FWAk$WQ_?va-SEcrXqjCtJ6J~voVv$(p?1goE&N>o$LnuDL24S<>(lx zfdH#~1?L(o>8p2q-B#B08|61^hGDP)_)Ek*sIZ~#F%ICZ$-0TXp$b0z zdiAqM3=r`7Ee0em$MgV?We_C=c@bb!EC7}g8rEEoKM=5{aMxK>y)n@o88XeA6(sT& z4ZYuXK%mp%*S`G4jDxoA=2eN$!o)O#Pf0oa3=kilR3erot1D3&rF0hQ2ZWqwe&mFLh?1WjLhywW7>BRT3Dkp59f&tun}ACMGBpP&vgF9&PF38$Pf^)NtVRrQIE4YZwAN~?t7N6BEr^di zFXJQT5i@-<28Utp#OQ6tZiuXo`9*sUdP8!JZA~3qQrHE&gRZpudUEJx?h>YqV`0xfbkX<+I{ z!H6qF`X5Xi zuTzX$ZU;G(KJd9(pIo)B92>JGJ?0nL$=DXK|8r0i=MJ29I|TyFlqB z7Ag%xR1bhKW?BgI&s~71Y*V+aJZ-?N|6SI%Jp`v z1V8S#<22FA7sKHG;~E;UD3JIrKuz|iQ}it}z)!?P$ncsO85P=ziUz_z(w3H#q$I9# zV)uOs=+R*)kRu&YLWbLgsn6V8!&58QX8xk@v%U$^t9^I$nG zT)aQ3m_X{DCapN!>hb8F@x|n{IynKV@(C>npgr>d zqBn4nzFh%~k=g$q&T_5kVm+`}ArYs{0jvU<=BN(`p-Wzsa>D!Ox~0C@UXIgEcd@{U zQ^@Bv4Ga{VIix{Y6RJ-$%?@LpenAO%T@Hv?O*8(j;@k1Xk3q8Q?3;$l5%E!R2;FGU zcORyh*2$%|?Nf~34v1&)yInyM>gQk>piT(8#O4pi)JF{{S5MH=HFJu$N2H;cRnKQQ zuQ%W$m!LpRedSp*^zzGb5AEdxWiINW2dDxQrT8IgqoGbUkMH=}`fNu4btKVWFAKE~ zDqDp%iV^cS`i8nCC?KH3<#JaJ-6a2mE>%O)wvG#$Y_>VqP9a`-z;lW4Rzv$@8RN=a z7S?$oNk61aTic(v)aCxU(N}NL|6#a_W$uc-W$v=h29$5XYi39u))#&b<>2?q6-whI zn2M;LSdL%!iwXVeX($S)49)aAyh=)ru>fB!3K@r;$&sl)_F4Z~2kTexdPi@8nG}wG z(>o6$AH1^-!xTj%OJIPqG((Hxk$j$aM-P)J)F0k!ZtJ9bG5o@v7wRN zmJ2t5G%HFnWt-;m0)}o?4a7E)j!EMy8d5PYSy(Haj__Lqt(|sZ#=;(@mSWo{*z>S68DB*+l#{ns>Us9TjKb@ zz`ow)f*=jb)GZbEMOR)B0+se{h^mAOvZKDPE^qDj$55JMY2)@={cXbPB^ejwG!@Y7 z_fV3P3EnWH;s@QCV%^=+>k9;UYs8_IhT70lUVx{EgKc+lpF)lDy3-1z9;w&aVm|w# zyPc?C!H@VhTi(l-iV#$rKo>he2fh52|&{wTg5Bi z6YX8)15b^6+xHAccGr1p@zhMP@I|j0iR%<8I6-lBpe>}%c+1~$o=>ez5edVY9%>~Z z68mrp1%@uK3AWW-E1D4M@(ix)j)A}-CbFtcNte*|iKQR4rG&>@Ewv-!Zq+L|HsE2$ zSILd$olw=S+Y2q2}$2^JyB;#_YdnP;vF~< zS+Xvey$iJUg0G*|$2&MxHB07=tSu_LTdiB~mPzSUH;{tI*g>5OJH&^zd>TbUy${F6 z@mdcel1rg+d|lHhtKU4;Bs|?|9(7;546?Tl;OD26@Kk-Lc@=}gij>LG)_12`m5yWn zEaC7Q7(vr1+6C{Jpqp{`^2kJ89of7uSKx<=x&QoyQe)W}5?UhlOAdR{{G`u?4rzk z`RiQHd(f!av0h$ZnEcNjnN=gngPE7T+@cq*N)V-p$T<9&i&PvON9{3&^W9`jD%U|G z5A{C%Tj+j^W~ZyKtTjN^%QR>jw6rlfJ<;QnIU{lj30bh6cl3eWT{i_D+No?x&Ga z;9fo$wrdO&G-=Ol(R%~gu6Kk*hM9RuRIJMw#kZqSrE13U+VNhvCdDwP#?0I#@UC`` zU-3h@#Bf!n8TqlS2|jdfT6|@NCP1pdXzs&`Bc1h2G7}V6nK$CFdL$l&%*o7YLCVyP zT*FGEHviJNEsD=wU>Zy<2nbE4=bURN=-%=(@Tqar2&Fq5OVj>d4U5G~I#B41KlttG zz31?BPYW|q5rAQTM9fJ#>npOuM_h29ZqmxrjJ)-jBTfZtQyYOZbY+u#>E`!1@%71R z5Rz#GOE=%P1AR*-cXZI^lUQc{ZrPFZw^dMt?|1Sf6`#iwd~n10iYYkLqsZJr4Lr3A zvE|kgtmP+{gK782+XK5sz0C)NYwssHc~g$-5u7C6uGXbnc3z!f+@@+=n^(WGzGC`l zLG8mdvD`F=vqE{RZrGp*exAj{>!;wR6lR)MqM`1`6kA+QvzMD-L`DCJOU05qZN4;j zaA<-?cbC^08mv*yA{N?)7xP|e%4K^}`C77;Xr1}Pf zJDP+^Je$Fm?_V(F&;!glq=s0g$9mR_21)wW&x ztdv{_Kl5;kh1cCI-4P)Z7RvL39%iJ(@dsc!jO1CmmY9F2e+%qtG%ln6_+3j%72U*G zKQ+NhX@3qUjnfxIu@z3UjKfx?eQ>#sV$3?Y@X~ zI;(waqS+{3ly}6%30>QYUmj(&eg*S;8Fk`Y<1j3X)81Se?;XMth-&AZprdS&E53QA z!A;cjC!Q0oYzLeX%;){txy?M%=#I}{QG?}+CJ@~3O%~f$O&jQ9xFp>03~GO$*YOl9 z2jekT!%bl_8ouP4Ho>zrT_3sDIxh->YQUN|G&?GwoE4twM@SXEx&w+GH4g3=$#N=;3P3UoY#*H1aGiGzGDpe>OGl z#}!<9U%abQP_Qbv>v`pBc--t*!ofKI1iqWQUjk*d$u~pb6hTV zUaz~0rpQ>`CL%&xE>iSck(815Lq;uxjA-Rg!(++6p-bi*hr`a~&%bH8>)n}l6p&E4 zjFjG#9^l`e58YN~q!+j_7LR$V_2}Y~*cApa@Jd=xi+Zj~w)~MxwtTorpOwJSE{drk zic9sJDx+_+hOwc|J@G?}ik;nIy(l2rn9Fo|Kgl)^k4(DhVj!rQ;=;vcGcfBpwKNDe zq8Fqo`i>f`n{Q!>NYc8)46c}ge<_%~uU>T{Pyb8aBadU$AGvvE8&QiFj=0potoI4( z1Q#{5Ed|Q8rk8XT0jOv^lJAP1D%}}n*p;^CB{*1AuPTQfxLw2vdS_WWDuzzC!@4$p z45G(~wJglg7KM5=GnMA{`njIzzCzs5jV*D`VGV`KLW!;B_zOoKXShgg)0mAoT?9Fb z;0J_t6&Gn^oEio9#PTPLET|VpbdAw&aK}}59n6T)>MlXL< zO5WRC;SU5MsggSzZ$%y~HC%23P4y8IV3=1DrtyUg&p~C&1ao#o-SMZ7pYBjfPH51ZRT$Eiciv9P0=hT|WQ#+w$Yxitp&vs_VD zJSCBoZ(R_eV*FtIly`y&RZu)VQNvfEBgSP47Y_vsV|q6}z!Xqc;A88WGOpvtlS$9N zWHdurURdK83Mcwm=A68WLeis^`KU@$B(P6NOehNbP+aoo4}%?%tjTN#R;rd1^B<>~ zvWR^IMI7&Z8e<#TaIvrs+trxIROg#B1&}g-Z63im#QH?^=B???UXJrp9VcTk)6RI* zn8^8?a1>Y;Kt(OH?-rIs)M$jd%8I}8ucc5w*SmNb8tR9ic1WNHoQ)kz9bJTYxEDhe zOg3MlR9|n*40qL&FwdbOd!k4LF57$k`j}o&;L%&_yLX}!cn&ul)Vwy|H?53)!0sDR zpfextF3v}FE<~d0D8hZgB{zPUpPk5TdeGr3qee`IaK|3`BI~v=?LK*{`jon4+hntC zw7Y13Qrl>Ms{#AUB0Ymz)dE|8%9`We=Oxm23ip_6pVEa_B_eSpy11)X=(S-93`|_C zM>{q#Yxgblv~Tn#Ic;M!NVW?!zUQ+ZwgoQ3`VOzQyt{ZaH=R`={223Q7Df$<{DgSnkD1yNl z6+*wgfwC)`UWPwhwK;xo%C4p&w;)2scy?;myY-#_;HM=e3aJq_=x|2$z+$^V7md_? z$HEv3JnC3t#P(%Aj#a4u(rEz|?#&wO8vHG22Rw`9X`{#v+_rNgz$ zs@kqp{*@tv0i&sY<)n1RDf%yj$1WNglQu3@uWZbIzmKS#VLw(^Px?yPQ8x2sozv!? zF{B2mR;ik*s$r6JM{=y!qa+fU-&3OHZE8qWyC}JyQo)B71~K=7H-mFmj&4YS=uEbL zd1%a3U#5_ZPf=Y<81US1MV}t-5fYJ*9Q5_|VO1*l0XjqhIgM7CZZ6`6CB4U~<-99n zAF`Wi+ek;9nM+d39ky@g&-W4eBJuC^I$qJl_iHxmscFWp5rb&hq$#95i%H%nW(LTW zNtl%5zf!%tf`Ha)Zs6mrxDaQH1*K(sw&5j+%LO%IUM8WdN$d2$ug*D)z4AV&fsJtx3$@Y)m-(hnbXMph@85$93@9A9bp zf+qEd&TlOoYWR}2r*Vfwxg+Ac>gV1{$cW^lL)Su#iAvQ)zD^pCQNMfeMhI56RY%MU+3rh?75$#*;pZz6J4b^hGb!M3MS_ITiEJ_X z$aNwRh=`Zwe_GnsQ}S|O=SLmHK4bd{i$hhXHIgUNB{<9#Vf&W-0Ruoy+{XP^8&1sr zSfGTJOp@HWr(c6%eqrpg!Kelka#*AG7*ap$DqnKvRHLJ}m$ONAh%|t~xHxShu9&Zp zm22!ZXkb93@%{y@poDO8olxDffaZpfH-ahl*B2bu2(wzfRyF(WMO#g~r>y?%EeEwM zji@o6GrZl0qm!8(bQ<-2tH+ZTg#PH;c(%*ARy zy1wn_OV_%my20!j)apk|sR(;EE@`Cm+6a@YSxuVGk?kW{@0}Lv z6SI7u0wohMmfOM5&3_EFY6hKm&Ep^K8zVrP;*N5`^!mfDUrcQ}*X9R!rBGca)1Mq; zg{I+QY1z3F3JCV<+=L*&#XU47{swPOoF5Iig$m@gs3iO3fc?`3hE;&`eXGfDpU?VT zdSjkl8&&Tu4o~&IpFRGI}8?!rf|yhY_;M`!gTeaAsdiQRW!YO zXh>@_mdf;*SaCHLj5quRG3_E=;9N(i2vM!hIqpw9!-KA`zs-g{m);IkUgob zZ!KG-#wQ2B;BEn)rDxPUq9XSGmUUDTESMxOzmeG;3zXc=q$ry6*qS_KgN@r%Cav~J zd@+WnvIc09<&ciWGvVPz-9S@Q25OhtGM|s!uoB&|YjVv_I03QlLOV)TH963;w$-CB z(GYc3-35vPtcWC?m+f`=Z4XpRpzQsG5w;@bByBy_AeWE%Zlxr5hs7)}tV!0*A;mZI z*Kk$1pz>+229uPCN?XDHgOVn8{WM#Kc@shpSSY+!E;G*I3NC$(LTR2CZ&FMoXlL&EYlo&!ScUp*;pzq?P9n^D>(%f zDKBdVjfs5i@+v-EYMpv;_55}jMvbu9`to4@*-fx+_ymW2nSTA1EHI+7)mZj?c|4SZ ziwCP_CK8Wgp-y+vfH1DN!vz7s`hF;8(?LyPY=_fqxEK#az3ODDBb7PL%5@Q8_^RP0 zNgdC$j_|o#xVBW~BIaxOOqKbo(?kC(hgkFQFx#QqqSNMOxts*g{Y(!g*JCi(`Q_0$ z1*LZZS>KB)v)hbE(gngGi7n*ah(>Xfl154>??MZ|`|av8YauFy@s__>0;5_1rfG|cs!7|m z-}vxCztkWK&0!(0s`?wFF}O`P{ZqIt>(MBBGE`|MK=X)QCf;j?P!)FdSPKr#9VBDl zID~~&O0rqD&2sCI@Hix)TqwY zgOV@x70Y6&S_^Z+(#-ufGfX)6s0i3WmEDmNcIAV$w>7~b6%Bbfzct;1;zW@54h=FZ zawOI}&?NtuKTiLU?Sm?IzQDC#B_ULx^zjHq3^@*_t59b8RGgt&s=|7~SW~e%#U5`> zfT7PH75;(yU=dSSL&*86Bp2LG4tr-gNFX^HQkB01d3LmG+^$AT_eG&r^XobO*Dt3s zL>I7u^9g(DAz5U(b>+N-x+9(-DbIgREA1BPG-HxktNo9z$+xJG2>OZVBKcR-5D}(? zhoRY?fc)opp3e+qcb*B~;+KOdg<=5rAKrXaC zA50Uq8XNW|^SwFdt#&-kQKNb7EqSEJ&9Ben#2>Rx=h*JfN>Q_%LhkG|1uErUw_7&F zxv|__>~F*mRAyY;F3(Q1M<1T{BB^!dn(Ws+#9>LVo=qlhFp%<&ZS@qJv?~c7>7AI( zkeqMK@1|Ay#ReTp1tV8kURbW(>Lh8v1cE3_Pamxju`Z52d$j(VJ)pAYn1lZKjv(*p zKYd4+av+tOI4Jc9A1qV@Z|L$1b#CiiFD@yq$=*vqEmor|=6{L0<1?MuFNOUPiW<~O|Pjs^GH5>+^KJ^povy~%Qj)PCP3L7QSiEEtvGu+VFhEq+Us z+EOQ5WBdZMm1F%r7Fxl*=2>EuHcy`fq*|AQ*w+hFb>N3U$`&J>)g`)wc!4tG4>2Wg z1A+ps!y#XtlGgrXl;&s8G@h(s=X};OLcYqg>g+7{h05xoGcrGB^A+y(&YDFW*AE&E z0zE|W!VVuWFcNy_IcA(@D%E$B2z$lnRthqnyOJr!*M66B&<&OMda@MNVJGk5JdH|& zx=CtvS0%?Nl`AdW)K5z1!V#piQB>96%n&I=!ihHrzsi$5NaBrOm5*5{Y?!?9(|~N4KEg7nM1$jb%jb~G(^}B3VUngz0lRUhM1RGeY}qp&GCb14S?h=-OHd zqX!MY&E#{Ag9u*E_{t%Y$<6G)F#L92_#3#DkGsG}n!_ZO-P1c`Ild2kH zqYS*Gw_enLrULVZ1H{V)dWx$Z*gQ~I+qa7dh#n!xzTORQ`wss=MXynIZg>`}eLp8#q(U8cX7gnym`h4}0oZpj6Sr0sOJ77~*U zqo^+Z=XMP>A2|n5qWx140Qia=$JM6b$CuL}rm|Qc2H#r)nAAXH9S!c*fa6E5ty`h_ zns1lwj7%puEmMvGz~1MV5kQu#Zj=RJyTJ4; z!(pVyUy6zsi3{`O!Viy*u;%~)yr?4ud2l2?e{w*Tsc;M+w_F$kw?@LRup-6154&b)`80mlXwB_@d3xH(1_$Hss(dey#qT$W!C z+vQZfdll=pgMpD`m5mbnQ1@b5WbY`q)ffh?`j!09F5mztcHsX4ak$N*I8WZTDZ?WH zLC_y9K$9@IK(not6dYJDk+A}n9Pn^oS}`THpkCY0RA!DT`KoIe_jCaGBe~CJeP<=7 z#?E(g3>;T}j6EpWWHYVe&@~yjdI7bzYtB^>vlNIyU;0u~SU*To=JmX`vG37T+LP0h z9^s_CGKIn~ch3}(l=m-?0#tY4{HhB@8N;5pnmJ3D!1o{_u9Iwd2>iGWL}1k(T#+`NY;Tcq!2||xb^F}B zw9Weo*5>&+FQ9z{_|dO1S$=#J3M$t8v7x!#HR;adU4OlB(-BSgES=}ec2`-aGo2L2 zT5FGfqu~Jae;9kqxTw0Y?ORk@LAtwJq;m)fMLdPFU=pk$}Fn&auFOajfhvAcY{duUEYA*%3e~U~k*x2o@owNPRK9MId zYifGre-qIrqXN%?a~p{tXExh(JUrG~@Vr%z^*~>Qtt72dD3#rWP^yPntwLN$Wiq{Y zt0}uL*y{#^1(%&R{l4mZZMI#&+9y_Lp=Pox?3ktIyqy4ma$OJF<=}bwzOFoXbaS+) zz|2JF_Q2(^Y5h^3YK8ajgD0=?YilHO{&WG)msNX23Fh1fAx5Cc5QQ0`NMtT;lTXP! z6i9bjr>oPSr|h{UyPMxn*>bby5=X4~upVAEI$_JHok(l6F!o)&E;Tne_7^byGWqFY zZe|4^GqKFiB@ab7!{S$+HyyE-nF(oOu27}5!POrk9@aiJ?=%x4@Ks8A698AZPm7LbgmC+ ztg*;mltuH1wt;}7`N9q%UI_a(@9PI2jb>}q^e8TBCV6=& zIb)33tGfu~m@XwqHpxbp9@VCozvXYj!unE~zPi`r-PA-d5!@uJiS}5mtZ(RcHS4Hv zPa`PCOj0o%g9J=IyG5y`N*zO7^wc>|e6-^zS;R*tP_r=h5NO!R88FEFeBM9v)@*ow z@TlugeCugSIMcqAl6%_Y&n7D$*1iwH{CYoXNEvq8y`ZbUc`#XH6)KS6PV=|!kjo4; znxu&Tmj$AP><QjOgg^zN*XYMHo+`G1`or=VCSyU;#G0P3KCBz9t zC&hLU0zNPMA{)-)n|`asg3)xl?(F&b=AHe@PqO=Ue++7G9(ue?b+JU2bW3FHP^qBg z=dXUyx*-I4@Gc1M|IuSy#-iAaG8{FCCH(saQ&MWz6l_b;N|(D-m*%vGjy{}MDpu*< ziccs4h=Yyo_*<;xjK$C#33*JmJ#(O`wAoUev+W=-Q$m=tzsC2@7!wzzi0K>D z0=j*l@2cH-v;>GHQ}F|ORy_kqIBc(=mU8aDvA~g#+4Qr;b z+lKe!!~OO<*z)pn)~{xA30cllHo7#9%;VXyP=XFSWp9HaA?OaK4bMuO9W)Rb;be0s z6cNO~@XG`;8VzcxD$JCqgojUlLE+Ob2{$dP zk7xe#m?~R?jbYdk#4U} zqK64QJD%suz=UJ3G?7iWZo_i*XAw;IOj#kLv+u+!M&#|FM$#pdu(-FAM?dm|ElUIR+c<#=gPIh8to^NH}^)#jY=oUjV7YNq{(+ZUBk)?ATg>t-_BhP ztgwZhu`Z#@cOL%$Nv5Wb2dIZAGGtqj3EH(4e`fAC@`6?a!XuzpSDXRzX@diff~0|= ze9ENQaEbnD>$(1#Dke}#tyM^QD~Gp$;Y?~z7N$nM>1-LQrA~66D2(Ef{PD6^Q{*wp zYtQy1t@cr)(RgN0uD+?wlT1msIGe_WZX>jrL*amAZc$c9y4VSb!qPnY%L|Rj01F7J6(kL4E74&Yn4<#xzm{COC zr1tA0X3|E&fb{fYqIB@Oys^!_Czp_0{j>Q!wVI$5OVvQj8Z(ykhMlXM$K}YEh(=2#;gLD8N$p8pEF084%PXhbaMu1CnY>(H5#Bq< z!Pe?=56Y@Yo_7f11VJ6{?_WS(A96WAl=rJD@L7o4_AlPBV!js#nxoN!?iFknHG_ul&kZBMND`n1en=9U@n_{>Q%WvR6~pKDm=U zqb%M5MZqrz8D4jfE*=}nySaKJOMl|+P2~`x(ff*~cSR?FrJNIO=iu$EF?$8FGOuNU`zh{qix6>^t-Rc zRlQ_4kB5+{d(ZzUmDW`MpOi`krkW*1*-UDsVA7jT$IeZ|$5ig!eW6D6h)FDt^63?) z!|is*t2jXs1?Ucik2ZJJLE@xfizjHugy{p@x=S6;z43I)3GRTeN(2I?PpXJrP$Q+N z6|8BsO{3`?qFHPn58t^ZxtPEf{s!i@=VlBR4`?Ht=|mgwW2mz1YZV@J%g~7^uciX+ z6;ZW}{gjz@rf?TLu8EU>`0`;LIN7V;fDh;#-QLLY+EdhGP=-m)sCQDT@G8pAVU|o5 zdUx8+fe_|G{>}5(8^T<<5G2i-Uf1Q$`60^b{(KSM(o}@jp_$C)#9?;3E8;edZLn1t6d8L-Kc z%Kqc}+XwjMZia?XjTxEpCyV3v=mNIX)g42wO)JF)*EXMaArpSpiszCJVX7D&-(P+Z*de*cXtv+Uq(;&7&Eo^<#obO=#L_D_EX$QcaBu$l=rFX| z`(|T(58|F;danEowPHOl+QP)DMIcH(#@)4XWm03LI3M*yz5~x*c*~-rd70!9&KeeQ zR}vJgnVSqX!MG|j$vI0DIbJTgm~ZGUcTup~U0s*nr_22GY>^6>F*SXla(099QkT#b7+n%;iZdr&k&};tO@{mM<{=1}f`SVv zu>8|YuP{+3E>UdRgf6@LjzM8L&%-*pp51r8Hk+aD&RPvvsYvW+c*33r$et?(in3cO1_OSw-Dp$No@7%zhADcj1D9c(zIkv))`_I~>(5e07Gbv)L32!_o&) z61jeevYyp^hz0%tO`FRtXnaO~LKiFD>c8s2nW|x2_j>z1%3pN9#B8ic`N-^wGE=Uh z_2cYeez^Z-*Y#}4)7IZ}F}h-mW>#c#87WUYA;+$LRRfq&hTL6;G7UQlf1M#8kz zUX(ef+D*1he%fvZ;z}{t;f>HT-oFG{>ur$u?{|$IO|APXS0oW#KJ) zt{rvaCaia6WhNXe4Sl`&$%G_(-QS&$ zfC)VVL`MLnBgDo#9dUL=>bOeC1+ZL;WsAnxNyELU98Sk7zaXn}4arJ674u26FzD)_ zeG2Z|3wYCGe77)PRol=ZiWrE3*`9hM*J%CgV0-B-xPCh-zI&RFsbdQ4Bu+Ml-HRljyJU~qeFS8)s-B~#z(8?DwO z@SG_@?REln9qmDAc-hc=9;#5C)JJ^dkSf}bi18hlWP>E0R*sKhQBgcVh!5|NFk?1{ zX@LvghMEfA9zPnR|Jv||!OT(yYSweWA)m#^obATM=etFQ^ zKaOd|6c)N!{9)pJFyF1ROijK`YFSIf_5>y{=D8EJm^A7;$s@CPb@bM_mt%Lff}!d6 zL9mQI(@m))8kxTG#w5Xdl+bVICe=UrI1-_Pr|%?n@aK$;L{rL$-K6SEX}88FS^A75 z^&L*nB!}xX#o1l8cBit5*b((4l`W0yk+gVsCz_0-^GlbsI)?2jGTY<=7$+!JKc%Ku zHH^JJv<<~SUYw`=O>_-{`@eTX*=gbCXR|73e_{beDwYiGh6j5 ziUVo3D@*$wyBc$x>_^}^jlqO)Ak!e-5^vnQ{;l~nTQc8%Kr2L^v68($lZJB~j>oHe zD)DIyXXwG+e1ym~bywuf;%~9K>t|iYHVpdv%4ZW>5a?;fGh1b>%#}uZ3j31jYE1l5 zqOvg?DPR%L}gng3LM zC$8BUXs43G^_*lBXFvRs+f9HYv^1M)`ZGO9US6#Y{{xSBcU9S9!PD7pLQ_+tPTA~ia(BPK ziO!U*`gx3ksa~hr7B9ZZ1(5{s*0Ob=pLK$eZKyuvAUHToN`T*|(({}x+FYE%f<;bG zF{GQske!HY+cyUcvyWWfS+sGxJvP!U){QNYfj&|AL!8rl(vrXJ5)$Sn8e%;LUDR?K z%t%aGdt!u)>U2f;ex}XKlN{}TS-anqeZuf!tWEqf#ybGTap-JI@lkSCrrvJ9Q(pMO zEv!DyPIl+|EjMR?Tt?IGQkhT_w}T%gtoP5a-p(ru#YIvOt9Ep72*&zhEwbw+J@#I; zp@9{ctZc!hv%h0mzj#;=L|T5h;%nhYlr_BYiadlDBb*)Abyv`ydPEo24XrO~XmWY6 z@Y`0(Bng|8Pgx(>Cu;p;p(+mlr%Ry}9q6(CfAI4Hb8Um38C|ztf;wI0Dxj6&{{OclsXi5xncboOeT^Jb^9m$xTLGil|*Hl(e0Y$e(HBIrwv5A37DNJz$E!AJ`?JU9R9{R43&08I(76>NRdlu-A36*MGS2@}T@8`?2Yz^1S*N5qa@(u7u+C%@ovy<&gWEs*)nz=DHIgHy^Wdae^`8 zO%DA8_rsP*3Bdlnh2Fk2>y_%dzK#A6v8|v%k16DaG;zGFr6-K#s!N`!C-l1+yt`p{ zQF3s)g+QG|o_}+{lkkW^kc`U8R=VPIyVdeq-h3CaIBzC?`n>uJ&=Ku>LH;Mn&C}e4 zZ*9F*3%`y!0%yA_bgfOX?pWX;hD~c7fL59K(&lX{X#C zk0~OO;b}5HRvjxi^>)NV!0O*FqHOk`<(?7t`n$h%fChaZ7{647zkhRg^vBWMPwS#H zkv#XKTn3U5N{j{*AI&W+;ODNwU(z`v5ndpX8U`@W$fGD>u`9o|`TH}fK%&1QlTJZ? z>dNckm-knVPcuF3lw(P(bCo9UGRPuXkywBRL|CG<{_Qpvef*;v zE7uPsC;tU}%PNx8ai>~!mPG5Do46InsX%G#7go}rX1i?-m_Pl2)>QcI5hMewKrwbG zc6BCQ>w!!@_uE!tbrjz!2Fq?iPu;negr1~&G}i=*UuE(btXLM*B20k8B2QP;({_=k z9npI{&u;^_x-rTRAWygCKATK9R~Wl?cOJ07AJsa&JOn?)h7>7tf?553a*NLMSZmz- zW#~rnd7qS7<>#a)NuTn2;Z{tx`RT&fcekpa72e_4f2tVI1`!ioP|3SSd+516!g=c~ zQ|C&{a|@&EjQ{khfBdJ5DLb7r)prjBx`6d+&8LR||N4^h7x6rED1UUl7yL>KNG?2A zlLGQ0%35vLB{2QOJ}(e#(SMl&!fp%LG^@Y04aEadL}e;2B7twV&Ja_TB~=D@1+C>X zVf&!X?j2}|O)V$xw$%eF`Ku1S>B{R%3i%cwaUQlD|czpc2lS;ejRiNat-Gk9%G=Dw0#Z+pgZ#BZiWxm5=wA%4Gj}C6ee{&mI{Hd_sP`%G)Gj$fx4@F z8t>&-K!QrO*&9VN)7IA38{S7nMRg0r@l>n;;Y)9L5~Y~20J_ELscqU_`7=cnCXklA zPGdsC>-?(ned`Qib*m$8yDywO6(YNRlcX?1zhzvMVwfuq+g9KocJ+8I*VJHOHF(hJ z2=<%_=C+>eW2nEm-l$2mn6YVvJK5fOp@;3t*D;YkqzGY@k?8h>s@<=xQ@o0S$HX#o zOHI;Sk4_nuHzPs*;x19{iT(YknrDrxQAyr#DMHKLk$5)=s3D$%;n`SRe8)?MP|#Xq-8s=RkV(exgE0)eFe-%XKTr50J1+NU#^c7vfTQf8D;-jME`J2D&1p}!8 z{v>0~#~mr)D>!ttcAzGK+IiqXtk6gvs+?Qtw&!x5%{Z*>comx9SYBtUSJ>zn$Mx@W z__4f{!Vq;>V#NRMCH4XiC^7wMzD*cdCC>r}) zaAV4(ic$SpKmI9@Y^X#bn#FMMWp`4cW1-omajjizG;UL|pWnN(ZE|8x1(Hv5as6gG z&&IY{mUsXjge&eoWw#Oi_-_p5=l^e=L>(=Op?K71MqCHd!U=qrJcIcLJE-s4+SkFH z?TF~;88EQ0_yV_%tyX_DCYZ(`>pUDJ1qMHsiBX~?MTLJWvvGj^V2qPhT~K}m_RBAx zB62?(&jJM1=puV<;E`4H6Y28bEOxT=QFbu&YH}TiESRCE?Txubi`>M7tSpAl#l%8K z2b1h*yD;4s%U>2|i^AKN+F^!Sb@IGJ$rA+?VO0vhn+_QMnalqSI5J_^Q!3u?j)tt2 zaj)a!*%g_yfG~W`3P4@qVz&cw-2I#;9)PrLx!hEn#C$-VALEok3FH#NIUf!Hug?#* znZ<1R5d?5Tcms1^h|}x#FSN0+hFwqiGIzi0PU9aq}dWvR4{ z9^H|flZu?{n$QCk5o`Dqhc6DzVi&EwgZC#IlWPM(q5+p-Xf?Jx++G%IAaY8t1dwtu z^8*nQiLVdmK289so^;qBqAB?xw)MY7+|Il2fu(QQ=(xGL8KksT_rKmD0(g>(B;r!5 z$^N-lnx9c#Zr$FOBvmX3wBgEA>ZyR$seVcqQz`6uv-;;PsnL-v(5lz*QsdyaZDkc1}zXaM2qvdGGLWaRBDy>ttoJbS7S{CBN+s*=0*PMa!=w@Qzdfg^AO60Vt8>9U!% zA;5bVsTAHGF4o&L47G`R-KH!5tH^jd7Eo`oQ;tY1Z9#ohT$q3#gpajmFuk?=c!O#W zZgEwz0b;`p_kq}-5C6BY>0HJ2UtRM*ofZmHx$=n?z?=QUHN(Mv8TDVv>WxZ;yw_g~ zb9#u+K`FBJHT@5_*G}5Al8?sQ=Wv%1k#3%>?spa9%YVA;D0?LPiubcAfo!IHfGm+J z0|aplyiZO`lL6#&fOdq@dbMp?5XibU_MWV>Srz4l8xjx@JOb?QWu~-0!1;cEpD=Q~ zJJZg1Pz4FW#8?jR7s?GLr}rAiHTECsODAmRTalKvAE+-gG!LY&{q*MMR>V`!2PJdA zz9_~`#bWT}@!^jQTefQJOf_*qfot>YKv%NA%##1M>wb#0h&t=R%XGC}7ptDG-UnA&?uD z&t+8{IO*J4gamiPdxBb9gCnX)%{|SH%kTL}WNBZIHbzV}bO~BK3mBxO*Xt2wDvuA- z-c^+S4!RCp>o0P=@jBrv5-9l5TQzvU!18J81?HWUxV0aekeX3;L!WZ`_t4>z(Y3zE zmh-zPCUm?r8wGJ715fjS$Gk)OY1ArTz5?L3yHiCfk5~~ssX@bqMMX^HZ@;!zRTl#Q zUfI33E)`K~YK3+p5~+rsG1lc25=#^9lfAx~(fJJ$(>0D3zJ?^X?WzfV&jWQyyLeDHJX8dRAQ*KL6Ns)3oUb;Ddit@qb1=m|IvjY_4?(bioaz$72^YT#K zT3S9ZGT;ps$&1`1dg`#fx-NEFzeg(Xd9ge#8X6Di;d9jOE&$S3ctK- z+7?%Qf9;sn+@H&);6CzY?ZuAI{T-`ZgeErItEtYXh4O&$KShNk+VF0IL9-0atr`mJ zqR2h70&AagJDp9tx{#)OmAr>D^i7UWNF4C;jF0uaY$7J@l%TfT)1qAI^>O7TyXBE# zVIaF15o|l4Z=nVSo+4geF8-FIaV)c8Y-Z?LKjM2+U>3c8udB}--tp&%qg}y!v|@D{ zV00$yJ8_q>e~*E99+Dp;Z&?y))&D3>+$O4RX~^LExbV0`HMDTWyy_K8vbg1@KX@WFw<^@KOGbtn4^T+4Ld9IcHJ&!qys zk?G?(V-CcESMwHaa@N{ai^GlUDr?6O72~64#ZT-mx8>f`ZXVhHY`DOmmnp|SiC7w4 z=8z79Wev6cK)xWAV|(%96ZjN$8`J4!Okdv|>hRfM=GV<%)h|z$H`sHhR@2e`R~Z1f zd!Q7B0&r=V0iahEnk#$i1;vIN?~Y|7hojlg3mbg_7I4*<0Dc??V=k$62E20s+N^P*ksgBJg3CX2r`JsC9t0{>KB%gI~)z?ArrKG50yb z+2Mf<-7yFBU!6I$8SQNq7G5tty1e1yz1d2ht@CEPYp&*4Xdv9&yQ1u#q?j}&?}=(Z z%(z8+dkm+#_KIf-oX0!NKB`}bL+IAB2Ww0-|HUobGeEU`2_;U&vQUahl^B?e&g=*qFSNW#GJ3_ZctG^6) zUGIs!ZT#Wa;bacYz}8js@;By9jiqm*`nBV}r=M0 z`enwvyY}nms?7)m9ampL zUSjNEEdJUeyVw(+Zu=;slQSZNW8k=W6%u9`;LTjBBspW?|b%528?x zM;PTnA4=SH*IBx-&9lFGOmi(g$n+!AoIf+zUOtzPOyPP~e-dnPQj=$JL}3)O_tVVl zZ4E@kwR(1^%whB!oCWQTd9DY@h1=y_Hw=O)K&Ie)e^)s0HTi3oO9j%J4Opl;r))e97x4pu)&J}Qdz4jSXj5f?y88Po1`7Vo zV?8R!G5$vi3Iy2mQ>`V8>DtKg`h?fy|m&$SduEaXk)nj z26^t_La8R7gdJQK^XAcZ=?o>PFJZR914PK-k8`m%_@(il#z%D3F)pN`lw;)*bku#wpA7HUeu+pEXqx4}4C`SZ zY1!JzJe?KhxCAU+m?M#>QGO@a)gMxrnsDRb|7lYDIXoG`T?5 zfy5vRnXkv#DcBxOpmBM?#awJD_;=6R!xA`Qi-rR1-LQ3$?tmZC)C-pj&mkK4Xy<3s z)o0gE8cwG#7n0xRAY6$yYe(Ma9&&DFI|wnj4UYev^&@=fv7m^eTl1A!qDw0?H;Yuhxy4depogACJWc|a|3 zi7nDbNlXu`>EVFyvEBoAyb~1_WeAie_0H=~fs{e%r{wP{)A5|3cM--z$yHkaW)rGt z{5PCbKTRa_@k8SnLHDgTnCh&e*ckFc$c|;X!y_VnMHdfa#L0@WC5B<;!>_ko=;GEJ zHgB?jnEy@!kq63+Hxg6m3N`xHGkq?KP+Jyu)F$8fb08<*J!0s+3!c?|Xh?PH<)z}5 zd>kS2DzM++FJ0XJVMU^BIe+YTBUvmNf$VswOtJt0$rM|rs9C$G40ap9#($R5VS|zN zSEpr%j;!Kx6R*|%c11if6Yu8mytK8%1NuU|*tBm>_hkDeXFo&Uls>|lXDBdl$6|`B z;WC4ytqaE8{ppNo&5E8VgVZ9eoZpt%39BxSCRM0D8-VdQd*+)pyl!hfv+@hQbV7!j zVE{mpe3^0$b-Y4Gp7iQ0KIUY;Hc>cvlXhUvhm~^Fp0(d=6=y@9ZhJI;gMJXnCV zj#Vf))2dAjmMWNh3D-Dv3OqmSo5|>0=|e>unr5C|l)lVt6O~yQu~JMLqp= zc2qM!({y=cyieVU{XQgN#fD-@b_!2doAX|vi1DJ1yXD2r?L8W)k~i9B`}|>rpi#~4 zV$I4elm(pg69#6-@g`>>L1Sm(WPP>D+M1>$hq~HK0dHY`k?*hL;sRr^{H(+VTyJ|b zGczqtPEPv&k}{=KKmT{7aYOsIW`C=RGM`9|O$Brf)U+i}6*HOFIR%v*<7qfK1));N z`VfRq#>Afvw71Bimdbw?0W7cWod^#c1l!Hdaxz?m1I7_ws0X}msfGKXmGuiDtkyRl0}@hebk_8S7t&U^jXLm+8+tx(d#pwjs zZeNgqV*Qh#OZeX;yPctw8l5jvfS0S7kcg;9KtQ1N+Y=`SsD>5mcLg7fl5Hy21A))+ zARqYc$)>+l&N_;yGjhsjwhOq zGL5Z}2sN>Z~ngeyCeA6K*&-zz(6Ko1FCx?0iCU)Py z|6o*)T6FHMbvge|y6L=42&Wp+R}KHxtuEKbz*lQz`|T&i_GyMVfdaagnBIk+koA>) zp;yj${uMUSP0pUzH*!B#Kz9wem3l9SG_87@&KJ7S&>3pVwVy=kh77jzT~)R1sz_x#^%YjWT=!<#ZsL3ZGp$(L50A#4lNQ(G-dKXk&%5+WQjdHnvD=kcyrCGz|01tfRV%@HjJ zb(yTT*JIU*RIjY8syx-Wem`y(OaN?5+LMThHCR8zBFqbAE30rH+WE)1de)bIo8vet zq19!>=_9ZOn!RAQ*)=eEZ%WOi`Z?vhdlLC4kuqe_xpBp zzUA;2$cJ~}kdaj?_>^+a@!xj)TPb=FN87bQYmNuvz8X-*LhIeRsO68IOnO~P1y(b* zFf4jOu6Rln$IS?TrpC6q2WvUGMz>kTA~ozDoUu7hWG56eT2FcYc^ z_$zdyv7a*kuRihFK=YimA`Z9L==Z`gkq1c)BihTetka z?Jv&mPMNT@8nR_X7^bcV(9*np)7Vy$@ zW#UAe^`l;Ou(9UA{G0L?;u6Zz>+$(!Rv2@8ruWyLX>h~Z>?wv^X9h{z`Fh2r zi`{uIpDBw6+f1n$f}f>cg25;{?v!&2?Fsr9SIkYiog9lO$g^&v)p` ztGF{~`yPgwFoB)0ISpKl#)yq(o}j~j+wCdGl=mA2AHcT#fxGd9WZF+?{-3L?1^q~i zZB?Y23We84<74jaVao~>-Eu8`njQ6^vCb5VtbO;<%YL3DJ4XV4O}X;mCx@VqE`hM0 zsP}!XkhG5nR>v7>Q`B*I2D-Md6N9_;z0xc2m1S?!}q;_J<{(ACc~C2l~VH@?0Fhe*{D7h5yWr>R>B?(WFA+ zu1d2I?@k>kT!)1N+FcQPM-Bt5uLPQWWv;yxNnyvK;!aN4R#qW33=D>SZH2DHgb`DY z?GrPv?vZ$;Nzx)I`Th)2xUAaJErP0V>W?oal59wP`*1e;q*~YE!vdOCo{<^T=xl7< z?e3o%oMv#Ss;xj5-ssjpYwrZ2lV@;7S2Fq{7|DC(56~D87PFe@<_Zy6Zs$H!9kg?O zvYbbnPUY!lsNQMsoVl0DB)BH7nEpjC%|HS`H!=7)grzM-1o-kVFd>kLMrYk>UGd`Wg3P^qi47kN0~fp-+gYAYWz^$x!$dL zveAn9L%4ug?W)1fs84dzI z7mP(M^{$2)V_VDZ;55EvdrO+7K>{!bEOr&*evRPSX6h?Q|J*c1^XnEkcN2=U8o1FH z)uF*tm~vMoHV~nLmse?6=t>3>g}=;1*Ut6J#((uKW|BtI_Eg%@@4!;%XRRfpWr?!q z$|8<<)t+wwxmxM&3kx=KekJPd2UpavQn#`SK77mbuG^wo{mDuMHP5{OREsAx=aiYx zC*5~wt9Kkb*QX{NmHW1)Rj`0}ecU3{C>M`soj%~%0J(!+SKA6KWtHwVGgC3`WKIab zC{o1iN(eu7;~aqId|FFFudX^dguwdKCJJk)mz9nmTy)6XU!6_FPiw>*ga2~6nz7CUkabO2C=2tK<5Hr0HxC##~*>_YOS6^DAz)T#q?wMsrxw^ zi<*v@V+KB90uk%}{x?slC^x)Fz1A81-9mZJN(*^zTTUQ;jQ3?MwJ0wU#|s+U%WzEI z6L0_7Gl9jA%*{TOA3OP=d>bPTyw`^bf~IShudLc|vw_;_Rkva3(zU*~-8aJE$Q2eJ z@(dDf2`=52G1@EFd$Z`W&K4=tXiDmQCM?i+=9wzF=CxGr0s$n{07>vM{^+ z&4$Ms3b5XzhBde!GvTu~2fKWn`gO=D(z5?{ecP4%0-DM?#45tlXc=lqB!C_nF$3u~e&xNTtKv>Q}Dv%Iz| zvFsOm=w6U~tCt4ruD!gd?+?D4rIVNMoq>!DglsfaKcb}$1TS5&t+J4ugL@A)zYq=v zKWA>ggu;M$jv)9;gS*}K798@dptIwavVh5igi4bOo|~VnMlehUg`T#kq)kbs6<5Ts zhy9-Hr+Dso^o8ZyM7ndL>?6X6WX+haZ-E_l!(dnyEL1&H0L}dfZ)@$(eKpmina)R2 zB**Krv90+ShI+*%@rnc&wDdxLc!<(*@<%)P-xoKZn=bIbRM?+H#J4<#JFwE7#qCab zekhvKm@o?WUREOoHpvGwWodQa2I6nt$pNPCI)x{+VMuGi)zKo~((39e9b^wsK%fFQ z-|ouuc=G(eI(%H83=EhQ|IL8a;`02C&GxtoBT z+`8)tpHP(gyS7$ElK>rnHVwcSWUgNL1G)KW)#VYYqG0cvt<_wam=!ZqQ;qOhdAhv2 zu!sn*g=(Wglc&erRnLpzEQ##T-M2Ilrvo*T9%0GgR|30$Rf7;0ceCC5lS-t`cur4i zG?|dz4_R7&fV=EjLim(*Rmo}Cd-xURayZ9H&&tYrP(AX5Y($%RcL7xN$(~405`ca8 zbRAAgO6spsPmhdAPMSlw3VadT0I;%kplSN%ViW{XiZt=cjv?eUz-%79t%(i|tu%nS z36uAYtbB!W=(WsU0uCX0+`&j<9`mG(jAaWjcy&Q0hMepdAwY709{?YuDIq<*bg*d~ z_)P>0s(<&I0A$c;Zcfh7oR_@3JZJMydf+#Ed!28FH5;S=|7TTGSLb~I7_nj9VL11= zP|b)bQ@_h0_helcqYY_6pJ`GIP;Cc zUv=LwdE0^j#F>wc&52;R5xrt&i(hS~5drp-089G(CzK3!+SUkA1Fd){v-rL zyuC)BI@1O)Kt>@#18{lLmigYj3pZS5u4KpihQz8}XIXAQbmfwG{|pY?fsKI}ljBmt zRX}io<8&}{=?=dty98(yy-dAN-S@rm+>jQ5!9PD(OaSi4%}rKm&j~Qi7h4?&H z0`DQfoR|WB`7l{g3XX84i_Nd;=vvK-UHtT;8pMp#P!BizAW$CJv|Q(_*#66 z%^dszfE*MtqB1C*5I~TX~_>idx~-Fea_^plz0f$Y{*5) z)41-G;O^nZ->d{Uk+H0dDv>5WU7E3jojHdGw|j+I_%&kTh{N-JHAl?AVf4KKoq?nZ zZn+#T7Jlh4EFsnN&QgRm*8M4B1UO*z@d5UtB<22DhL`7PrpPF83_dBdzXJX%=I2EK z_t5hkcuG@HV(s!a{pN>@UQ}HX!8QuKhTn){^tqH2t3LOJa{P=jeS;iQX1SolE z#sY=T<;3~fp1MJQ9sG0?icx=lsn|h1p{Lx>Ls9fg4d4{j@W+fWpKFTs126G42CHB0 zPfG%)E-`ZmEd(ABE2#T*E5CMdu!;eYn3izLq}EK}oEBB8hJdNXR|V~PJ_ay|s1D-k zSW&)-v!iR)*aRFoNX5c|5TM6Iw+^bx`(hM(P1%u|LXCpb6+YJf;rllI3MTx`+w1EF zWAN+~4+!tFO@H0O`-H?fy*g`IRqKRAM5Hy(e}&I7E9tLS*OkoGsW+h3DG__(VoivZ zj9iY5Q0GET6qtKQwq&X~i%2 z@FF&JJQxI!mhsGMZ!-770Avg;TsX&d=;>G9>WsFr&r}1i9AyKB6hKYRLi{|hjnCZc zb3VWzLrO*lW+Ja?k65mr$px-m=UeANEp+3jq0!?tv;WQ`LZ`CIG< zmriJVP-!3-@!$)*u-i;*qDyc`gx`yW&lXgA#dzshF4J5Xd9Npd{lrM<0=qHvxKxY^ zi4H3gtHO|j5me6N^I{b-8nkxySeHJx`}K!^A7fG$r=ects*Qb!-wjCtomO66F3{g* zqi(Ue2i^&ux4l;j76)-V4izad06rTtcvk2%Pm$i90*bF9s-4-DNjJB4^|&7wH{7N5 z)oQukHKHBAjhlg)W>0UAR@+2+kg_M(YfGIF0J26o#LEo$JXs_S5LHj%%(ky!oK()3 zwUti3;zddH(^gEXj0&s`G-ROFC=up}2%rvqLdlEmUU?~Ya7_QH--a*8R6h|PX{rjr z`UQPrzl~05onKv+DNPc-hi>Rp+-&7%hIXe)^zuxrH=3SXJ(|I^njyx$njuxBm#$OK zYBR0A$Cq4(n=t5LmFZL)G8oQAdGJ|CX^nEcxbf`K+}m==8U-*FK?9M4<5DAQq4^Ir z6vMJ(eyp5RYu`{Bd#kaN;jBc)s@`%=;n;YuYYZrGY!Hq7T!WS&D>)@w%)%OL->Xyj z@UADJ_Y%dzN_XZqKl2h5dQ_kyEVx|mG;>Obj>M_w1C}!-B)MmRai@|8rFpzz0(e@^--6>BY~R{J*9(fA7se zH}F6Y``z?20p#k-CbRNLGHc4}ff%3l*4y``UR_5<$It1*s9nFN1a+6&x zBn9G9kKPjvy%ViyC|sWMH`G0AuV(2^j)p3iRUc=}0Ege;-l*yT*pUEuz?(3gU@IsJ zOI>dWY5)b!P5cc^)_f;Rove-T-d-B5@S@F#@si(rqnoQ)BOUWj5kp5QLEmJwl!qSpp03K@+`lcwwpWcO;#B_+HSV@hIZWRB~=8|-SQe-!N zVP4)|9&#o$9v&P#i2j?%Mi(yTf?AVC67ic4GJbe}KaUChsyBEW=|K9Rc`f!6RJ#jH zp)(LAqsrRgFMdKaj!~y+ViPLfX%z9783ioT{Lzil1iYH+*P0Q4wpC$5xi90HEb`yp z@r;e_dPO1HThjbBQW%Gq++Uf7-~EiM7b;&8TnsgP`jyOX(PoTukps|Y;PJ#cx+(BS zTt399v40V9ig^nE4TC3KiS9BybvOy__}H0h3wc}T0X(OKV+AmPKtFn?11G%m=zpc) zRLixwEgtT!r9W+rfQRJ$Evc~N!*(;m-!_zkPHR2w9eeYt>M3wqV+D z0&aU3aK5(T1t#%D(72N3`ON|J)QtWuMo~!o)2CcFQBnUm8Gq2)xy7N-({*2OWp%a3 zP#}QKhRCuk`kc*fR~3e!3s;rso7@$vP0vxkNCvv>7GROJqQxB2+=|yX`#S?RzX6co z)=&!dn{onPli}1&far`R6xvrUnA8yoIJ@w+aY}gizGrZdz8F9|b^l%)WxxO5wRj6M zugR9EHQP%L>NGP+-wd1}lEUr@uHkTs9WU2mz24;X0^Jz%=bx(gAvl`bVHtB7nzdg| zp1!bz6M8{acyK4P$R71AiOX({ileX@RaklduSV-rNqr&4&c7H%x{`6Au~#l(lAwgr zi~1)Ah}IR+UhzqCe@<9t%gTRON`ntKWG z^+qlQ{|;(sSI5C1*}1hi7Ac2%%6C*&q5rIGdV1!_?#k+xpQ19oy7<8@4m3|_Hb@p# z=(gfOeak!kW9OD75(IAp9FkiGr#ikM5Gz9Y3*bIR4~W2f1)&nUe_kvGokq(u^-_&! z&EAv99-)>1Aq$>*0*k5-o(Re76#a!_fBpwhiU6n?JyaO(KW6kle!PQ#iFsi)T~5eO zOA@CEzOS4C#6Cn|_XhWOiZ5Z{k-2)HBUmyISb{iE*79*A$1F-A^xB;~;MlJ>oK+P@ zfM5#)D%S(nqL=0%!r}khq+t9gBcFUt2xyqNCIUlP3k<>k^Y#~d)d4Q8x{Crlbx#qUn zUuQR=q&Xr~va@5d^Qr)42&fk-EG2*q_i}qI#|40XdrCl)y$78Fd{57Si(+hooo?-*o2CbX@!VphiLm+tE-oyxb_(7Z~)9}$h{R38e08d3BjoM zU)E0^YUuDK!fk;%h(V?*mkKVDol_a*4r7k+d(;!N;)BM}jV?-Uro-)7RHOI9zIVke8PJEmU4%W3!b1`bVv9(livu9#z%(a0)r?kjf)K z<6|5V_5G{^BRf_P;1^LR?~6#L`}*Dt15+$YXo3-3y1oaeQ42e8zKmd1D|-B(sPR3% zfxc^qXoFT0QpF7XP*tc&NjsvP>Z6+R1G_{qY8}b_W2FK8O^SnqWA*QpQye>n^9-rX zLcRU?V`Llo66RvGOB6>_v#3hKY=s6BzgrboX?;;aa6O55-C6MI#VoNG?7FVtF}Z}e#ZiJw^PIbbp@sXQv$XtKSrU!P+>8! zj#bD5AZ%h6M@P>|kez{mYr3d$vS>-RZUdHG9L`<;J`kIS176_ySD;OI05A`5dTHkv z!je*>E@;C2Pa>VZ|M2yGP6c3kzEBYsWg6&t4v0PykF7R6I+__4`*&vs^@5Z5XXgbWq|S#AQD0=Dpiw>8c_qzOxP~R^u~Ve-6tlop zla-Z~1DI0V+uOK(J=FsrOn9TeMXi-g=L_7hv&SsAJ59lGdd9qWy8k~h(~3GiMmam{ zU@ypZ3=mvEsDOB%+@kJNch3GQ9zCWg2yMvd*BaU^BRa7IyAm~szxDf~ND)A;Am?8% zN@$b>C|fQ`gA3daTl8vR@rs296Dln}-k7X;QW3WCneRK(PoF5ZPOp=Jz2?q=;B;RW zPaEz^Y#fDP>jSb0QEy>&u6>S_iHoDf$5=yx-ly4Y7-T;Uj?T>9vl?CZe?`Gfk8FWRoCiwPZr%2uxiv;>!oZ_9`3 zUhh^{z#4~b{X@k10B1K)7qR($cxG*LlN<%ri9yph2@G^m;R4KDDYG~6$VEX#$2#Ni;9Xilr)MW6U<{Q`)tLY zb2UU`4~Gk)nUM}CW6^(4|(&&0TNjrB<nC06n>ip2DuR5tOVXZ_N){LqL1kW39yAq?V|Pj@);LSqLrKaJ65zlK0Zd#EVKjzuyFJJNu35Jy_8XVbs zJViIQ@`$?*4tiZac|18-e%0dPbOa|XqrnB6zV!GJ(s}igKOtY|b(V#f$Sgk%s!jXT zc3gqiHI70EF4CsKN_L0�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 ZaZz%7J` defaults `once-per-request` to `false`, `filter-all-dispatcher-types` to `true`, and `use-authorization-manager` to `true`. -Also, xref:servlet/authorization/authorize-requests.adoc#filtersecurityinterceptor-every-request[`authorizeRequests#filterSecurityInterceptorOncePerRequest`] defaults to `false` and xref:servlet/authorization/authorize-http-requests.adoc[`authorizeHttpRequests#filterAllDispatcherTypes`] defaults to `true`. +Also, {security-api-url}org/springframework/security/config/annotation/web/configurers/AbstractInterceptUrlConfigurer.AbstractInterceptUrlRegistry.html#filterSecurityInterceptorOncePerRequest(boolean)[`authorizeRequests#filterSecurityInterceptorOncePerRequest`] defaults to `false` and xref:servlet/authorization/authorize-http-requests.adoc[`authorizeHttpRequests#filterAllDispatcherTypes`] defaults to `true`. So, to complete migration, any defaults values can be removed. For example, if you opted in to the 6.0 default for `filter-all-dispatcher-types` or `authorizeHttpRequests#filterAllDispatcherTypes` like so: diff --git a/docs/modules/ROOT/pages/servlet/architecture.adoc b/docs/modules/ROOT/pages/servlet/architecture.adoc index 36b8d2520c..b804f6405b 100644 --- a/docs/modules/ROOT/pages/servlet/architecture.adoc +++ b/docs/modules/ROOT/pages/servlet/architecture.adoc @@ -194,7 +194,7 @@ The following is a comprehensive list of Spring Security Filter ordering: * `OAuth2AuthorizationCodeGrantFilter` * `SessionManagementFilter` * <> -* xref:servlet/authorization/authorize-requests.adoc#servlet-authorization-filtersecurityinterceptor[`FilterSecurityInterceptor`] +* xref:servlet/authorization/authorize-http-requests.adoc[`AuthorizationFilter`] * `SwitchUserFilter` [[servlet-exceptiontranslationfilter]] diff --git a/docs/modules/ROOT/pages/servlet/authentication/passwords/basic.adoc b/docs/modules/ROOT/pages/servlet/authentication/passwords/basic.adoc index 7c84277062..9eba5df7f1 100644 --- a/docs/modules/ROOT/pages/servlet/authentication/passwords/basic.adoc +++ b/docs/modules/ROOT/pages/servlet/authentication/passwords/basic.adoc @@ -15,7 +15,7 @@ The preceding figure builds off our xref:servlet/architecture.adoc#servlet-secur image:{icondir}/number_1.png[] First, a user makes an unauthenticated request to the resource `/private` for which it is not authorized. -image:{icondir}/number_2.png[] Spring Security's xref:servlet/authorization/authorize-requests.adoc#servlet-authorization-filtersecurityinterceptor[`FilterSecurityInterceptor`] indicates that the unauthenticated request is __Denied__ by throwing an `AccessDeniedException`. +image:{icondir}/number_2.png[] Spring Security's xref:servlet/authorization/authorize-http-requests.adoc[`AuthorizationFilter`] indicates that the unauthenticated request is __Denied__ by throwing an `AccessDeniedException`. image:{icondir}/number_3.png[] Since the user is not authenticated, xref:servlet/architecture.adoc#servlet-exceptiontranslationfilter[`ExceptionTranslationFilter`] initiates __Start Authentication__. The configured xref:servlet/authentication/architecture.adoc#servlet-authentication-authenticationentrypoint[`AuthenticationEntryPoint`] is an instance of {security-api-url}org/springframework/security/web/authentication/www/BasicAuthenticationEntryPoint.html[`BasicAuthenticationEntryPoint`], which sends a WWW-Authenticate header. diff --git a/docs/modules/ROOT/pages/servlet/authentication/passwords/form.adoc b/docs/modules/ROOT/pages/servlet/authentication/passwords/form.adoc index 7961352430..95c00337f8 100644 --- a/docs/modules/ROOT/pages/servlet/authentication/passwords/form.adoc +++ b/docs/modules/ROOT/pages/servlet/authentication/passwords/form.adoc @@ -16,7 +16,7 @@ The preceding figure builds off our xref:servlet/architecture.adoc#servlet-secur image:{icondir}/number_1.png[] First, a user makes an unauthenticated request to the resource (`/private`) for which it is not authorized. -image:{icondir}/number_2.png[] Spring Security's xref:servlet/authorization/authorize-requests.adoc#servlet-authorization-filtersecurityinterceptor[`FilterSecurityInterceptor`] indicates that the unauthenticated request is __Denied__ by throwing an `AccessDeniedException`. +image:{icondir}/number_2.png[] Spring Security's xref:servlet/authorization/authorize-http-requests.adoc[`AuthorizationFilter`] indicates that the unauthenticated request is __Denied__ by throwing an `AccessDeniedException`. image:{icondir}/number_3.png[] Since the user is not authenticated, xref:servlet/architecture.adoc#servlet-exceptiontranslationfilter[`ExceptionTranslationFilter`] initiates __Start Authentication__ and sends a redirect to the login page with the configured xref:servlet/authentication/architecture.adoc#servlet-authentication-authenticationentrypoint[`AuthenticationEntryPoint`]. In most cases, the `AuthenticationEntryPoint` is an instance of {security-api-url}org/springframework/security/web/authentication/LoginUrlAuthenticationEntryPoint.html[`LoginUrlAuthenticationEntryPoint`]. diff --git a/docs/modules/ROOT/pages/servlet/authorization/architecture.adoc b/docs/modules/ROOT/pages/servlet/authorization/architecture.adoc index 5eaf5b1e85..04292720b8 100644 --- a/docs/modules/ROOT/pages/servlet/authorization/architecture.adoc +++ b/docs/modules/ROOT/pages/servlet/authorization/architecture.adoc @@ -23,30 +23,76 @@ String getAuthority(); ---- ==== -This method lets an -`AccessDecisionManager` instance to obtain a precise `String` representation of the `GrantedAuthority`. -By returning a representation as a `String`, a `GrantedAuthority` can be easily "`read`" by most `AccessDecisionManager` implementations. -If a `GrantedAuthority` cannot be precisely represented as a `String`, the `GrantedAuthority` is considered "`complex`" and `getAuthority()` must return `null`. +This method is used by an +`AuthorizationManager` instance to obtain a precise `String` representation of the `GrantedAuthority`. +By returning a representation as a `String`, a `GrantedAuthority` can be easily "read" by most `AuthorizationManager` implementations. +If a `GrantedAuthority` cannot be precisely represented as a `String`, the `GrantedAuthority` is considered "complex" and `getAuthority()` must return `null`. -An example of a "`complex`" `GrantedAuthority` would be an implementation that stores a list of operations and authority thresholds that apply to different customer account numbers. +An example of a complex `GrantedAuthority` would be an implementation that stores a list of operations and authority thresholds that apply to different customer account numbers. Representing this complex `GrantedAuthority` as a `String` would be quite difficult. As a result, the `getAuthority()` method should return `null`. -This indicates to any `AccessDecisionManager` that it needs to support the specific `GrantedAuthority` implementation to understand its contents. +This indicates to any `AuthorizationManager` that it needs to support the specific `GrantedAuthority` implementation to understand its contents. Spring Security includes one concrete `GrantedAuthority` implementation: `SimpleGrantedAuthority`. This implementation lets any user-specified `String` be converted into a `GrantedAuthority`. All `AuthenticationProvider` instances included with the security architecture use `SimpleGrantedAuthority` to populate the `Authentication` object. +[[jc-method-security-custom-granted-authority-defaults]] +By default, role-based authorization rules include `ROLE_` as a prefix. +This means that if there is an authorization rule that requires a security context to have a role of "USER", Spring Security will by default look for a `GrantedAuthority#getAuthority` that returns "ROLE_USER". + +You can customize this with `GrantedAuthorityDefaults`. +`GrantedAuthorityDefaults` exists to allow customizing the prefix to use for role-based authorization rules. + +You can configure the authorization rules to use a different prefix by exposing a `GrantedAuthorityDefaults` bean, like so: + +.Custom MethodSecurityExpressionHandler +==== +.Java +[source,java,role="primary"] +---- +@Bean +static GrantedAuthorityDefaults grantedAuthorityDefaults() { + return new GrantedAuthorityDefaults("MYPREFIX_"); +} +---- + +.Kotlin +[source,kotlin,role="secondary"] +---- +companion object { + @Bean + fun grantedAuthorityDefaults() : GrantedAuthorityDefaults { + return GrantedAuthorityDefaults("MYPREFIX_"); + } +} +---- + +.Xml +[source,xml,role="secondary"] +---- + + + +---- +==== + +[TIP] +==== +You expose `GrantedAuthorityDefaults` using a `static` method to ensure that Spring publishes it before it initializes Spring Security's method security `@Configuration` classes +==== + [[authz-pre-invocation]] -== Pre-Invocation Handling +== Invocation Handling Spring Security provides interceptors that control access to secure objects, such as method invocations or web requests. -A pre-invocation decision on whether the invocation is allowed to proceed is made by the `AccessDecisionManager`. +A pre-invocation decision on whether the invocation is allowed to proceed is made by `AuthorizationManager` instances. +Also post-invocation decisions on whether a given value may be returned is made by `AuthorizationManager` instances. === The AuthorizationManager `AuthorizationManager` supersedes both <>. Applications that customize an `AccessDecisionManager` or `AccessDecisionVoter` are encouraged to <>. -``AuthorizationManager``s are called by the xref:servlet/authorization/authorize-http-requests.adoc[`AuthorizationFilter`] and are responsible for making final access control decisions. +``AuthorizationManager``s are called by Spring Security's xref:servlet/authorization/authorize-http-requests.adoc[request-based], xref:servlet/authorization/method-security.adoc[method-based], and xref:servlet/integrations/websocket.adoc[message-based] authorization components and are responsible for making final access control decisions. The `AuthorizationManager` interface contains two methods: ==== @@ -97,6 +143,10 @@ Another manager is the `AuthenticatedAuthorizationManager`. It can be used to differentiate between anonymous, fully-authenticated and remember-me authenticated users. Many sites allow certain limited access under remember-me authentication, but require a user to confirm their identity by logging in for full access. +[[authz-authorization-managers]] +==== AuthorizationManagers +There are also helpful static factories in `AuthenticationManagers` for composing individual ``AuthenticationManager``s into more sophisticated expressions. + [[authz-custom-authorization-manager]] ==== Custom Authorization Managers Obviously, you can also implement a custom `AuthorizationManager` and you can put just about any access-control logic you want in it. diff --git a/docs/modules/ROOT/pages/servlet/authorization/authorize-http-requests.adoc b/docs/modules/ROOT/pages/servlet/authorization/authorize-http-requests.adoc index 72d720b329..c0514e4ad2 100644 --- a/docs/modules/ROOT/pages/servlet/authorization/authorize-http-requests.adoc +++ b/docs/modules/ROOT/pages/servlet/authorization/authorize-http-requests.adoc @@ -1,61 +1,172 @@ [[servlet-authorization-authorizationfilter]] -= Authorize HttpServletRequests with AuthorizationFilter += Authorize HttpServletRequests :figures: servlet/authorization -This section builds on xref:servlet/architecture.adoc#servlet-architecture[Servlet Architecture and Implementation] by digging deeper into how xref:servlet/authorization/index.adoc#servlet-authorization[authorization] works within Servlet-based applications. +Spring Security allows you to xref:servlet/authorization/index.adoc[model your authorization] at the request level. +For example, with Spring Security you can say that all pages under `/admin` require one authority while all other pages simply require authentication. -[NOTE] -`AuthorizationFilter` supersedes xref:servlet/authorization/authorize-requests.adoc#servlet-authorization-filtersecurityinterceptor[`FilterSecurityInterceptor`]. -To remain backward compatible, `FilterSecurityInterceptor` remains the default. -This section discusses how `AuthorizationFilter` works and how to override the default configuration. +By default, Spring Security requires that every request be authenticated. +That said, any time you use xref:servlet/configuration/java.adoc#jc-httpsecurity[an `HttpSecurity` instance], it's necessary to declare your authorization rules. -The {security-api-url}org/springframework/security/web/access/intercept/AuthorizationFilter.html[`AuthorizationFilter`] provides xref:servlet/authorization/index.adoc#servlet-authorization[authorization] for ``HttpServletRequest``s. -It is inserted into the xref:servlet/architecture.adoc#servlet-filterchainproxy[FilterChainProxy] as one of the xref:servlet/architecture.adoc#servlet-security-filters[Security Filters]. - -You can override the default when you declare a `SecurityFilterChain`. -Instead of using xref:servlet/authorization/authorize-http-requests.adoc#servlet-authorize-requests-defaults[`authorizeRequests`], use `authorizeHttpRequests`, like so: +[[activate-request-security]] +Whenever you have an `HttpSecurity` instance, you should at least do: .Use authorizeHttpRequests ==== .Java [source,java,role="primary"] ---- -@Bean -SecurityFilterChain web(HttpSecurity http) throws AuthenticationException { - http - .authorizeHttpRequests((authorize) -> authorize - .anyRequest().authenticated(); - ) - // ... +http + .authorizeHttpRequests((authorize) -> authorize + .anyRequest().authenticated() + ) +---- - return http.build(); +.Kotlin +[source,kotlin,role="secondary"] +---- +http { + authorizeHttpRequests { + authorize(anyRequest, authenticated) + } } ---- + +.Xml +[source,xml,role="secondary"] +---- + + + +---- ==== -This improves on `authorizeRequests` in a number of ways: +This tells Spring Security that any endpoint in your application requires that the security context at a minimum be authenticated in order to allow it. -1. Uses the simplified `AuthorizationManager` API instead of metadata sources, config attributes, decision managers, and voters. -This simplifies reuse and customization. -2. Delays `Authentication` lookup. -Instead of the authentication needing to be looked up for every request, it will only look it up in requests where an authorization decision requires authentication. -3. Bean-based configuration support. +In many cases, your authorization rules will be more sophisticated than that, so please consider the following use cases: + +* I have an app that uses `authorizeRequests` and I want to <> +* I want to <> +* I want to <> based on a pattern; specifically <> +* I want to <> +* I want to <> +* I want to <> +* I want to <> to a policy agent -When `authorizeHttpRequests` is used instead of `authorizeRequests`, then {security-api-url}org/springframework/security/web/access/intercept/AuthorizationFilter.html[`AuthorizationFilter`] is used instead of xref:servlet/authorization/authorize-requests.adoc#servlet-authorization-filtersecurityinterceptor[`FilterSecurityInterceptor`]. +[[request-authorization-architecture]] +== Understanding How Request Authorization Components Work + +[NOTE] +This section builds on xref:servlet/architecture.adoc#servlet-architecture[Servlet Architecture and Implementation] by digging deeper into how xref:servlet/authorization/index.adoc#servlet-authorization[authorization] works at the request level in Servlet-based applications. .Authorize HttpServletRequest image::{figures}/authorizationfilter.png[] -* image:{icondir}/number_1.png[] First, the `AuthorizationFilter` obtains an xref:servlet/authentication/architecture.adoc#servlet-authentication-authentication[Authentication] from the xref:servlet/authentication/architecture.adoc#servlet-authentication-securitycontextholder[SecurityContextHolder]. -It wraps this in an `Supplier` in order to delay lookup. +* image:{icondir}/number_1.png[] First, the `AuthorizationFilter` constructs a `Supplier` that retrieves an xref:servlet/authentication/architecture.adoc#servlet-authentication-authentication[Authentication] from the xref:servlet/authentication/architecture.adoc#servlet-authentication-securitycontextholder[SecurityContextHolder]. * image:{icondir}/number_2.png[] Second, it passes the `Supplier` and the `HttpServletRequest` to the xref:servlet/architecture.adoc#authz-authorization-manager[`AuthorizationManager`]. -** image:{icondir}/number_3.png[] If authorization is denied, an `AccessDeniedException` is thrown. +The `AuthorizationManager` matches the request to the patterns in `authorizeHttpRequests`, and runs the corresponding rule. +** image:{icondir}/number_3.png[] If authorization is denied, xref:servlet/authorization/events.adoc[an `AuthorizationDeniedEvent` is published], and an `AccessDeniedException` is thrown. In this case the xref:servlet/architecture.adoc#servlet-exceptiontranslationfilter[`ExceptionTranslationFilter`] handles the `AccessDeniedException`. -** image:{icondir}/number_4.png[] If access is granted, `AuthorizationFilter` continues with the xref:servlet/architecture.adoc#servlet-filters-review[FilterChain] which allows the application to process normally. +** image:{icondir}/number_4.png[] If access is granted, xref:servlet/authorization/events.adoc[an `AuthorizationGrantedEvent` is published] and `AuthorizationFilter` continues with the xref:servlet/architecture.adoc#servlet-filters-review[FilterChain] which allows the application to process normally. -We can configure Spring Security to have different rules by adding more rules in order of precedence. +=== `AuthorizationFilter` Is Last By Default -.Authorize Requests +The `AuthorizationFilter` is last in xref:servlet/architecture.adoc#servlet-filterchain-figure[the Spring Security filter chain] by default. +This means that Spring Security's xref:servlet/authentication/index.adoc[authentication filters], xref:servlet/exploits/index.adoc[exploit protections], and other filter integrations do not require authorization. +If you add filters of your own before the `AuthorizationFilter`, they will also not require authorization; otherwise, they will. + +A place where this typically becomes important is when you are adding {spring-framework-reference-url}web.html#spring-web[Spring MVC] endpoints. +Because they are executed by the {spring-framework-reference-url}web.html#mvc-servlet[`DispatcherServlet`] and this comes after the `AuthorizationFilter`, you're endpoints need to be <>. + +=== All Dispatches Are Authorized + +The `AuthorizationFilter` runs not just on every request, but on every dispatch. +This means that the `REQUEST` dispatch needs authorization, but also ``FORWARD``s, ``ERROR``s, and ``INCLUDE``s. + +For example, {spring-framework-reference-url}web.html#spring-web[Spring MVC] can `FORWARD` the request to a view resolver that renders a Thymeleaf template, like so: + +.Sample Forwarding Spring MVC Controller +==== +.Java +[source,java,role="primary"] +---- +@Controller +public class MyController { + @GetMapping("/endpoint") + public String endpoint() { + return "endpoint"; + } +} +---- + +.Kotlin +[source,kotlin,role="secondary"] +---- +@Controller +class MyController { + @GetMapping("/endpoint") + fun endpoint(): String { + return "endpoint" + } +} +---- +==== + +In this case, authorization happens twice; once for authorizing `/endpoint` and once for forwarding to Thymeleaf to render the "endpoint" template. + +For that reason, you may want to <>. + +Another example of this principle is {spring-boot-reference-url}web.html#web.servlet.spring-mvc.error-handling[how Spring Boot handles errors]. +If the container catches an exception, say like the following: + +.Sample Erroring Spring MVC Controller +==== +.Java +[source,java,role="primary"] +---- +@Controller +public class MyController { + @GetMapping("/endpoint") + public String endpoint() { + throw new UnsupportedOperationException("unsupported"); + } +} +---- + +.Kotlin +[source,kotlin,role="secondary"] +---- +@Controller +class MyController { + @GetMapping("/endpoint") + fun endpoint(): String { + throw UnsupportedOperationException("unsupported") + } +} +---- +==== + +then Boot will dispatch it to the `ERROR` dispatch. + +In that case, authorization also happens twice; once for authorizing `/endpoint` and once for dispatching the error. + +For that reason, you may want to <>. + +=== `Authentication` Lookup is Deferred + +Remember that xref:servlet/authorization/architecture.adoc#_the_authorizationmanager[the `AuthorizationManager` API uses a `Supplier`]. + +This matters with `authorizeHttpRequests` when requests are <>. +In those cases, xref:servlet/authentication/architecture.adoc#servlet-authentication-authentication[the `Authentication`] is not queried, making for a faster request. + +[[authorizing-endpoints]] +== Authorizing an Endpoint + +You can configure Spring Security to have different rules by adding more rules in order of precedence. + +If you want to require that `/endpoint` only be accessible by end users with the `USER` authority, then you can do: + +.Authorize an Endpoint ==== .Java [source,java,role="primary"] @@ -63,225 +174,649 @@ We can configure Spring Security to have different rules by adding more rules in @Bean SecurityFilterChain web(HttpSecurity http) throws Exception { http - // ... - .authorizeHttpRequests(authorize -> authorize // <1> - .requestMatchers("/resources/**", "/signup", "/about").permitAll() // <2> - .requestMatchers("/admin/**").hasRole("ADMIN") // <3> - .requestMatchers("/db/**").access(new WebExpressionAuthorizationManager("hasRole('ADMIN') and hasRole('DBA')")) // <4> - // .requestMatchers("/db/**").access(AuthorizationManagers.allOf(AuthorityAuthorizationManager.hasRole("ADMIN"), AuthorityAuthorizationManager.hasRole("DBA"))) // <5> - .anyRequest().denyAll() // <6> - ); + .authorizeHttpRequests((authorize) -> authorize + .requestMatchers("/endpoint").hasAuthority('USER') + .anyRequest().authenticated() + ) + // ... return http.build(); } ---- + +.Kotlin +[source,kotlin,role="secondary"] +---- +@Bean +SecurityFilterChain web(HttpSecurity http) throws Exception { + http { + authorizeHttpRequests { + authorize("/endpoint", hasAuthority('USER')) + authorize(anyRequest, authenticated) + } + } + return http.build(); +} +---- + +.Xml +[source,xml,role="secondary"] +---- + + + + +---- ==== -<1> There are multiple authorization rules specified. -Each rule is considered in the order they were declared. -<2> We specified multiple URL patterns that any user can access. -Specifically, any user can access a request if the URL starts with "/resources/", equals "/signup", or equals "/about". -<3> Any URL that starts with "/admin/" will be restricted to users who have the role "ROLE_ADMIN". -You will notice that since we are invoking the `hasRole` method we do not need to specify the "ROLE_" prefix. -<4> Any URL that starts with "/db/" requires the user to have both "ROLE_ADMIN" and "ROLE_DBA". -You will notice that since we are using the `hasRole` expression we do not need to specify the "ROLE_" prefix. -<5> The same rule from 4, could be written by combining multiple `AuthorizationManager`. -<6> Any URL that has not already been matched on is denied access. -This is a good strategy if you do not want to accidentally forget to update your authorization rules. -You can take a bean-based approach by constructing your own xref:servlet/authorization/architecture.adoc#authz-delegate-authorization-manager[`RequestMatcherDelegatingAuthorizationManager`] like so: +As you can see, the declaration can be broken up in to pattern/rule pairs. + +`AuthorizationFilter` processes these pairs in the order listed, applying only the first match to the request. +This means that even though `/**` would also match for `/endpoint` the above rules are not a problem. +The way to read the above rules is "if the request is `/endpoint`, then require the `USER` authority; else, only require authentication". + +Spring Security supports several patterns and several rules; you can also programmatically create your own of each. + +Once authorized, you can test it using xref:servlet/test/method.adoc#test-method-withmockuser[Security's test support] in the following way: -.Configure RequestMatcherDelegatingAuthorizationManager +.Test Endpoint Authorization ==== .Java [source,java,role="primary"] ---- -@Bean -SecurityFilterChain web(HttpSecurity http, AuthorizationManager access) - throws AuthenticationException { - http - .authorizeHttpRequests((authorize) -> authorize - .anyRequest().access(access) - ) - // ... +@WithMockUser(authorities="USER") +@Test +void endpointWhenUserAuthorityThenAuthorized() { + this.mvc.perform(get("/endpoint")) + .andExpect(status().isOk()); +} - return http.build(); +@WithMockUser +@Test +void endpointWhenNotUserAuthorityThenForbidden() { + this.mvc.perform(get("/endpoint")) + .andExpect(status().isForbidden()); } -@Bean -AuthorizationManager requestMatcherAuthorizationManager(HandlerMappingIntrospector introspector) { - MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector); - RequestMatcher permitAll = - new AndRequestMatcher( - mvcMatcherBuilder.pattern("/resources/**"), - mvcMatcherBuilder.pattern("/signup"), - mvcMatcherBuilder.pattern("/about")); - RequestMatcher admin = mvcMatcherBuilder.pattern("/admin/**"); - RequestMatcher db = mvcMatcherBuilder.pattern("/db/**"); - RequestMatcher any = AnyRequestMatcher.INSTANCE; - AuthorizationManager manager = RequestMatcherDelegatingAuthorizationManager.builder() - .add(permitAll, (context) -> new AuthorizationDecision(true)) - .add(admin, AuthorityAuthorizationManager.hasRole("ADMIN")) - .add(db, AuthorityAuthorizationManager.hasRole("DBA")) - .add(any, new AuthenticatedAuthorizationManager()) - .build(); - return (context) -> manager.check(context.getRequest()); +@Test +void anyWhenUnauthenticatedThenUnauthorized() { + this.mvc.perform(get("/any")) + .andExpect(status().isUnauthorized()) } ---- ==== -You can also wire xref:servlet/authorization/architecture.adoc#authz-custom-authorization-manager[your own custom authorization managers] for any request matcher. +[[match-requests]] +== Matching Requests + +Above you've already seen <>. + +The first you saw was the simplest, which is to match any request. -Here is an example of mapping a custom authorization manager to the `my/authorized/endpoint`: +The second is to match by a URI pattern. +Spring Security supports two languages for URI pattern-matching: <> (as seen above) and <>. -.Custom Authorization Manager +[[match-by-ant]] +=== Matching Using Ant +Ant is the default language that Spring Security uses to match requests. + +You can use it to match a single endpoint or a directory, and you can even capture placeholders for later use. +You can also refine it to match a specific set of HTTP methods. + +Let's say that you instead of wanting to match the `/endpoint` endpoint, you want to match all endpoints under the `/resource` directory. +In that case, you can do something like the following: + +.Match with Ant ==== .Java [source,java,role="primary"] ---- -@Bean -SecurityFilterChain web(HttpSecurity http) throws Exception { - http - .authorizeHttpRequests((authorize) -> authorize - .requestMatchers("/my/authorized/endpoint").access(new CustomAuthorizationManager()); - ) - // ... +http + .authorizeHttpRequests((authorize) -> authorize + .requestMatchers("/resource/**").hasAuthority("USER") + .anyRequest().authenticated() + ) +---- - return http.build(); +.Kotlin +[source,kotlin,role="secondary"] +---- +http { + authorizeHttpRequests { + authorize("/resource/**", hasAuthority("USER")) + authorize(anyRequest, authenticated) + } } ---- + +.Xml +[source,xml,role="secondary"] +---- + + + + +---- ==== -Or you can provide it for all requests as seen below: +The way to read this is "if the request is `/resource` or some subdirectory, require the `USER` authority; otherwise, only require authentication" -.Custom Authorization Manager for All Requests +You can also extract path values from the request, as seen below: + +.Authorize and Extract ==== .Java [source,java,role="primary"] ---- -@Bean -SecurityFilterChain web(HttpSecurity http) throws Exception { - http - .authorizeHttpRequests((authorize) -> authorize - .anyRequest().access(new CustomAuthorizationManager()); - ) - // ... +http + .authorizeHttpRequests((authorize) -> authorize + .requestMatchers("/resource/{name}").access(new WebExpressionAuthorizationManager("#name == authentication.name")) + .anyRequest().authenticated() + ) +---- - return http.build(); +.Kotlin +[source,kotlin,role="secondary"] +---- +http { + authorizeHttpRequests { + authorize("/resource/{name}", WebExpressionAuthorizationManager("#name == authentication.name")) + authorize(anyRequest, authenticated) + } } ---- + +.Xml +[source,xml,role="secondary"] +---- + + + + +---- ==== -By default, the `AuthorizationFilter` applies to all dispatcher types. -We can configure Spring Security to not apply the authorization rules to all dispatcher types by using the `shouldFilterAllDispatcherTypes` method: +Once authorized, you can test it using xref:servlet/test/method.adoc#test-method-withmockuser[Security's test support] in the following way: -.Set shouldFilterAllDispatcherTypes to false +.Test Directory Authorization ==== .Java [source,java,role="primary"] ---- -@Bean -SecurityFilterChain web(HttpSecurity http) throws Exception { - http - .authorizeHttpRequests((authorize) -> authorize - .shouldFilterAllDispatcherTypes(false) - .anyRequest().authenticated() - ) - // ... +@WithMockUser(authorities="USER") +@Test +void endpointWhenUserAuthorityThenAuthorized() { + this.mvc.perform(get("/endpoint/jon")) + .andExpect(status().isOk()); +} - return http.build(); +@WithMockUser +@Test +void endpointWhenNotUserAuthorityThenForbidden() { + this.mvc.perform(get("/endpoint/jon")) + .andExpect(status().isForbidden()); +} + +@Test +void anyWhenUnauthenticatedThenUnauthorized() { + this.mvc.perform(get("/any")) + .andExpect(status().isUnauthorized()) } ---- +==== + +[NOTE] +Spring Security only matches paths. +If you want to match query parameters, you will need a custom request matcher. + +[[match-by-regex]] +=== Matching Using Regular Expressions +Spring Security supports matching requests against a regular expression. +This can come in handy if you want to apply more strict matching criteria than `**` on a subdirectory. + +For example, consider a path that contains the username and the rule that all usernames must be alphanumeric. +You can use {security-api-url}org/springframework/security/web/util/matcher/RegexRequestMatcher.html[`RegexRequestMatcher`] to respect this rule, like so: + +.Match with Regex +==== +.Java +[source,java,role="primary"] +---- +http + .authorizeHttpRequests((authorize) -> authorize + .requestMatchers(RegexRequestMatcher.regexMatcher("/resource/[A-Za-z0-9]+")).hasAuthority("USER") + .anyRequest().denyAll() + ) +---- + .Kotlin [source,kotlin,role="secondary"] ---- -@Bean -open fun web(http: HttpSecurity): SecurityFilterChain { - http { - authorizeHttpRequests { - shouldFilterAllDispatcherTypes = false - authorize(anyRequest, authenticated) - } +http { + authorizeHttpRequests { + authorize(RegexRequestMatcher.regexMatcher("/resource/[A-Za-z0-9]+"), hasAuthority("USER")) + authorize(anyRequest, denyAll) + } +} +---- + +.Xml +[source,xml,role="secondary"] +---- + + + + +---- +==== + +[[match-by-httpmethod]] +=== Matching By Http Method + +You can also match rules by HTTP method. +One place where this is handy is when authorizing by permissions granted, like being granted a `read` or `write` privilege. + +To require all ``GET``s to have the `read` permission and all ``POST``s to have the `write` permission, you can do something like this: + +.Match by HTTP Method +==== +.Java +[source,java,role="primary"] +---- +http + .authorizeHttpRequests((authorize) -> authorize + .requestMatchers(HttpMethod.GET).hasAuthority("read") + .requestMatchers(HttpMethod.POST).hasAuthority("write") + .anyRequest().denyAll() + ) +---- + +.Kotlin +[source,kotlin,role="secondary"] +---- +http { + authorizeHttpRequests { + authorize(HttpMethod.GET, hasAuthority("read")) + authorize(HttpMethod.POST, hasAuthority("write")) + authorize(anyRequest, denyAll) + } +} +---- + +.Xml +[source,xml,role="secondary"] +---- + + + + + +---- +==== + +These authorization rules should read as: "if the request is a GET, then require `read` permission; else, if the request is a POST, then require `write` permission; else, deny the request" + +[TIP] +Denying the request by default is a healthy security practice since it turns the set of rules into an allow list. + +Once authorized, you can test it using xref:servlet/test/method.adoc#test-method-withmockuser[Security's test support] in the following way: + +.Test Http Method Authorization +==== +.Java +[source,java,role="primary"] +---- +@WithMockUser(authorities="read") +@Test +void getWhenReadAuthorityThenAuthorized() { + this.mvc.perform(get("/any")) + .andExpect(status().isOk()); +} + +@WithMockUser +@Test +void getWhenNoReadAuthorityThenForbidden() { + this.mvc.perform(get("/any")) + .andExpect(status().isForbidden()); +} + +@WithMockUser(authorities="write") +@Test +void postWhenWriteAuthorityThenAuthorized() { + this.mvc.perform(post("/any").with(csrf())) + .andExpect(status().isOk()) +} + +@WithMockUser(authorities="read") +@Test +void postWhenNoWriteAuthorityThenForbidden() { + this.mvc.perform(get("/any").with(csrf())) + .andExpect(status().isForbidden()); +} +---- +==== + +[[match-by-dispatcher-type]] +=== Matching By Dispatcher Type + +[NOTE] +This feature is not currently supported in XML + +As stated earlier, Spring Security <<_all_dispatches_are_authorized, authorizes all dispatcher types by default>>. +And even though xref:servlet/authentication/architecture.adoc#servlet-authentication-securitycontext[the security context] established on the `REQUEST` dispatch carries over to subsequent dispatches, subtle mismatches can sometimes cause an unexpected `AccessDeniedException`. + +To address that, you can configure Spring Security Java configuration to allow dispatcher types like `FORWARD` and `ERROR`, like so: + +.Match by Dispatcher Type +==== +.Java +[source,java,role="secondary"] +---- +http + .authorizeHttpRequests((authorize) -> authorize + .dispatcherTypeMatchers(DispatcherType.FORWARD, DispatcherType.ERROR).permitAll() + .requestMatchers("/endpoint").permitAll() + .anyRequest().denyAll() + ) +---- + +.Kotlin +[source,kotlin,role="secondary"] +---- +http { + authorizeHttpRequests { + authorize(DispatcherType.FORWARD, permitAll) + authorize(DispatcherType.ERROR, permitAll) + authorize("/endpoint", permitAll) + authorize(anyRequest, denyAll) } - return http.build() } ---- ==== -Instead of setting `shouldFilterAllDispatcherTypes` to `false`, the recommended approach is to customize authorization on the dispatcher types. -For example, you may want to grant all access on requests with dispatcher type `ASYNC` or `FORWARD`. +[[match-by-custom]] +=== Using a Custom Matcher + +[NOTE] +This feature is not currently supported in XML -.Permit ASYNC and FORWARD dispatcher type +In Java configuration, you can create your own {security-api-url}org/springframework/security/web/util/matcher/RequestMatcher.html[`RequestMatcher`] and supply it to the DSL like so: + +.Authorize by Dispatcher Type +==== +.Java +[source,java,role="secondary"] +---- +RequestMatcher printview = (request) -> request.getParameter("print") != null; +http + .authorizeHttpRequests((authorize) -> authorize + .requestMatchers(printview).hasAuthority("print") + .anyRequest().authenticated() + ) +---- + +.Kotlin +[source,kotlin,role="secondary"] +---- +val printview: RequestMatcher = { (request) -> request.getParameter("print") != null } +http { + authorizeHttpRequests { + authorize(printview, hasAuthority("print")) + authorize(anyRequest, authenticated) + } +} +---- +==== + +[TIP] +Because {security-api-url}org/springframework/security/web/util/matcher/RequestMatcher.html[`RequestMatcher`] is a functional interface, you can supply it as a lambda in the DSL. +However, if you want to extract values from the request, you will need to have a concrete class since that requires overriding a `default` method. + +Once authorized, you can test it using xref:servlet/test/method.adoc#test-method-withmockuser[Security's test support] in the following way: + +.Test Custom Authorization ==== .Java [source,java,role="primary"] ---- +@WithMockUser(authorities="print") +@Test +void printWhenPrintAuthorityThenAuthorized() { + this.mvc.perform(get("/any?print")) + .andExpect(status().isOk()); +} + +@WithMockUser +@Test +void printWhenNoPrintAuthorityThenForbidden() { + this.mvc.perform(get("/any?print")) + .andExpect(status().isForbidden()); +} +---- +==== + +[[authorize-requests]] +== Authorizing Requests + +Once a request is matched, you can authorize it in several ways <> like `permitAll`, `denyAll`, and `hasAuthority`. + +As a quick summary, here are the authorization rules built into the DSL: + +* `permitAll` - The request requires no authorization and is a public endpoint; note that in this case, xref:servlet/authentication/architecture.adoc#servlet-authentication-authentication[the `Authentication`] is never retrieved from the session +* `denyAll` - The request is not allowed under any circumstances; note that in this case, the `Authentication` is never retrieved from the session +* `hasAuthority` - The request requires that the `Authentication` have xref:servlet/authorization/architecture.adoc#authz-authorities[a `GrantedAuthority`] that matches the given value +* `hasRole` - A shortcut for `hasAuthority` that prefixes `ROLE_` or whatever is configured as the default prefix +* `hasAnyAuthority` - The request requires that the `Authentication` have a `GrantedAuthority` that matches any of the given values +* `hasAnyRole` - A shortcut for `hasAnyAuthority` that prefixes `ROLE_` or whatever is configured as the default prefix +* `access` - The request uses this custom `AuthorizationManager` to determine access + +Having now learned the patterns, rules, and how they can be paired together, you should be able to understand what is going on in this more complex example: + +.Authorize Requests +==== +.Java +[source,java,role="primary"] +---- +import static jakarta.servlet.DispatcherType.*; + +import static org.springframework.security.authorization.AuthorizationManagers.allOf; +import static org.springframework.security.authorization.AuthorityAuthorizationManager.hasAuthority; +import static org.springframework.security.authorization.AuthorityAuthorizationManager.hasRole; + @Bean SecurityFilterChain web(HttpSecurity http) throws Exception { - http - .authorizeHttpRequests((authorize) -> authorize - .dispatcherTypeMatchers(DispatcherType.ASYNC, DispatcherType.FORWARD).permitAll() - .anyRequest().authenticated() - ) - // ... + http + // ... + .authorizeHttpRequests(authorize -> authorize // <1> + .dispatcherTypeMatchers(FORWARD, ERROR).permitAll() // <2> + .requestMatchers("/static/**", "/signup", "/about").permitAll() // <3> + .requestMatchers("/admin/**").hasRole("ADMIN") // <4> + .requestMatchers("/db/**").access(allOf(hasAuthority('db'), hasRole('ADMIN'))) // <5> + .anyRequest().denyAll() // <6> + ); - return http.build(); + return http.build(); +} +---- +==== +<1> There are multiple authorization rules specified. +Each rule is considered in the order they were declared. +<2> Dispatches `FORWARD` and `ERROR` are permitted to allow {spring-framework-reference-url}web.html#spring-web[Spring MVC] to render views and Spring Boot to render errors +<3> We specified multiple URL patterns that any user can access. +Specifically, any user can access a request if the URL starts with "/resources/", equals "/signup", or equals "/about". +<4> Any URL that starts with "/admin/" will be restricted to users who have the role "ROLE_ADMIN". +You will notice that since we are invoking the `hasRole` method we do not need to specify the "ROLE_" prefix. +<5> Any URL that starts with "/db/" requires the user to have both been granted the "db" permission as well as be a "ROLE_ADMIN". +You will notice that since we are using the `hasRole` expression we do not need to specify the "ROLE_" prefix. +<6> Any URL that has not already been matched on is denied access. +This is a good strategy if you do not want to accidentally forget to update your authorization rules. + +[[remote-authorization-manager]] +=== Use an Authorization Database, Policy Agent, or Other Service +If you want to configure Spring Security to use a separate service for authorization, you can create your own `AuthorizationManager` and match it to `anyRequest`. + +First, your `AuthorizationManager` may look something like this: + +.Open Policy Agent Authorization Manager +==== +.Java +[source,java,role="primary"] +---- +@Component +public final class OpenPolicyAgentAuthorizationManager implements AuthorizationManager { + @Override + public AuthorizationDecision check(Supplier authentication, RequestAuthorizationContext context) { + // make request to Open Policy Agent + } } ---- +==== + +Then, you can wire it into Spring Security in the following way: + +.Any Request Goes to Remote Service +==== +.Java +[source,java,role="primary"] +---- +@Bean +SecurityFilterChain web(HttpSecurity http, AuthorizationManager authz) throws Exception { + http + // ... + .authorizeHttpRequests((authorize) -> authorize + .anyRequest().access(authz) + ); + + return http.build(); +} +---- +==== + +[[favor-permitall]] +=== Favor `permitAll` over `ignoring` +When you have static resources it can be tempting to configure the filter chain to ignore these values. +A more secure approach is to permit them using `permitAll` like so: + +.Permit Static Resources +==== +.Java +[source,java,role="secondary"] +---- +http + .authorizeHttpRequests((authorize) -> authorize + .requestMatchers("/css/**").permitAll() + .anyRequest().authenticated() + ) +---- + .Kotlin [source,kotlin,role="secondary"] ---- -@Bean -open fun web(http: HttpSecurity): SecurityFilterChain { - http { - authorizeHttpRequests { - authorize(DispatcherTypeRequestMatcher(DispatcherType.ASYNC, DispatcherType.FORWARD), permitAll) - authorize(anyRequest, authenticated) - } +http { + authorizeHttpRequests { + authorize("/css/**", permitAll) + authorize(anyRequest, authenticated) } - return http.build() } ---- ==== -You can also customize it to require a specific role for a dispatcher type: +It's more secure because even with static resources it's important to write secure headers, which Spring Security cannot do if the request is ignored. + +In this past, this came with a performance tradeoff since the session was consulted by Spring Security on every request. +As of Spring Security 6, however, the session is no longer pinged unless required by the authorization rule. +Because the performance impact is now addressed, Spring Security recommends using at least `permitAll` for all requests. + +[[migrate-authorize-requests]] +== Migrating from `authorizeRequests` + +[NOTE] +`AuthorizationFilter` supersedes {security-api-url}org/springframework/security/web/access/intercept/FilterSecurityInterceptor.html[`FilterSecurityInterceptor`]. +To remain backward compatible, `FilterSecurityInterceptor` remains the default. +This section discusses how `AuthorizationFilter` works and how to override the default configuration. + +The {security-api-url}org/springframework/security/web/access/intercept/AuthorizationFilter.html[`AuthorizationFilter`] provides xref:servlet/authorization/index.adoc#servlet-authorization[authorization] for ``HttpServletRequest``s. +It is inserted into the xref:servlet/architecture.adoc#servlet-filterchainproxy[FilterChainProxy] as one of the xref:servlet/architecture.adoc#servlet-security-filters[Security Filters]. + +You can override the default when you declare a `SecurityFilterChain`. +Instead of using {security-api-url}org/springframework/security/config/annotation/web/builders/HttpSecurity.html#authorizeRequests()[`authorizeRequests`], use `authorizeHttpRequests`, like so: -.Require ADMIN for Dispatcher Type ERROR +.Use authorizeHttpRequests ==== .Java [source,java,role="primary"] ---- @Bean -SecurityFilterChain web(HttpSecurity http) throws Exception { +SecurityFilterChain web(HttpSecurity http) throws AuthenticationException { http .authorizeHttpRequests((authorize) -> authorize - .dispatcherTypeMatchers(DispatcherType.ERROR).hasRole("ADMIN") - .anyRequest().authenticated() + .anyRequest().authenticated(); ) // ... return http.build(); } ---- +==== + +This improves on `authorizeRequests` in a number of ways: + +1. Uses the simplified `AuthorizationManager` API instead of metadata sources, config attributes, decision managers, and voters. +This simplifies reuse and customization. +2. Delays `Authentication` lookup. +Instead of the authentication needing to be looked up for every request, it will only look it up in requests where an authorization decision requires authentication. +3. Bean-based configuration support. + +When `authorizeHttpRequests` is used instead of `authorizeRequests`, then {security-api-url}org/springframework/security/web/access/intercept/AuthorizationFilter.html[`AuthorizationFilter`] is used instead of {security-api-url}org/springframework/security/web/access/intercept/FilterSecurityInterceptor.html[`FilterSecurityInterceptor`]. + +=== Migrating Expressions + +Where possible, it is recommended that you use type-safe authorization managers instead of SpEL. +For Java configuration, {security-api-url}org/springframework/security/web/access/expression/WebExpressionAuthorizationManager.html[`WebExpressionAuthorizationManager`] is available to help migrate legacy SpEL. + +To use `WebExpressionAuthorizationManager`, you can construct one with the expression you are trying to migrate, like so: + +==== +.Java +[source,java,role="primary"] +---- +.requestMatchers("/test/**").access(new WebExpressionAuthorizationManager("hasRole('ADMIN') && hasRole('USER')")) +---- + .Kotlin [source,kotlin,role="secondary"] ---- -@Bean -open fun web(http: HttpSecurity): SecurityFilterChain { - http { - authorizeHttpRequests { - authorize(DispatcherTypeRequestMatcher(DispatcherType.ERROR), hasRole("ADMIN")) - authorize(anyRequest, authenticated) - } - } - return http.build() -} +.requestMatchers("/test/**").access(WebExpressionAuthorizationManager("hasRole('ADMIN') && hasRole('USER')")) ---- ==== -== Request Matchers +If you are referring to a bean in your expression like so: `@webSecurity.check(authentication, request)`, it's recommended that you instead call the bean directly, which will look something like the following: -The `RequestMatcher` interface is used to determine if a request matches a given rule. -We use `securityMatchers` to determine if a given `HttpSecurity` should be applied to a given request. +==== +.Java +[source,java,role="primary"] +---- +.requestMatchers("/test/**").access((authentication, context) -> + new AuthorizationDecision(webSecurity.check(authentication.get(), context.getRequest()))) +---- + +.Kotlin +[source,kotlin,role="secondary"] +---- +.requestMatchers("/test/**").access((authentication, context): AuthorizationManager -> + AuthorizationDecision(webSecurity.check(authentication.get(), context.getRequest()))) +---- +==== + +For complex instructions that include bean references as well as other expressions, it is recommended that you change those to implement `AuthorizationManager` and refer to them by calling `.access(AuthorizationManager)`. + +If you are not able to do that, you can configure a {security-api-url}org/springframework/security/web/access/expression/DefaultHttpSecurityExpressionHandler.html[`DefaultHttpSecurityExpressionHandler`] with a bean resolver and supply that to `WebExpressionAuthorizationManager#setExpressionhandler`. + +[[security-matchers]] +== Security Matchers + +The {security-api-url}org/springframework/security/web/util/matcher/RequestMatcher.html[`RequestMatcher`] interface is used to determine if a request matches a given rule. +We use `securityMatchers` to determine if xref:servlet/configuration/java.adoc#jc-httpsecurity[a given `HttpSecurity`] should be applied to a given request. The same way, we can use `requestMatchers` to determine the authorization rules that we should apply to a given request. Look at the following example: @@ -336,7 +871,7 @@ open class SecurityConfig { <3> Allow access to URLs that start with `/admin/` to users with the `ADMIN` role <4> Any other request that doesn't match the rules above, will require authentication -The `securityMatcher(s)` and `requestMatcher(s)` methods will decide which `RequestMatcher` implementation fits best for your application: If Spring MVC is in the classpath, then `MvcRequestMatcher` will be used, otherwise, `AntPathRequestMatcher` will be used. +The `securityMatcher(s)` and `requestMatcher(s)` methods will decide which `RequestMatcher` implementation fits best for your application: If {spring-framework-reference-url}web.html#spring-web[Spring MVC] is in the classpath, then {security-api-url}org/springframework/security/web/servlet/util/matcher/MvcRequestMatcher.html[`MvcRequestMatcher`] will be used, otherwise, {security-api-url}org/springframework/security/web/servlet/util/matcher/AntPathRequestMatcher.html[`AntPathRequestMatcher`] will be used. You can read more about the Spring MVC integration xref:servlet/integrations/mvc.adoc[here]. If you want to use a specific `RequestMatcher`, just pass an implementation to the `securityMatcher` and/or `requestMatcher` methods: @@ -409,45 +944,7 @@ open class SecurityConfig { <4> Allow access to URLs that start with `/admin/` to users with the `ADMIN` role, using `RegexRequestMatcher` <5> Allow access to URLs that match the `MyCustomRequestMatcher` to users with the `SUPERVISOR` role, using a custom `RequestMatcher` -== Expressions - -It is recommended that you use type-safe authorization managers instead of SpEL. -However, `WebExpressionAuthorizationManager` is available to help migrate legacy SpEL. - -To use `WebExpressionAuthorizationManager`, you can construct one with the expression you are trying to migrate, like so: - -==== -.Java -[source,java,role="primary"] ----- -.requestMatchers("/test/**").access(new WebExpressionAuthorizationManager("hasRole('ADMIN') && hasRole('USER')")) ----- - -.Kotlin -[source,kotlin,role="secondary"] ----- -.requestMatchers("/test/**").access(WebExpressionAuthorizationManager("hasRole('ADMIN') && hasRole('USER')")) ----- -==== - -If you are referring to a bean in your expression like so: `@webSecurity.check(authentication, request)`, it's recommended that you instead call the bean directly, which will look something like the following: - -==== -.Java -[source,java,role="primary"] ----- -.requestMatchers("/test/**").access((authentication, context) -> - new AuthorizationDecision(webSecurity.check(authentication.get(), context.getRequest()))) ----- - -.Kotlin -[source,kotlin,role="secondary"] ----- -.requestMatchers("/test/**").access((authentication, context): AuthorizationManager -> - AuthorizationDecision(webSecurity.check(authentication.get(), context.getRequest()))) ----- -==== - -For complex instructions that include bean references as well as other expressions, it is recommended that you change those to implement `AuthorizationManager` and refer to them by calling `.access(AuthorizationManager)`. +== Further Reading -If you are not able to do that, you can configure a `DefaultHttpSecurityExpressionHandler` with a bean resolver and supply that to `WebExpressionAuthorizationManager#setExpressionhandler`. +Now that you have secured your application's requests, consider xref:servlet/authorization/method-security.adoc[securing its methods]. +You can also read further on xref:servlet/test/index.adoc[testing your application] or on integrating Spring Security with other aspects of you application like xref:servlet/integrations/data.adoc[the data layer] or xref:servlet/integrations/observability.adoc[tracing and metrics]. diff --git a/docs/modules/ROOT/pages/servlet/authorization/authorize-requests.adoc b/docs/modules/ROOT/pages/servlet/authorization/authorize-requests.adoc deleted file mode 100644 index 83d62c42da..0000000000 --- a/docs/modules/ROOT/pages/servlet/authorization/authorize-requests.adoc +++ /dev/null @@ -1,183 +0,0 @@ -[[servlet-authorization-filtersecurityinterceptor]] -= Authorize HttpServletRequest with FilterSecurityInterceptor -:figures: servlet/authorization - -[NOTE] -==== -`FilterSecurityInterceptor` is in the process of being replaced by xref:servlet/authorization/authorize-http-requests.adoc[`AuthorizationFilter`]. -Consider using that instead. -==== - -This section builds on xref:servlet/architecture.adoc#servlet-architecture[Servlet Architecture and Implementation] by digging deeper into how xref:servlet/authorization/index.adoc#servlet-authorization[authorization] works within Servlet-based applications. - -The {security-api-url}org/springframework/security/web/access/intercept/FilterSecurityInterceptor.html[`FilterSecurityInterceptor`] provides xref:servlet/authorization/index.adoc#servlet-authorization[authorization] for `HttpServletRequest` instances. -It is inserted into the xref:servlet/architecture.adoc#servlet-filterchainproxy[FilterChainProxy] as one of the xref:servlet/architecture.adoc#servlet-security-filters[Security Filters]. - -The following image shows the role of `FilterSecurityInterceptor`: - -.Authorize HttpServletRequest -image::{figures}/filtersecurityinterceptor.png[] - -image:{icondir}/number_1.png[] The `FilterSecurityInterceptor` obtains an xref:servlet/authentication/architecture.adoc#servlet-authentication-authentication[Authentication] from the xref:servlet/authentication/architecture.adoc#servlet-authentication-securitycontextholder[SecurityContextHolder]. -image:{icondir}/number_2.png[] `FilterSecurityInterceptor` creates a {security-api-url}org/springframework/security/web/FilterInvocation.html[`FilterInvocation`] from the `HttpServletRequest`, `HttpServletResponse`, and `FilterChain` that are passed into the `FilterSecurityInterceptor`. -image:{icondir}/number_3.png[] It passes the `FilterInvocation` to `SecurityMetadataSource` to get the ``ConfigAttribute``s. -image:{icondir}/number_4.png[] It passes the `Authentication`, `FilterInvocation`, and ``ConfigAttribute``s to the `AccessDecisionManager`. -image:{icondir}/number_5.png[] If authorization is denied, an `AccessDeniedException` is thrown. -In this case, the xref:servlet/architecture.adoc#servlet-exceptiontranslationfilter[`ExceptionTranslationFilter`] handles the `AccessDeniedException`. -image:{icondir}/number_6.png[] If access is granted, `FilterSecurityInterceptor` continues with the xref:servlet/architecture.adoc#servlet-filters-review[`FilterChain`], which lets the application process normally. - -// configuration (xml/java) - -By default, Spring Security's authorization requires all requests to be authenticated. -The following listing shows the explicit configuration: - -[[servlet-authorize-requests-defaults]] -.Every Request Must be Authenticated -==== -.Java -[source,java,role="primary"] ----- -@Bean -public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - http - // ... - .authorizeRequests(authorize -> authorize - .anyRequest().authenticated() - ); - return http.build(); -} ----- - -.XML -[source,xml,role="secondary"] ----- - - - - ----- - -.Kotlin -[source,kotlin,role="secondary"] ----- -@Bean -open fun filterChain(http: HttpSecurity): SecurityFilterChain { - http { - // ... - authorizeRequests { - authorize(anyRequest, authenticated) - } - } - return http.build() -} ----- -==== - -We can configure Spring Security to have different rules by adding more rules in order of precedence: - -.Authorize Requests -==== -.Java -[source,java,role="primary"] ----- -@Bean -public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - http - // ... - .authorizeRequests(authorize -> authorize // <1> - .requestMatchers("/resources/**", "/signup", "/about").permitAll() // <2> - .requestMatchers("/admin/**").hasRole("ADMIN") // <3> - .requestMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')") // <4> - .anyRequest().denyAll() // <5> - ); - return http.build(); -} ----- - -.XML -[source,xml,role="secondary"] ----- - - - - - - - - - - - ----- - -.Kotlin -[source,kotlin,role="secondary"] ----- -@Bean -open fun filterChain(http: HttpSecurity): SecurityFilterChain { - http { - authorizeRequests { // <1> - authorize("/resources/**", permitAll) // <2> - authorize("/signup", permitAll) - authorize("/about", permitAll) - - authorize("/admin/**", hasRole("ADMIN")) // <3> - authorize("/db/**", "hasRole('ADMIN') and hasRole('DBA')") // <4> - authorize(anyRequest, denyAll) // <5> - } - } - return http.build() -} ----- -==== -<1> There are multiple authorization rules specified. -Each rule is considered in the order they were declared. -<2> We specified multiple URL patterns that any user can access. -Specifically, any user can access a request if the URL starts with "/resources/", equals "/signup", or equals "/about". -<3> Any URL that starts with "/admin/" will be restricted to users who have the role "ROLE_ADMIN". -You will notice that since we are invoking the `hasRole` method we do not need to specify the "ROLE_" prefix. -<4> Any URL that starts with "/db/" requires the user to have both "ROLE_ADMIN" and "ROLE_DBA". -You will notice that since we are using the `hasRole` expression we do not need to specify the "ROLE_" prefix. -<5> Any URL that has not already been matched on is denied access. -This is a good strategy if you do not want to accidentally forget to update your authorization rules. -==== - - -[[filtersecurityinterceptor-every-request]] -== Configure FilterSecurityInterceptor with Dispatcher Types - -By default, the `FilterSecurityInterceptor` applies to every request. -This means that if a request is dispatched from a request that was already filtered, the `FilterSecurityInterceptor` will perform the same authorization checks on the dispatched request. -In some scenarios, you may not want to apply authorization on some dispatcher types: - -.Permit ASYNC and ERROR dispatcher types -==== -.Java -[source,java,role="primary"] ----- -@Bean -SecurityFilterChain web(HttpSecurity http) throws Exception { - http - .authorizeRequests((authorize) -> authorize - .dispatcherTypeMatchers(DispatcherType.ASYNC, DispatcherType.ERROR).permitAll() - .anyRequest.authenticated() - ) - // ... - - return http.build(); -} ----- -.XML -[source,xml] ----- - - - - - - - - - ----- -==== diff --git a/docs/modules/ROOT/pages/servlet/authorization/index.adoc b/docs/modules/ROOT/pages/servlet/authorization/index.adoc index a528115372..1a0579336b 100644 --- a/docs/modules/ROOT/pages/servlet/authorization/index.adoc +++ b/docs/modules/ROOT/pages/servlet/authorization/index.adoc @@ -2,11 +2,12 @@ = Authorization :page-section-summary-toc: 1 +Having established xref:servlet/authentication/index.adoc[how users will authenticate], you also need to configure your application's authorization rules. + The advanced authorization capabilities within Spring Security represent one of the most compelling reasons for its popularity. Irrespective of how you choose to authenticate (whether using a Spring Security-provided mechanism and provider or integrating with a container or other non-Spring Security authentication authority), the authorization services can be used within your application in a consistent and simple way. -In this part, we explore the different `AbstractSecurityInterceptor` implementations, which were introduced in Part I. -We then move on to explore how to fine-tune authorization through the use of domain access control lists. - +You should consider attaching authorization rules to xref:servlet/authorization/authorize-http-requests.adoc[request URIs] and xref:servlet/authorization/method-security.adoc[methods] to begin. +Below there is also wealth of detail about xref:servlet/authorization/architecture.adoc[how Spring Security authorization works] and how, having established a basic model, it can be fine-tuned. diff --git a/docs/modules/ROOT/pages/servlet/authorization/method-security.adoc b/docs/modules/ROOT/pages/servlet/authorization/method-security.adoc index 60da21403f..0d29172b50 100644 --- a/docs/modules/ROOT/pages/servlet/authorization/method-security.adoc +++ b/docs/modules/ROOT/pages/servlet/authorization/method-security.adoc @@ -1,18 +1,70 @@ [[jc-method]] = Method Security +:figures: servlet/authorization -From version 2.0 onwards, Spring Security has improved support substantially for adding security to your service layer methods. -It provides support for JSR-250 annotation security as well as the framework's original `@Secured` annotation. -From 3.0, you can also make use of new xref:servlet/authorization/expression-based.adoc#el-access[expression-based annotations]. -You can apply security to a single bean, by using the `intercept-methods` element to decorate the bean declaration, or you can secure multiple beans across the entire service layer by using AspectJ style pointcuts. +In addition to xref:servlet/authorization/authorize-http-requests.adoc[modeling authorization at the request level], Spring Security also supports modeling at the method level. -[[jc-enable-method-security]] -== EnableMethodSecurity +[[activate-method-security]] +You can activate it in your application by annotating any `@Configuration` class with `@EnableMethodSecurity` or adding `` to any XML configuration file, like so: -In Spring Security 5.6, we can enable annotation-based security using the `@EnableMethodSecurity` annotation on any `@Configuration` instance. +==== +.Java +[source,java,role="primary"] +---- +@EnableMethodSecurity +---- + +.Kotlin +[source,kotlin,role="secondary"] +---- +@EnableMethodSecurity +---- + +.Xml +[source,xml,role="secondary"] +---- + +---- +==== + +Then, you are immediately able to annotate any Spring-managed class or method with <>, <>, <>, and <> to authorize method invocations, including the input parameters and return values. + +[NOTE] +{spring-boot-reference-url}using.html#using.build-systems.starters[Spring Boot Starter Security] does not activate method-level authorization by default. + +Method Security supports many other use cases as well including <>, <>, and several configuration points. +Consider learning about the following use cases: + +* <> +* Understanding <> and reasons to use it +* Comparing <> +* Authorizing methods with <> and <> +* Filtering methods with <> and <> +* Authorizing methods with <> +* Authorizing methods with <> +* Integrating with <> +* Customizing <> +* Integrating with <> + +[[method-security-architecture]] +== How Method Security Works -This improves upon `@EnableGlobalMethodSecurity` in a number of ways. `@EnableMethodSecurity`: +Spring Security's method authorization support is handy for: + +* Extracting fine-grained authorization logic; for example, when the method parameters and return values contribute to the authorization decision. +* Enforcing security at the service layer +* Stylistically favoring annotation-based over `HttpSecurity`-based configuration + +And since Method Security is built using {spring-framework-reference-url}core.html#aop-api[Spring AOP], you have access to all its expressive power to override Spring Security's defaults as needed. + +As already mentioned, you begin by adding `@EnableMethodSecurity` to a `@Configuration` class or `` in a Spring XML configuration file. + +[[use-method-security]] +[NOTE] +==== +This annotation and XML element supercede `@EnableGlobalMethodSecurity` and ``, respectively. +They offer the following improvements: 1. Uses the simplified `AuthorizationManager` API instead of metadata sources, config attributes, decision managers, and voters. This simplifies reuse and customization. @@ -22,382 +74,814 @@ This simplifies reuse and customization. 5. Complies with JSR-250 6. Enables `@PreAuthorize`, `@PostAuthorize`, `@PreFilter`, and `@PostFilter` by default -[NOTE] -==== -For earlier versions, please read about similar support with <>. +If you are using `@EnableGlobalMethodSecurity` or ``, these are now deprecated, and you are encouraged to migrate. ==== -For example, the following would enable Spring Security's `@PreAuthorize` annotation: +Method authorization is a combination of before- and after-method authorization. +Consider a service bean that is annotated in the following way: -.Method Security Configuration ==== .Java [source,java,role="primary"] ---- -@Configuration -@EnableMethodSecurity -public class MethodSecurityConfig { - // ... +@Service +public class MyCustomerService { + @PreAuthorize("hasAuthority('permission:read')") + @PostAuthorize("returnObject.owner == authentication.name") + public Customer readCustomer(String id) { ... } } ---- .Kotlin [source,kotlin,role="secondary"] ---- -@Configuration -@EnableMethodSecurity -class MethodSecurityConfig { - // ... +@Service +open class MyCustomerService { + @PreAuthorize("hasAuthority('permission:read')") + @PostAuthorize("returnObject.owner == authentication.name") + fun readCustomer(val id: String): Customer { ... } } ---- +==== -.Xml -[source,xml,role="secondary"] +A given invocation to `MyCustomerService#readCustomer` may look something like this when Method Security <>: + +image::{figures}/methodsecurity.png[] + +1. Spring AOP invokes its proxy method for `readCustomer`. Among the proxy's other advisors, it invokes an {security-api-url}org/springframework/security/authorization/method/AuthorizationManagerBeforeMethodInterceptor/html[`AuthorizationManagerBeforeMethodInterceptor`] that matches <> +2. The interceptor invokes {security-api-url}org/springframework/security/authorization/method/PreAuthorizeAuthorizationManager.html[`PreAuthorizeAuthorizationManager#check`] +3. The authorization manager uses a `MethodSecurityExpressionHandler` to parse the annotation's xref:servlet/authorization/expression-based.adoc[SpEL expression] and constructs a corresponding `EvaluationContext` from a `MethodSecurityExpressionRoot` containing xref:servlet/authentication/architecture.adoc#servlet-authentication-authentication[a `Supplier`] and `MethodInvocation`. +4. The interceptor uses this context to evaluate the expression; specifically, it reads xref:servlet/authentication/architecture.adoc#servlet-authentication-authentication[the `Authentication`] from the `Supplier` and checks whether it has `permission:read` in its collection of xref:servlet/authorization/architecture.adoc#authz-authorities[authorities] +5. If the evaluation passes, then Spring AOP proceeds to invoke the method. +6. If not, the interceptor publishes an `AuthorizationDeniedEvent` and throws an {security-api-url}org/springframework/security/access/AccessDeniedException.html[`AccessDeniedException`] which xref:servlet/architecture.adoc#servlet-exceptiontranslationfilter[the `ExceptionTranslationFilter`] catches and returns a 403 status code to the response +7. After the method returns, Spring AOP invokes an {security-api-url}org/springframework/security/authorization/method/AuthorizationManagerAfterMethodInterceptor.html[`AuthorizationManagerAfterMethodInterceptor`] that matches <>, operating the same as above, but with {security-api-url}org/springframework/security/authorization/method/PostAuthorizeAuthorizationManager.html[`PostAuthorizeAuthorizationManager`] +8. If the evaluation passes (in this case, the return value belongs to the logged-in user), processing continues normally +9. If not, the interceptor publishes an `AuthorizationDeniedEvent` and throws an {security-api-url}org/springframework/security/access/AccessDeniedException.html[`AccessDeniedException`], which xref:servlet/architecture.adoc#servlet-exceptiontranslationfilter[the `ExceptionTranslationFilter`] catches and returns a 403 status code to the response + +[NOTE] +If the method is not being called in the context of an HTTP request, you will likely need to handle the `AccessDeniedException` yourself + +[[unanimous-based-authorization-decisions]] +=== Multiple Annotations Are Computed In Series + +As demonstrated above, if a method invocation involves multiple <>, each of those is processed one at a time. +This means that they can collectively be thought of as being "anded" together. +In other words, for an invocation to be authorized, all annotation inspections need to pass authorization. + +[[repeated-annotations]] +=== Repeated Annotations Are Not Supported + +That said, it is not supported to repeat the same annotation on the same method. +For example, you cannot please `@PreAuthorize` twice on the same method. + +Instead, use SpEL's boolean support or its support for delegating to a separate bean. + +[[annotation-method-pointcuts]] +=== Each Annotation Has Its Own Pointcut + +Each annotation has its own pointcut instance that looks for that annotation or its <> counterparts across the entire object hierarchy, starting at <>. + +You can see the specifics of this in {security-api-url}org/springframework/security/authorization/method/AuthorizationMethodPointcuts.html[`AuthorizationMethodPointcuts`]. + +[[annotation-method-interceptors]] +=== Each Annotation Has Its Own Method Interceptor + +Each annotation has its own dedicated method interceptor. +The reason for this is to make things more composable. +For example, if needed, you can disable the Spring Security defaults and <<_enabling_certain_annotations,publish only the `@PostAuthorize` method interceptor>>. + +The method interceptors are as follows: + +* For <>, Spring Security uses {security-api-url}org/springframework/security/authorization/method/AuthorizationManagerBeforeMethodInterceptor.html[`AuthenticationManagerBeforeMethodInterceptor#preAuthorize`], which in turn uses {security-api-url}org/springframework/security/authorization/method/PreAuthorizeAuthorizationManager.html[`PreAuthorizeAuthorizationManager`] +* For <>, Spring Security uses {security-api-url}org/springframework/security/authorization/method/AuthorizationManagerAfterMethodInterceptor.html[`AuthenticationManagerAfterMethodInterceptor#postAuthorize`], which in turn uses {security-api-url}org/springframework/security/authorization/method/PostAuthorizeAuthorizationManager.html[`PostAuthorizeAuthorizationManager`] +* For <>, Spring Security uses {security-api-url}org/springframework/security/authorization/method/PreFilterAuthorizationMethodInterceptor.html[`PreFilterAuthorizationMethodInterceptor`] +* For <>, Spring Security uses {security-api-url}org/springframework/security/authorization/method/PostFilterAuthorizationMethodInterceptor.html[`PostFilterAuthorizationMethodInterceptor`] +* For <>, Spring Security uses {security-api-url}org/springframework/security/authorization/method/AuthorizationManagerBeforeMethodInterceptor.html[`AuthenticationManagerBeforeMethodInterceptor#secured`], which in turn uses {security-api-url}org/springframework/security/authorization/method/SecuredAuthorizationManager.html[`SecuredAuthorizationManager`] +* For JSR-250 annotations, Spring Security uses {security-api-url}org/springframework/security/authorization/method/AuthorizationManagerBeforeMethodInterceptor.html[`AuthenticationManagerBeforeMethodInterceptor#jsr250`], which in turn uses {security-api-url}org/springframework/security/authorization/method/Jsr250AuthorizationManager.html[`Jsr250AuthorizationManager`] + +Generally speaking, you can consider the following listing as representative of what interceptors Spring Security publishes when you add `@EnableMethodSecurity`: + +==== +.Java +[source,java,role="primary"] ---- - +@Bean +@Role(BeanDefinition.ROLE_INFRASTRUCTURE) +static Advisor preAuthorizeMethodInterceptor() { + return AuthorizationManagerBeforeMethodInterceptor.preAuthorize(); +} + +@Bean +@Role(BeanDefinition.ROLE_INFRASTRUCTURE) +static Advisor postAuthorizeMethodInterceptor() { + return AuthorizationManagerAfterMethodInterceptor.postAuthorize(); +} + +@Bean +@Role(BeanDefinition.ROLE_INFRASTRUCTURE) +static Advisor preFilterMethodInterceptor() { + return AuthorizationManagerBeforeMethodInterceptor.preFilter(); +} + +@Bean +@Role(BeanDefinition.ROLE_INFRASTRUCTURE) +static Advisor postFilterMethodInterceptor() { + return AuthorizationManagerAfterMethodInterceptor.postFilter(); +} ---- ==== -Adding an annotation to a method (on a class or interface) would then limit the access to that method accordingly. -Spring Security's native annotation support defines a set of attributes for the method. -These will be passed to the `DefaultAuthorizationMethodInterceptorChain` for it to make the actual decision: +[[favor-granting-authorities]] +=== Favor Granting Authorities Over Complicated SpEL Expressions + +Quite often it can be tempting to introduce a complicated SpEL expression like the following: -.Method Security Annotation Usage ==== .Java [source,java,role="primary"] ---- -public interface BankService { - @PreAuthorize("hasRole('USER')") - Account readAccount(Long id); +@PreAuthorize("hasAuthority('permission:read') || hasRole('ADMIN')") +---- - @PreAuthorize("hasRole('USER')") - List findAccounts(); +.Kotlin +[source,kotlin,role="kotlin"] +---- +@PreAuthorize("hasAuthority('permission:read') || hasRole('ADMIN')") +---- +==== + +However, you could instead grant `permission:read` to those with `ROLE_ADMIN`. +One way to do this is with a `RoleHierarchy` like so: - @PreAuthorize("hasRole('TELLER')") - Account post(Account account, Double amount); +==== +.Java +[source,java,role="primary"] +---- +@Bean +static RoleHierarchy roleHierarchy() { + return new RoleHierarchyImpl("ROLE_ADMIN > permission:read"); } ---- .Kotlin -[source,kotlin,role="secondary"] +[source,java,role="secondary"] ---- -interface BankService { - @PreAuthorize("hasRole('USER')") - fun readAccount(id : Long) : Account - - @PreAuthorize("hasRole('USER')") - fun findAccounts() : List - - @PreAuthorize("hasRole('TELLER')") - fun post(account : Account, amount : Double) : Account +companion object { + @Bean + fun roleHierarchy(): RoleHierarchy { + return RoleHierarchyImpl("ROLE_ADMIN > permission:read") + } } ---- + +.Xml +[source,xml,role="secondary"] +---- + + + +---- ==== -You can enable support for Spring Security's `@Secured` annotation using: +and then <>. +This then allows you to have a simpler <> expression like this one: -.@Secured Configuration ==== .Java [source,java,role="primary"] ---- -@Configuration -@EnableMethodSecurity(securedEnabled = true) -public class MethodSecurityConfig { - // ... -} +@PreAuthorize("hasAuthority('permission:read')") ---- .Kotlin [source,kotlin,role="secondary"] ---- -@Configuration -@EnableMethodSecurity(securedEnabled = true) -class MethodSecurityConfig { - // ... +@PreAuthorize("hasAuthority('permission:read')") +---- +==== + +Or, where possible, adapt application-specific authorization logic into granted authorities at login time. + +[[request-vs-method]] +== Comparing Request-level vs Method-level Authorization + +When should you favor method-level authorization over xref:servlet/authorization/authorize-http-requests.adoc[request-level authorization]? +Some of it comes down to taste; however, consider the following strengths list of each to help you decide. + +|=== +|| *request-level* | *method-level* +| *authorization type* | coarse-grained | fine-grained +| *configuration location* | declared in a config class | local to method declaration +| *configuration style* | DSL | Annotations +| *authorization definitions* | programmatic | SpEL +|=== + +The main tradeoff seems to be where you want your authorization rules to live. + +[NOTE] +It's important to remember that when you use annotation-based Method Security, then unannotated methods are not secured. +To protect against this, declare xref:servlet/authorization/authorize-http-requests.adoc#activate-request-security[a catch-all authorization rule] in your xref:servlet/configuration/java.adoc#jc-httpsecurity[`HttpSecurity`] instance. + +[[authorizing-with-annotations]] +== Authorizing with Annotations + +The primary way Spring Security enables method-level authorization support is through annotations that you can add to methods, classes, and interfaces. + +[[use-preauthorize]] +=== Authorizing Method Invocation with `@PreAuthorize` + +When <>, you can annotate a method with the {security-api-url}org/springframework/security/access/prepost/PreAuthorize.html[`@PreAuthorize`] annotation like so: + +==== +.Java +[source,java,role="primary"] +---- +@Component +public class BankService { + @PreAuthorize("hasRole('ADMIN')") + public Account readAccount(Long id) { + // ... is only invoked if the `Authentication` has the `ROLE_ADMIN` authority + } } ---- -.Xml -[source,xml,role="secondary"] +.Kotlin +[source,kotlin,role="secondary"] ---- - +@Component +open class BankService { + @PreAuthorize("hasRole('ADMIN')") + fun readAccount(val id: Long): Account { + // ... is only invoked if the `Authentication` has the `ROLE_ADMIN` authority + } +} ---- ==== -or JSR-250 using: +This is meant to indicate that the method can only be invoked if the provided expression `hasRole('ADMIN')` passes. + +You can then xref:servlet/test/method.adoc[test the class] to confirm it is enforcing the authorization rule like so: -.JSR-250 Configuration ==== .Java [source,java,role="primary"] ---- -@Configuration -@EnableMethodSecurity(jsr250Enabled = true) -public class MethodSecurityConfig { - // ... +@Autowired +BankService bankService; + +@WithMockUser(roles="ADMIN") +@Test +void readAccountWithAdminRoleThenInvokes() { + Account account = this.bankService.readAccount("12345678"); + // ... assertions +} + +@WithMockUser(roles="WRONG") +@Test +void readAccountWithWrongRoleThenAccessDenied() { + assertThatExceptionOfType(AccessDeniedException.class).isThrownBy( + () -> this.bankService.readAccount("12345678")); } ---- .Kotlin [source,kotlin,role="secondary"] ---- -@Configuration -@EnableMethodSecurity(jsr250Enabled = true) -class MethodSecurityConfig { - // ... +@WithMockUser(roles="ADMIN") +@Test +fun readAccountWithAdminRoleThenInvokes() { + val account: Account = this.bankService.readAccount("12345678") + // ... assertions +} + +@WithMockUser(roles="WRONG") +@Test +fun readAccountWithWrongRoleThenAccessDenied() { + assertThatExceptionOfType(AccessDeniedException::class.java).isThrownBy { + this.bankService.readAccount("12345678") + } } ---- +==== -.Xml -[source,xml,role="secondary"] +[TIP] +`@PreAuthorize` also can be a <>, be defined <>, and use xref:servlet/authorization/expression-based.adoc[SpEL authorization expressions]. + +While `@PreAuthorize` is quite helpful for declaring needed authorities, it can also be used to evaluate more complex permissions that involve the method parameters. +To achieve that, you can use Spring Security's `@P` annotation to remember the parameter name: + +==== +.Java +[source,java,role="primary"] ---- - +@PreAuthorize("#username == authentication.name") +Collection findOrders(@P("username") String username) { ... } +---- + +.Kotlin +[source,java,role="secondary"] +---- +@PreAuthorize("#username == authentication.name") +fun findOrders(@P("username") val username: String): Collection { ... } ---- ==== -=== Customizing Authorization +Or, Spring Security also integrate with {spring-framework-reference-url}web.html#spring-web[Spring MVC] to identify parameters like so: -Spring Security's `@PreAuthorize`, `@PostAuthorize`, `@PreFilter`, and `@PostFilter` ship with rich expression-based support. +==== +[source,java,role="primary"] +---- +@GetMapping("/orders/{username}") +@PreAuthorize("#username == authentication.name") +Collection findOrders(@PathVariable("username") String username) { ... } +---- + +[source,kotlin,role="secondary"] +---- +@GetMapping("/orders/{username}") +@PreAuthorize("#username == authentication.name") +fun findOrders(@PathVariable("username") val username: String): Collection { ... } +---- +==== -[[jc-method-security-custom-expression-handler]] -If you need to customize the way that expressions are handled, you can expose a custom `MethodSecurityExpressionHandler`, like so: +The above two snippets are ensuring that the user can only request orders that belong to them by comparing the username parameter to xref:servlet/authentication/architecture.adoc#servlet-authentication-authentication[`Authentication#getName`]. + +The result is that the above method will only be invoked if the `username` in the request path matches the logged-in user's `name`. +If not, Spring Security will throw an `AccessDeniedException` and return a 403 status code. + +[[use-postauthorize]] +=== Authorization Method Results with `@PostAuthorize` + +When Method Security is active, you can annotate a method with the {security-api-url}org/springframework/security/access/prepost/PostAuthorize.html[`@PostAuthorize`] annotation like so: -.Custom MethodSecurityExpressionHandler ==== .Java [source,java,role="primary"] ---- -@Bean -static MethodSecurityExpressionHandler methodSecurityExpressionHandler() { - DefaultMethodSecurityExpressionHandler handler = new DefaultMethodSecurityExpressionHandler(); - handler.setTrustResolver(myCustomTrustResolver); - return handler; +@Component +public class BankService { + @PostAuthorize("returnObject.owner == authentication.name") + public Account readAccount(Long id) { + // ... is only returned if the `Account` belongs to the logged in user + } } ---- .Kotlin [source,kotlin,role="secondary"] ---- -companion object { - @Bean - fun methodSecurityExpressionHandler() : MethodSecurityExpressionHandler { - val handler = DefaultMethodSecurityExpressionHandler(); - handler.setTrustResolver(myCustomTrustResolver); - return handler; +@Component +open class BankService { + @PostAuthorize("returnObject.owner == authentication.name") + fun readAccount(val id: Long): Account { + // ... is only returned if the `Account` belongs to the logged in user } } ---- +==== -.Xml -[source,xml,role="secondary"] +This is meant to indicate that the method can only return the value if the provided expression `returnObject.owner == authentication.name` passes. +`returnObject` represents the `Account` object to be returned. + +You can then xref:servlet/test/method.adoc[test the class] to confirm it is enforcing the authorization rule: + +==== +.Java +[source,java,role="primary"] ---- - - - +@Autowired +BankService bankService; - - - +@WithMockUser(username="owner") +@Test +void readAccountWhenOwnedThenReturns() { + Account account = this.bankService.readAccount("12345678"); + // ... assertions +} + +@WithMockUser(username="wrong") +@Test +void readAccountWhenNotOwnedThenAccessDenied() { + assertThatExceptionOfType(AccessDeniedException.class).isThrownBy( + () -> this.bankService.readAccount("12345678")); +} +---- + +.Kotlin +[source,kotlin,role="secondary"] +---- +@WithMockUser(username="owner") +@Test +fun readAccountWhenOwnedThenReturns() { + val account: Account = this.bankService.readAccount("12345678") + // ... assertions +} + +@WithMockUser(username="wrong") +@Test +fun readAccountWhenNotOwnedThenAccessDenied() { + assertThatExceptionOfType(AccessDeniedException::class.java).isThrownBy { + this.bankService.readAccount("12345678") + } +} ---- ==== [TIP] +`@PostAuthorize` also can be a <>, be defined <>, and use xref:servlet/authorization/expression-based.adoc[SpEL Authorization Expressions]. + +`@PostAuthorize` is particularly helpful when defending against https://cheatsheetseries.owasp.org/cheatsheets/Insecure_Direct_Object_Reference_Prevention_Cheat_Sheet.html[Insecure Direct Object Reference]. +In fact, it can be defined as a <> like so: + ==== -We expose `MethodSecurityExpressionHandler` using a `static` method to ensure that Spring publishes it before it initializes Spring Security's method security `@Configuration` classes -==== +.Java +[source,java,role="primary"] +---- +@Target({ ElementType.METHOD, ElementType.TYPE }) +@Retention(RetentionPolicy.RUNTIME) +@PostAuthorize("returnObject.owner == authentication.name") +public @interface RequireOwnership {} +---- -Also, for role-based authorization, Spring Security adds a default `ROLE_` prefix, which is uses when evaluating expressions like `hasRole`. +.Kotlin +[source,kotlin,role="secondary"] +---- +@Target(ElementType.METHOD, ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@PostAuthorize("returnObject.owner == authentication.name") +annotation class RequireOwnership +---- +==== -[[jc-method-security-custom-granted-authority-defaults]] -You can configure the authorization rules to use a different prefix by exposing a `GrantedAuthorityDefaults` bean, like so: +Allowing you to instead annotate the service in the following way: -.Custom MethodSecurityExpressionHandler ==== .Java [source,java,role="primary"] ---- -@Bean -static GrantedAuthorityDefaults grantedAuthorityDefaults() { - return new GrantedAuthorityDefaults("MYPREFIX_"); +@Component +public class BankService { + @RequireOwnership + public Account readAccount(Long id) { + // ... is only returned if the `Account` belongs to the logged in user + } } ---- .Kotlin [source,kotlin,role="secondary"] ---- -companion object { - @Bean - fun grantedAuthorityDefaults() : GrantedAuthorityDefaults { - return GrantedAuthorityDefaults("MYPREFIX_"); +@Component +open class BankService { + @RequireOwnership + fun readAccount(val id: Long): Account { + // ... is only returned if the `Account` belongs to the logged in user } } ---- +==== -.Xml -[source,xml,role="secondary"] +The result is that the above method will only return the `Account` if its `owner` attribute matches the logged-in user's `name`. +If not, Spring Security will throw an `AccessDeniedException` and return a 403 status code. + +[[use-prefilter]] +=== Filtering Method Parameters with `@PreFilter` + +[NOTE] +`@PreFilter` is not yet supported for Kotlin-specific data types; for that reason, only Java snippets are shown + +When Method Security is active, you can annotate a method with the {security-api-url}org/springframework/security/access/prepost/PreFilter.html[`@PreFilter`] annotation like so: + +==== +.Java +[source,java,role="primary"] ---- - +@Component +public class BankService { + @PreFilter("filterObject.owner == authentication.name") + public Collection updateAccounts(Account... accounts) { + // ... `accounts` will only contain the accounts owned by the logged-in user + return updated; + } +} +---- +==== - - - +This is meant to filter out any values from `accounts` where the expression `filterObject.owner == authentication.name` fails. +`filterObject` represents each `account` in `accounts` and is used to test each `account`. + +You can then test the class in the following way to confirm it is enforcing the authorization rule: + +==== +.Java +[source,java,role="primary"] +---- +@Autowired +BankService bankService; + +@WithMockUser(username="owner") +@Test +void updateAccountsWhenOwnedThenReturns() { + Account ownedBy = ... + Account notOwnedBy = ... + Collection updated = this.bankService.updateAccounts(ownedBy, notOwnedBy); + assertThat(updated).containsOnly(ownedBy); +} ---- ==== [TIP] +`@PreFilter` also can be a <>, be defined <>, and use xref:servlet/authorization/expression-based.adoc[SpEL Authorization Expressions]. + +`@PreFilter` supports arrays, collections, maps, and streams (so long as the stream is still open). + +For example, the above `updateAccounts` declaration will function the same way as the following other four: + ==== -We expose `GrantedAuthorityDefaults` using a `static` method to ensure that Spring publishes it before it initializes Spring Security's method security `@Configuration` classes +.Java +[source,java,role="primary"] +---- +@PreFilter("filterObject.owner == authentication.name") +public Collection updateAccounts(Account[] accounts) + +@PreFilter("filterObject.owner == authentication.name") +public Collection updateAccounts(Collection accounts) + +@PreFilter("filterObject.value.owner == authentication.name") +public Collection updateAccounts(Map accounts) + +@PreFilter("filterObject.owner == authentication.name") +public Collection updateAccounts(Stream accounts) +---- ==== -[[jc-method-security-custom-authorization-manager]] -=== Custom Authorization Managers +The result is that the above method will only have the `Account` instances where their `owner` attribute matches the logged-in user's `name`. -Method authorization is a combination of before- and after-method authorization. +[[use-postfilter]] +=== Filtering Method Results with `@PostFilter` [NOTE] +`@PostFilter` is not yet supported for Kotlin-specific data types; for that reason, only Java snippets are shown + +When Method Security is active, you can annotate a method with the {security-api-url}org/springframework/security/access/prepost/PostFilter.html[`@PostFilter`] annotation like so: + ==== -Before-method authorization is performed before the method is invoked. -If that authorization denies access, the method is not invoked, and an `AccessDeniedException` is thrown. -After-method authorization is performed after the method is invoked, but before the method returns to the caller. -If that authorization denies access, the value is not returned, and an `AccessDeniedException` is thrown +.Java +[source,java,role="primary"] +---- +@Component +public class BankService { + @PostFilter("filterObject.owner == authentication.name") + public Collection readAccounts(String... ids) { + // ... the return value will be filtered to only contain the accounts owned by the logged-in user + return accounts; + } +} +---- ==== -To recreate what adding `@EnableMethodSecurity` does by default, you would publish the following configuration: +This is meant to filter out any values from the return value where the expression `filterObject.owner == authentication.name` fails. +`filterObject` represents each `account` in `accounts` and is used to test each `account`. + +You can then test the class like so to confirm it is enforcing the authorization rule: -.Full Pre-post Method Security Configuration ==== .Java [source,java,role="primary"] ---- -@Configuration -@EnableMethodSecurity(prePostEnabled = false) -class MethodSecurityConfig { - @Bean - @Role(BeanDefinition.ROLE_INFRASTRUCTURE) - Advisor preFilterAuthorizationMethodInterceptor() { - return new PreFilterAuthorizationMethodInterceptor(); - } +@Autowired +BankService bankService; - @Bean - @Role(BeanDefinition.ROLE_INFRASTRUCTURE) - Advisor preAuthorizeAuthorizationMethodInterceptor() { - return AuthorizationManagerBeforeMethodInterceptor.preAuthorize(); - } +@WithMockUser(username="owner") +@Test +void readAccountsWhenOwnedThenReturns() { + Collection accounts = this.bankService.updateAccounts("owner", "not-owner"); + assertThat(accounts).hasSize(1); + assertThat(accounts.get(0).getOwner()).isEqualTo("owner"); +} +---- +==== - @Bean - @Role(BeanDefinition.ROLE_INFRASTRUCTURE) - Advisor postAuthorizeAuthorizationMethodInterceptor() { - return AuthorizationManagerAfterMethodInterceptor.postAuthorize(); - } +[TIP] +`@PostFilter` also can be a <>, be defined <>, and use xref:servlet/authorization/expression-based.adoc[SpEL Authorization Expressions]. - @Bean - @Role(BeanDefinition.ROLE_INFRASTRUCTURE) - Advisor postFilterAuthorizationMethodInterceptor() { - return new PostFilterAuthorizationMethodInterceptor(); - } +`@PostFilter` supports arrays, collections, maps, and streams (so long as the stream is still open). + +For example, the above `readAccounts` declaration will function the same way as the following other three: + +```java +@PostFilter("filterObject.owner == authentication.name") +public Account[] readAccounts(String... ids) + +@PostFilter("filterObject.value.owner == authentication.name") +public Map readAccounts(String... ids) + +@PostFilter("filterObject.owner == authentication.name") +public Stream readAccounts(String... ids) +``` + +The result is that the above method will return the `Account` instances where their `owner` attribute matches the logged-in user's `name`. + +[NOTE] +In-memory filtering can obviously be expensive, and so be considerate of whether it is better to xref:servlet/integrations/data.adoc[filter the data in the data layer] instead. + +[[use-secured]] +=== Authorizing Method Invocation with `@Secured` + +{security-api-url}org/springframework/security/access/annotation/Secured.html[`@Secured`] is a legacy option for authorizing invocations. +<> supercedes it and is recommended instead. + +To use the `@Secured` annotation, you should first change your Method Security declaration to enable it like so: + +==== +.Java +[source,java,role="primary"] +---- +@EnableMethodSecurity(securedEnabled = true) +---- + +.Kotlin +[source,kotlin,role="secondary"] +---- +@EnableMethodSecurity(securedEnabled = true) +---- + +.Xml +[source,xml,role="secondary"] +---- + +---- +==== + +This will cause Spring Security to publish <> that authorizes methods, classes, and interfaces annotated with `@Secured`. + +[[use-jsr250]] +=== Authorizing Method Invocation with JSR-250 Annotations + +In case you would like to use https://jcp.org/en/jsr/detail?id=250[JSR-250] annotations, Spring Security also supports that. +<> has more expressive power and is thus recommended. + +To use the JSR-250 annotations, you should first change your Method Security declaration to enable them like so: + +==== +.Java +[source,java,role="primary"] +---- +@EnableMethodSecurity(jsr250Enabled = true) +---- + +.Kotlin +[source,kotlin,role="secondary"] +---- +@EnableMethodSecurity(jsr250Enabled = true) +---- + +.Xml +[source,xml,role="secondary"] +---- + +---- +==== + +This will cause Spring Security to publish <> that authorizes methods, classes, and interfaces annotated with `@RolesAllowed`, `@PermitAll`, and `@DenyAll`. + + +[[class-or-interface-annotations]] +=== Declaring Annotations at the Class or Interface Level + +It's also supported to have Method Security annotations at the class and interface level. + +If it is at the class level like so: + +==== +.Java +[source,java,role="primary"] +---- +@Controller +@PreAuthorize("hasAuthority('ROLE_USER')") +public class MyController { + @GetMapping("/endpoint") + public String endpoint() { ... } } ---- .Kotlin [source,kotlin,role="secondary"] ---- -@Configuration -@EnableMethodSecurity(prePostEnabled = false) -class MethodSecurityConfig { - @Bean - @Role(BeanDefinition.ROLE_INFRASTRUCTURE) - fun preFilterAuthorizationMethodInterceptor() : Advisor { - return PreFilterAuthorizationMethodInterceptor(); - } +@Controller +@PreAuthorize("hasAuthority('ROLE_USER')") +open class MyController { + @GetMapping("/endpoint") + fun endpoint(): String { ... } +} +---- +==== - @Bean - @Role(BeanDefinition.ROLE_INFRASTRUCTURE) - fun preAuthorizeAuthorizationMethodInterceptor() : Advisor { - return AuthorizationManagerBeforeMethodInterceptor.preAuthorize(); - } +then all methods inherit the class-level behavior. - @Bean - @Role(BeanDefinition.ROLE_INFRASTRUCTURE) - fun postAuthorizeAuthorizationMethodInterceptor() : Advisor { - return AuthorizationManagerAfterMethodInterceptor.postAuthorize(); - } +Or, if it's declared like the following at both the class and method level: - @Bean - @Role(BeanDefinition.ROLE_INFRASTRUCTURE) - fun postFilterAuthorizationMethodInterceptor() : Advisor { - return PostFilterAuthorizationMethodInterceptor(); - } +==== +.Java +[source,java,role="primary"] +---- +@Controller +@PreAuthorize("hasAuthority('ROLE_USER')") +public class MyController { + @GetMapping("/endpoint") + @PreAuthorize("hasAuthority('ROLE_ADMIN')") + public String endpoint() { ... } +} +---- + +.Kotlin +[source,kotlin,role="secondary"] +---- +@Controller +@PreAuthorize("hasAuthority('ROLE_USER')") +open class MyController { + @GetMapping("/endpoint") + @PreAuthorize("hasAuthority('ROLE_ADMIN')") + fun endpoint(): String { ... } } ---- +==== + +then methods declaring the annotation override the class-level annotation. + +The same is true for interfaces, with the exception that if a class inherits the annotation from two different interfaces, then startup will fail. +This is because Spring Security has no way to tell which one you want to use. + +In cases like this, you can resolve the ambiguity by adding the annotation to the concrete method. + +[[meta-annotations]] +=== Using Meta Annotations + +Method Security supports meta annotations. +This means that you can take any annotation and improve readability based on your application-specific use cases. + +For example, you can simplify `@PreAuthorize("hasRole('ADMIN')")` to `@IsAdmin` like so: + +==== +.Java +[source,java,role="primary"] +---- +@Target({ ElementType.METHOD, ElementType.TYPE }) +@Retention(RetentionPolicy.RUNTIME) +@PreAuthorize("hasRole('ADMIN')") +public @interface IsAdmin {} +---- -.Xml -[source,xml,role="secondary"] +.Kotlin +[source,kotlin,role="secondary"] ---- - - - - - - - - +@Target(ElementType.METHOD, ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@PreAuthorize("hasRole('ADMIN')") +annotation class IsAdmin ---- ==== -Notice that Spring Security's method security is built using Spring AOP. -So, interceptors are invoked based on the order specified. -This can be customized by calling `setOrder` on the interceptor instances like so: +And the result is that on your secured methods you can now do the following instead: -.Publish Custom Advisor ==== .Java [source,java,role="primary"] ---- -@Bean -@Role(BeanDefinition.ROLE_INFRASTRUCTURE) -Advisor postFilterAuthorizationMethodInterceptor() { - PostFilterAuthorizationMethodInterceptor interceptor = new PostFilterAuthorizationMethodInterceptor(); - interceptor.setOrder(AuthorizationInterceptorOrders.POST_AUTHORIZE.getOrder() - 1); - return interceptor; +@Component +public class BankService { + @IsAdmin + public Account readAccount(Long id) { + // ... is only returned if the `Account` belongs to the logged in user + } } ---- .Kotlin [source,kotlin,role="secondary"] ---- -@Bean -@Role(BeanDefinition.ROLE_INFRASTRUCTURE) -fun postFilterAuthorizationMethodInterceptor() : Advisor { - val interceptor = PostFilterAuthorizationMethodInterceptor(); - interceptor.setOrder(AuthorizationInterceptorOrders.POST_AUTHORIZE.getOrder() - 1); - return interceptor; +@Component +open class BankService { + @IsAdmin + fun readAccount(val id: Long): Account { + // ... is only returned if the `Account` belongs to the logged in user + } } ---- - -.Xml -[source,xml,role="secondary"] ----- - - - ----- ==== -You may want to only support `@PreAuthorize` in your application, in which case you can do the following: +This results in more readable method definitions. +[[enable-annotation]] +=== Enabling Certain Annotations -.Only @PreAuthorize Configuration +You can turn off ``@EnableMethodSecurity``'s pre-configuration and replace it with you own. +You may choose to do this if you want to <> or `Pointcut`. +Or you may simply want to only enable a specific annotation, like `@PostAuthorize`. + +You can do this in the following way: + +.Only @PostAuthorize Configuration ==== .Java [source,java,role="primary"] @@ -407,8 +891,8 @@ You may want to only support `@PreAuthorize` in your application, in which case class MethodSecurityConfig { @Bean @Role(BeanDefinition.ROLE_INFRASTRUCTURE) - Advisor preAuthorize() { - return AuthorizationManagerBeforeMethodInterceptor.preAuthorize(); + Advisor postAuthorize() { + return AuthorizationManagerBeforeMethodInterceptor.postAuthorize(); } } ---- @@ -421,8 +905,8 @@ class MethodSecurityConfig { class MethodSecurityConfig { @Bean @Role(BeanDefinition.ROLE_INFRASTRUCTURE) - fun preAuthorize() : Advisor { - return AuthorizationManagerBeforeMethodInterceptor.preAuthorize() + fun postAuthorize() : Advisor { + return AuthorizationManagerBeforeMethodInterceptor.postAuthorize() } } ---- @@ -434,36 +918,60 @@ class MethodSecurityConfig { - + factory-method="postAuthorize"/> ---- ==== -Or, you may have a custom before-method `AuthorizationManager` that you want to add to the list. +The above snippet achieves this by first disabling Method Security's pre-configurations and then publishing <> itself. -In this case, you will need to tell Spring Security both the `AuthorizationManager` and to which methods and classes your authorization manager applies. +[[use-intercept-methods]] +== Authorizing with `` -Thus, you can configure Spring Security to invoke your `AuthorizationManager` in between `@PreAuthorize` and `@PostAuthorize` like so: +While using Spring Security's <> is preferred for method security, you can also use XML to declare bean authorization rules. -.Custom Before Advisor +If you need to declare it in your XML configuration instead, you can use xref:servlet/appendix/namespace/method-security.adoc#nsa-intercept-methods[``] like so: + +==== +.Xml +[source,xml,role="primary"] +---- + + + + + + +---- ==== +[NOTE] +This only supports matching method by prefix or by name. +If your needs are more complex than that, <> instead. + +[[use-programmatic-authorization]] +== Authorizing Methods Programmatically + +As you've already seen, there are several ways that you can specify non-trivial authorization rules using xref:servlet/authorization/expression-based.adoc[Method Security SpEL expressions]. + +There are a number of ways that you can instead allow your logic to be Java-based instead of SpEL-based. +This gives use access the entire Java language for increased testability and flow control. + +=== Using a Custom Bean in SpEL + +The first way to authorize a method programmatically is a two-step process. + +First, declare a bean that has a method that takes a `MethodSecurityExpressionOperations` instance like the following: + +==== .Java [source,java,role="primary"] ---- -@Configuration -@EnableMethodSecurity -class MethodSecurityConfig { - @Bean - @Role(BeanDefinition.ROLE_INFRASTRUCTURE) - public Advisor customAuthorize() { - JdkRegexpMethodPointcut pattern = new JdkRegexpMethodPointcut(); - pattern.setPattern("org.mycompany.myapp.service.*"); - AuthorizationManager rule = AuthorityAuthorizationManager.isAuthenticated(); - AuthorizationManagerBeforeMethodInterceptor interceptor = new AuthorizationManagerBeforeMethodInterceptor(pattern, rule); - interceptor.setOrder(AuthorizationInterceptorsOrder.PRE_AUTHORIZE_ADVISOR_ORDER.getOrder() + 1); - return interceptor; +@Component("authz") +public class AuthorizationLogic { + public boolean decide(MethodSecurityExpressionOperations operations) { + // ... authorization logic } } ---- @@ -471,101 +979,102 @@ class MethodSecurityConfig { .Kotlin [source,kotlin,role="secondary"] ---- -@Configuration -@EnableMethodSecurity -class MethodSecurityConfig { - @Bean - @Role(BeanDefinition.ROLE_INFRASTRUCTURE) - fun customAuthorize() : Advisor { - val pattern = JdkRegexpMethodPointcut(); - pattern.setPattern("org.mycompany.myapp.service.*"); - val rule = AuthorityAuthorizationManager.isAuthenticated(); - val interceptor = AuthorizationManagerBeforeMethodInterceptor(pattern, rule); - interceptor.setOrder(AuthorizationInterceptorsOrder.PRE_AUTHORIZE_ADVISOR_ORDER.getOrder() + 1); - return interceptor; - } +@Component("authz") +open class AuthorizationLogic { + fun decide(val operations: MethodSecurityExpressionOperations): boolean { + // ... authorization logic + } } ---- +==== -.Xml -[source,xml,role="secondary"] ----- - +Then, reference that bean in your annotations in the following way: - +==== +.Java +[source,java,role="primary"] +---- +@Controller +public class MyController { + @PreAuthorize("@authz.decide(#root)") + @GetMapping("/endpoint") + public String endpoint() { + // ... + } +} +---- - - - - - - - - - - - +.Kotlin +[source,kotlin,role="secondary"] +---- +@Controller +open class MyController { + @PreAuthorize("@authz.decide(#root)") + @GetMapping("/endpoint") + fun String endpoint() { + // ... + } +} ---- ==== -[TIP] -==== -You can place your interceptor in between Spring Security method interceptors using the order constants specified in `AuthorizationInterceptorsOrder`. -==== +Spring Security will invoke the given method on that bean for each method invocation. -The same can be done for after-method authorization. -After-method authorization is generally concerned with analysing the return value to verify access. +What's nice about this is all your authorization logic is in a separate class that can be independently unit tested and verified for correctness. +It also has access to the full Java language. -For example, you might have a method that confirms that the account requested actually belongs to the logged-in user like so: +[[custom-authorization-managers]] +=== Using a Custom Authorization Manager + +The second way to authorize a method programmatically is two create a custom xref:servlet/authorization/architecture.adoc#_the_authorizationmanager[`AuthorizationManager`]. + +First, declare an authorization manager instance, perhaps like this one: -.@PostAuthorize example ==== .Java [source,java,role="primary"] ---- -public interface BankService { - - @PreAuthorize("hasRole('USER')") - @PostAuthorize("returnObject.owner == authentication.name") - Account readAccount(Long id); +@Component +public class MyAuthorizationManager implements AuthorizationManager { + public AuthorizationDecision check(Supplier authentication, MethodInvocation invocation) { + // ... authorization logic + } } ---- .Kotlin [source,kotlin,role="secondary"] ---- -interface BankService { - - @PreAuthorize("hasRole('USER')") - @PostAuthorize("returnObject.owner == authentication.name") - fun readAccount(id : Long) : Account +@Component("authz") +open class MyAuthorizationManager: AuthorizationManager { + fun check(val authentication: Supplier, val invocation: MethodInvocation): AuthorizationDecision { + // ... authorization logic + } } ---- ==== -You can supply your own `AuthorizationMethodInterceptor` to customize how access to the return value is evaluated. +Then, publish the method interceptor with a pointcut that corresponds to when you want that `AuthorizationManager` to run. +For example, you could replace how `@PreAuthorize` and `@PostAuthorize` work like so: -For example, if you have your own custom annotation, you can configure it like so: - - -.Custom After Advisor +.Only @PostAuthorize Configuration ==== .Java [source,java,role="primary"] ---- @Configuration -@EnableMethodSecurity +@EnableMethodSecurity(prePostEnabled = false) class MethodSecurityConfig { + @Bean + @Role(BeanDefinition.ROLE_INFRASTRUCTURE) + Advisor postAuthorize(MyAuthorizationManager manager) { + return AuthorizationManagerBeforeMethodInterceptor.preAuthorize(manager); + } + @Bean @Role(BeanDefinition.ROLE_INFRASTRUCTURE) - public Advisor customAuthorize(AuthorizationManager rules) { - AnnotationMatchingPointcut pattern = new AnnotationMatchingPointcut(MySecurityAnnotation.class); - AuthorizationManagerAfterMethodInterceptor interceptor = new AuthorizationManagerAfterMethodInterceptor(pattern, rules); - interceptor.setOrder(AuthorizationInterceptorsOrder.POST_AUTHORIZE_ADVISOR_ORDER.getOrder() + 1); - return interceptor; + Advisor postAuthorize(MyAuthorizationManager manager) { + return AuthorizationManagerAfterMethodInterceptor.postAuthorize(manager); } } ---- @@ -574,15 +1083,18 @@ class MethodSecurityConfig { [source,kotlin,role="secondary"] ---- @Configuration -@EnableMethodSecurity +@EnableMethodSecurity(prePostEnabled = false) class MethodSecurityConfig { + @Bean + @Role(BeanDefinition.ROLE_INFRASTRUCTURE) + fun preAuthorize(val manager: MyAuthorizationManager) : Advisor { + return AuthorizationManagerBeforeMethodInterceptor.preAuthorize(manager) + } + @Bean @Role(BeanDefinition.ROLE_INFRASTRUCTURE) - fun customAuthorize(rules : AuthorizationManager) : Advisor { - val pattern = AnnotationMatchingPointcut(MySecurityAnnotation::class.java); - val interceptor = AuthorizationManagerAfterMethodInterceptor(pattern, rules); - interceptor.setOrder(AuthorizationInterceptorsOrder.POST_AUTHORIZE_ADVISOR_ORDER.getOrder() + 1); - return interceptor; + fun postAuthorize(val manager: MyAuthorizationManager) : Advisor { + return AuthorizationManagerAfterMethodInterceptor.postAuthorize(manager) } } ---- @@ -590,353 +1102,360 @@ class MethodSecurityConfig { .Xml [source,xml,role="secondary"] ---- - + - - - - - - - - - - + + + + + + ---- ==== -and it will be invoked after the `@PostAuthorize` interceptor. +[TIP] +==== +You can place your interceptor in between Spring Security method interceptors using the order constants specified in `AuthorizationInterceptorsOrder`. +==== -[[jc-enable-global-method-security]] -== EnableGlobalMethodSecurity +[[customizing-expression-handling]] +=== Customizing Expression Handling -We can enable annotation-based security by using the `@EnableGlobalMethodSecurity` annotation on any `@Configuration` instance. -The following example enables Spring Security's `@Secured` annotation: +Or, third, you can customize how each SpEL expression is handled. +To do that, you can expose a custom {security-api-url}org.springframework.security.access.expression.method.MethodSecurityExpressionHandler.html[`MethodSecurityExpressionHandler`], like so: +.Custom MethodSecurityExpressionHandler ==== .Java [source,java,role="primary"] ---- -@Configuration -@EnableGlobalMethodSecurity(securedEnabled = true) -public class MethodSecurityConfig { -// ... +@Bean +static MethodSecurityExpressionHandler methodSecurityExpressionHandler(RoleHierarchy roleHierarchy) { + DefaultMethodSecurityExpressionHandler handler = new DefaultMethodSecurityExpressionHandler(); + handler.setRoleHierarchy(roleHierarchy); + return handler; } ---- .Kotlin [source,kotlin,role="secondary"] ---- -@Configuration -@EnableGlobalMethodSecurity(securedEnabled = true) -open class MethodSecurityConfig { - // ... +companion object { + @Bean + fun methodSecurityExpressionHandler(val roleHierarchy: RoleHierarchy) : MethodSecurityExpressionHandler { + val handler = DefaultMethodSecurityExpressionHandler(); + handler.setRoleHierarchy(roleHierarchy); + return handler; + } } ---- + +.Xml +[source,xml,role="secondary"] +---- + + + + + + + +---- +==== + +[TIP] +==== +We expose `MethodSecurityExpressionHandler` using a `static` method to ensure that Spring publishes it before it initializes Spring Security's method security `@Configuration` classes ==== -Adding an annotation to a method (on a class or interface) would then limit the access to that method accordingly. -Spring Security's native annotation support defines a set of attributes for the method. -These are passed to the `AccessDecisionManager` for it to make the actual decision: +You can also <> to add your own custom authorization expressions beyond the defaults. + +[[use-aspectj]] +== Authorizing with AspectJ + +[[match-by-pointcut]] +=== Matching Methods with Custom Pointcuts + +Being built on Spring AOP, you can declare patterns that are not related to annotations, similar to xref:servlet/authorization/authorize-http-requests.adoc[request-level authorization]. +This has the potential advantage of centralizing method-level authorization rules. + +For example, you can use publish your own `Advisor` or use xref:servlet/appendix/namespace/method-security.adoc#nsa-protect-pointcut[``] to match AOP expressions to authorization rules for your service layer like so: ==== .Java [source,java,role="primary"] ---- -public interface BankService { - -@Secured("IS_AUTHENTICATED_ANONYMOUSLY") -public Account readAccount(Long id); +import static org.springframework.security.authorization.AuthorityAuthorizationManager.hasRole; -@Secured("IS_AUTHENTICATED_ANONYMOUSLY") -public Account[] findAccounts(); - -@Secured("ROLE_TELLER") -public Account post(Account account, double amount); +@Bean +@Role(BeanDefinition.ROLE_INFRASTRUCTURE) +static Advisor protectServicePointcut() { + JdkRegexpMethodPointcut pattern = new JdkRegexpMethodPointcut(); + pattern.setPattern("execution(* com.mycompany.*Service.*(..))"); + return new AuthorizationManagerBeforeMethodInterceptor(pattern, hasRole("USER")); } ---- .Kotlin [source,kotlin,role="secondary"] ---- -interface BankService { - @Secured("IS_AUTHENTICATED_ANONYMOUSLY") - fun readAccount(id: Long): Account - - @Secured("IS_AUTHENTICATED_ANONYMOUSLY") - fun findAccounts(): Array +import static org.springframework.security.authorization.AuthorityAuthorizationManager.hasRole; - @Secured("ROLE_TELLER") - fun post(account: Account, amount: Double): Account +companion object { + @Bean + @Role(BeanDefinition.ROLE_INFRASTRUCTURE) + fun protectServicePointcut(): Advisor { + var pattern = JdkRegexpMethodPointcut(); + pattern.setPattern("execution(* com.mycompany.*Service.*(..))"); + return new AuthorizationManagerBeforeMethodInterceptor(pattern, hasRole("USER")); + } } ---- + +[source,xml] +---- + + + +---- ==== -Support for JSR-250 annotations can be enabled by using: +[[weave-aspectj]] +=== Integrate with AspectJ Byte-weaving + +Performance can at times be enhanced by using AspectJ to weave Spring Security advice into the byte code of your beans. + +After setting up AspectJ, you can quite simply state in the `@EnableMethodSecurity` annotation or `` element that you are using AspectJ: ==== .Java [source,java,role="primary"] ---- -@Configuration -@EnableGlobalMethodSecurity(jsr250Enabled = true) -public class MethodSecurityConfig { -// ... -} +@EnableMethodSecurity(mode=AdviceMode.ASPECTJ) ---- .Kotlin [source,kotlin,role="secondary"] ---- -@Configuration -@EnableGlobalMethodSecurity(jsr250Enabled = true) -open class MethodSecurityConfig { - // ... -} +@EnableMethodSecurity(mode=AdviceMode.ASPECTJ) +---- + +.Xml +[source,xml,role="secondary"] +---- + ---- ==== -These are standards-based and let simple role-based constraints be applied but do not have the power Spring Security's native annotations. -To use the new expression-based syntax, you would use: +And the result will be that Spring Security will publish its advisors as AspectJ advice so that they can be woven in accordingly. + +[[migration-enableglobalmethodsecurity]] +== Migrating from `@EnableGlobalMethodSecurity` + +If you are using `@EnableGlobalMethodSecurity`, you should migrate to `@EnableMethodSecurity`. + +[[servlet-replace-globalmethodsecurity-with-methodsecurity]] +=== Replace xref:servlet/authorization/method-security.adoc#jc-enable-global-method-security[global method security] with xref:servlet/authorization/method-security.adoc#jc-enable-method-security[method security] + +{security-api-url}org/springframework/security/config/annotation/method/configuration/EnableGlobalMethodSecurity.html[`@EnableGlobalMethodSecurity`] and xref:servlet/appendix/namespace/method-security.adoc#nsa-global-method-security[``] are deprecated in favor of {security-api-url}org/springframework/security/config/annotation/method/configuration/EnableMethodSecurity.html[`@EnableMethodSecurity`] and xref:servlet/appendix/namespace/method-security.adoc#nsa-method-security[``], respectively. +The new annotation and XML element activate Spring's xref:servlet/authorization/method-security.adoc#jc-enable-method-security[pre-post annotations] by default and use `AuthorizationManager` internally. + +This means that the following two listings are functionally equivalent: ==== .Java [source,java,role="primary"] ---- -@Configuration @EnableGlobalMethodSecurity(prePostEnabled = true) -public class MethodSecurityConfig { -// ... -} ---- .Kotlin [source,kotlin,role="secondary"] ---- -@Configuration @EnableGlobalMethodSecurity(prePostEnabled = true) -open class MethodSecurityConfig { - // ... -} +---- + +.Xml +[source,xml,role="secondary"] +---- + ---- ==== -The equivalent Java code is: +and: ==== .Java [source,java,role="primary"] ---- -public interface BankService { - -@PreAuthorize("isAnonymous()") -public Account readAccount(Long id); - -@PreAuthorize("isAnonymous()") -public Account[] findAccounts(); - -@PreAuthorize("hasAuthority('ROLE_TELLER')") -public Account post(Account account, double amount); -} +@EnableMethodSecurity ---- .Kotlin [source,kotlin,role="secondary"] ---- -interface BankService { - @PreAuthorize("isAnonymous()") - fun readAccount(id: Long): Account - - @PreAuthorize("isAnonymous()") - fun findAccounts(): Array +@EnableMethodSecurity +---- - @PreAuthorize("hasAuthority('ROLE_TELLER')") - fun post(account: Account, amount: Double): Account -} +.Xml +[source,xml,role="secondary"] +---- + ---- ==== -== GlobalMethodSecurityConfiguration +For applications not using the pre-post annotations, make sure to turn it off to avoid activating unwanted behavior. -Sometimes, you may need to perform operations that are more complicated than are possible with the `@EnableGlobalMethodSecurity` annotation. -For these instances, you can extend the `GlobalMethodSecurityConfiguration`, ensuring that the `@EnableGlobalMethodSecurity` annotation is present on your subclass. -For example, if you wanted to provide a custom `MethodSecurityExpressionHandler`, you could use the following configuration: +For example, a listing like: ==== .Java [source,java,role="primary"] ---- -@Configuration -@EnableGlobalMethodSecurity(prePostEnabled = true) -public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration { - @Override - protected MethodSecurityExpressionHandler createExpressionHandler() { - // ... create and return custom MethodSecurityExpressionHandler ... - return expressionHandler; - } -} +@EnableGlobalMethodSecurity(securedEnabled = true) ---- .Kotlin [source,kotlin,role="secondary"] ---- -@Configuration -@EnableGlobalMethodSecurity(prePostEnabled = true) -open class MethodSecurityConfig : GlobalMethodSecurityConfiguration() { - override fun createExpressionHandler(): MethodSecurityExpressionHandler { - // ... create and return custom MethodSecurityExpressionHandler ... - return expressionHandler - } -} +@EnableGlobalMethodSecurity(securedEnabled = true) ---- -==== -For additional information about methods that can be overridden, see the Javadoc for the {security-api-url}org/springframework/security/config/annotation/method/configuration/GlobalMethodSecurityConfiguration.html[`GlobalMethodSecurityConfiguration`] class. - -[[ns-global-method]] -== The Element -This element is used to enable annotation-based security in your application (by setting the appropriate attributes on the element) and to group together security pointcut declarations that are applied across your entire application context. -You should only declare one `` element. -The following declaration enables support for Spring Security's `@Secured`: - -==== -[source,xml] +.Xml +[source,xml,role="secondary"] ---- - + ---- ==== -Adding an annotation to a method (on a class or interface) would then limit the access to that method accordingly. -Spring Security's native annotation support defines a set of attributes for the method. -These are passed to the `AccessDecisionManager` for it to make the actual decision. -The following example shows the `@Secured` annotation in a typical interface: +should change to: ==== .Java [source,java,role="primary"] ---- -public interface BankService { - -@Secured("IS_AUTHENTICATED_ANONYMOUSLY") -public Account readAccount(Long id); - -@Secured("IS_AUTHENTICATED_ANONYMOUSLY") -public Account[] findAccounts(); - -@Secured("ROLE_TELLER") -public Account post(Account account, double amount); -} +@EnableMethodSecurity(securedEnabled = true, prePostEnabled = false) ---- - .Kotlin [source,kotlin,role="secondary"] ---- -interface BankService { - @Secured("IS_AUTHENTICATED_ANONYMOUSLY") - fun readAccount(id: Long): Account - - @Secured("IS_AUTHENTICATED_ANONYMOUSLY") - fun findAccounts(): Array - - @Secured("ROLE_TELLER") - fun post(account: Account, amount: Double): Account -} +@EnableMethodSecurity(securedEnabled = true, prePostEnabled = false) ---- -==== - -Support for JSR-250 annotations can be enabled by using: -==== -[source,xml] +.Xml +[source,xml,role="secondary"] ---- - + ---- ==== -These are standards-based and allow simple role-based constraints to be applied, but they do not have the power Spring Security's native annotations. -To use the expression-based syntax, use: +=== Use a Custom `@Bean` instead of subclassing `DefaultMethodSecurityExpressionHandler` -==== -[source,xml] ----- - ----- -==== +As a performance optimization, a new method was introduced to `MethodSecurityExpressionHandler` that takes a `Supplier` instead of an `Authentication`. + +This allows Spring Security to defer the lookup of the `Authentication`, and is taken advantage of automatically when you use `@EnableMethodSecurity` instead of `@EnableGlobalMethodSecurity`. + +However, let's say that your code extends `DefaultMethodSecurityExpressionHandler` and overrides `createSecurityExpressionRoot(Authentication, MethodInvocation)` to return a custom `SecurityExpressionRoot` instance. +This will no longer work because the arrangement that `@EnableMethodSecurity` sets up calls `createEvaluationContext(Supplier, MethodInvocation)` instead. + +Happily, such a level of customization is often unnecessary. +Instead, you can create a custom bean with the authorization methods that you need. -The equivalent Java code is: +For example, let's say you are wanting a custom evaluation of `@PostAuthorize("hasAuthority('ADMIN')")`. +You can create a custom `@Bean` like this one: ==== .Java [source,java,role="primary"] ---- -public interface BankService { - -@PreAuthorize("isAnonymous()") -public Account readAccount(Long id); - -@PreAuthorize("isAnonymous()") -public Account[] findAccounts(); - -@PreAuthorize("hasAuthority('ROLE_TELLER')") -public Account post(Account account, double amount); +class MyAuthorizer { + boolean isAdmin(MethodSecurityExpressionOperations root) { + boolean decision = root.hasAuthority("ADMIN"); + // custom work ... + return decision; + } } ---- .Kotlin [source,kotlin,role="secondary"] ---- -interface BankService { - @PreAuthorize("isAnonymous()") - fun readAccount(id: Long): Account - - @PreAuthorize("isAnonymous()") - fun findAccounts(): Array - - @PreAuthorize("hasAuthority('ROLE_TELLER')") - fun post(account: Account, amount: Double): Account +class MyAuthorizer { + fun isAdmin(val root: MethodSecurityExpressionOperations): boolean { + val decision = root.hasAuthority("ADMIN"); + // custom work ... + return decision; + } } ---- ==== -Expression-based annotations are a good choice if you need to define simple rules that go beyond checking the role names against the user's list of authorities. +and then refer to it in the annotation like so: -[NOTE] -==== -The annotated methods will only be secured for instances which are defined as Spring beans (in the same application context in which method-security is enabled). -If you want to secure instances which are not created by Spring (using the `new` operator, for example) then you need to use AspectJ. ==== +.Java +[source,java,role="primary"] +---- +@PreAuthorize("@authz.isAdmin(#root)") +---- -[NOTE] -==== -You can enable more than one type of annotation in the same application, but only one type should be used for any interface or class as the behaviour will not be well-defined otherwise. -If two annotations are found which apply to a particular method, then only one of them will be applied. +.Kotlin +[source,kotlin,role="secondary"] +---- +@PreAuthorize("@authz.isAdmin(#root)") +---- ==== -[[ns-protect-pointcut]] -== Adding Security Pointcuts by using protect-pointcut +[[subclass-defaultmethodsecurityexpressionhandler]] +==== I'd still prefer to subclass `DefaultMethodSecurityExpressionHandler` -`protect-pointcut` is particularly powerful, as it lets you apply security to many beans with only a simple declaration. -Consider the following example: +If you must continue subclassing `DefaultMethodSecurityExpressionHandler`, you can still do so. +Instead, override the `createEvaluationContext(Supplier, MethodInvocation)` method like so: ==== -[source,xml] +.Java +[source,java,role="primary"] +---- +@Component +class MyExpressionHandler extends DefaultMethodSecurityExpressionHandler { + @Override + public EvaluationContext createEvaluationContext(Supplier authentication, MethodInvocation mi) { + StandardEvaluationContext context = (StandardEvaluationContext) super.createEvaluationContext(authentication, mi); + MethodSecurityExpressionOperations delegate = (MethodSecurityExpressionOperations) context.getRootObject().getValue(); + MySecurityExpressionRoot root = new MySecurityExpressionRoot(delegate); + context.setRootObject(root); + return context; + } +} +---- + +.Kotlin +[source,kotlin,role="secondary"] ---- - - - +@Component +class MyExpressionHandler: DefaultMethodSecurityExpressionHandler { + override fun createEvaluationContext(val authentication: Supplier, + val mi: MethodInvocation): EvaluationContext { + val context = super.createEvaluationContext(authentication, mi) as StandardEvaluationContext + val delegate = context.getRootObject().getValue() as MethodSecurityExpressionOperations + val root = MySecurityExpressionRoot(delegate) + context.setRootObject(root); + return context; + } +} ---- ==== -d. -This configuration protects all methods on beans declared in the application context whose classes are in the `com.mycompany` package and whose class names end in `Service`. -Only users with the `ROLE_USER` role can invoke these methods. -As with URL matching, the most specific matches must come first in the list of pointcuts, as the first matching expression is used. -Security annotations take precedence over pointcuts. +== Further Reading + +Now that you have secured your application's requests, please xref:servlet/authorization/authorize-http-requests.adoc[secure its requests] if you haven't already. +You can also read further on xref:servlet/test/index.adoc[testing your application] or on integrating Spring Security with other aspects of you application like xref:servlet/integrations/data.adoc[the data layer] or xref:servlet/integrations/observability.adoc[tracing and metrics]. diff --git a/docs/modules/ROOT/pages/servlet/authorization/secure-objects.adoc b/docs/modules/ROOT/pages/servlet/authorization/secure-objects.adoc deleted file mode 100644 index 84557b540c..0000000000 --- a/docs/modules/ROOT/pages/servlet/authorization/secure-objects.adoc +++ /dev/null @@ -1,143 +0,0 @@ - -[[secure-object-impls]] -= Secure Object Implementations - -This section covers how Spring Security handles Secure Object implementations. - -[[aop-alliance]] -== AOP Alliance (MethodInvocation) Security Interceptor -Prior to Spring Security 2.0, securing `MethodInvocation` instances needed a lot of boiler plate configuration. -Now the recommended approach for method security is to use xref:servlet/configuration/xml-namespace.adoc#ns-method-security[namespace configuration]. -This way, the method security infrastructure beans are configured automatically for you, so you need not know about the implementation classes. -We provide only a quick overview of the classes that are involved here. - -Method security is enforced by using a `MethodSecurityInterceptor`, which secures `MethodInvocation` instances. -Depending on the configuration approach, an interceptor may be specific to a single bean or shared between multiple beans. -The interceptor uses a `MethodSecurityMetadataSource` instance to obtain the configuration attributes that apply to a particular method invocation. -`MapBasedMethodSecurityMetadataSource` is used to store configuration attributes keyed by method names (which can be wildcarded) and will be used internally when the attributes are defined in the application context using the `` or `` elements. -Other implementations are used to handle annotation-based configuration. - -=== Explicit MethodSecurityInterceptor Configuration -You can configure a `MethodSecurityInterceptor` directly in your application context for use with one of Spring AOP's proxying mechanisms: - -==== -[source,xml] ----- - - - - - - - - - - - ----- -==== - -[[aspectj]] -== AspectJ (JoinPoint) Security Interceptor -The AspectJ security interceptor is very similar to the AOP Alliance security interceptor discussed in the previous section. -We discuss only the differences in this section. - -The AspectJ interceptor is named `AspectJSecurityInterceptor`. -Unlike the AOP Alliance security interceptor, which relies on the Spring application context to weave in the security interceptor through proxying, the `AspectJSecurityInterceptor` is woven in through the AspectJ compiler. -It would not be uncommon to use both types of security interceptors in the same application, with `AspectJSecurityInterceptor` being used for domain object instance security and the AOP Alliance `MethodSecurityInterceptor` being used for services layer security. - -We first consider how the `AspectJSecurityInterceptor` is configured in the Spring application context: - -==== -[source,xml] ----- - - - - - - - - - - - ----- -==== - -The two interceptors can share the same `securityMetadataSource`, as the `SecurityMetadataSource` works with `java.lang.reflect.Method` instances rather than an AOP library-specific class. -Your access decisions have access to the relevant AOP library-specific invocation (`MethodInvocation` or `JoinPoint`) and can consider a range of additional criteria (such as method arguments) when making access decisions. - -Next, you need to define an AspectJ `aspect`, as the following example shows: - -==== -[source,java] ----- - -package org.springframework.security.samples.aspectj; - -import org.springframework.security.access.intercept.aspectj.AspectJSecurityInterceptor; -import org.springframework.security.access.intercept.aspectj.AspectJCallback; -import org.springframework.beans.factory.InitializingBean; - -public aspect DomainObjectInstanceSecurityAspect implements InitializingBean { - - private AspectJSecurityInterceptor securityInterceptor; - - pointcut domainObjectInstanceExecution(): target(PersistableEntity) - && execution(public * *(..)) && !within(DomainObjectInstanceSecurityAspect); - - Object around(): domainObjectInstanceExecution() { - if (this.securityInterceptor == null) { - return proceed(); - } - - AspectJCallback callback = new AspectJCallback() { - public Object proceedWithObject() { - return proceed(); - } - }; - - return this.securityInterceptor.invoke(thisJoinPoint, callback); - } - - public AspectJSecurityInterceptor getSecurityInterceptor() { - return securityInterceptor; - } - - public void setSecurityInterceptor(AspectJSecurityInterceptor securityInterceptor) { - this.securityInterceptor = securityInterceptor; - } - - public void afterPropertiesSet() throws Exception { - if (this.securityInterceptor == null) - throw new IllegalArgumentException("securityInterceptor required"); - } - } -} ----- -==== - - -In the preceding example, the security interceptor is applied to every instance of `PersistableEntity`, which is an abstract class not shown (you can use any other class or `pointcut` expression you like). -For those curious, `AspectJCallback` is needed because the `proceed();` statement has special meaning only within an `around()` body. -The `AspectJSecurityInterceptor` calls this anonymous `AspectJCallback` class when it wants the target object to continue. - -You need to configure Spring to load the aspect and wire it with the `AspectJSecurityInterceptor`. -The following example shows a bean declaration that achieves this: - -==== -[source,xml] ----- - - - - ----- -==== - -Now you can create your beans from anywhere within your application, using whatever means you think fit (e.g. `new Person();`), and they have the security interceptor applied. diff --git a/docs/modules/ROOT/pages/servlet/oauth2/resource-server/index.adoc b/docs/modules/ROOT/pages/servlet/oauth2/resource-server/index.adoc index 52e991a0f4..3a3eae8ea7 100644 --- a/docs/modules/ROOT/pages/servlet/oauth2/resource-server/index.adoc +++ b/docs/modules/ROOT/pages/servlet/oauth2/resource-server/index.adoc @@ -27,7 +27,7 @@ The figure above builds off our xref:servlet/architecture.adoc#servlet-securityf image:{icondir}/number_1.png[] First, a user makes an unauthenticated request to the `/private` resource for which the user is not authorized. -image:{icondir}/number_2.png[] Spring Security's xref:servlet/authorization/authorize-requests.adoc#servlet-authorization-filtersecurityinterceptor[`FilterSecurityInterceptor`] indicates that the unauthenticated request is _Denied_ by throwing an `AccessDeniedException`. +image:{icondir}/number_2.png[] Spring Security's xref:servlet/authorization/authorize-http-requests.adoc[`AuthorizationFilter`] indicates that the unauthenticated request is _Denied_ by throwing an `AccessDeniedException`. image:{icondir}/number_3.png[] Since the user is not authenticated, xref:servlet/architecture.adoc#servlet-exceptiontranslationfilter[`ExceptionTranslationFilter`] initiates _Start Authentication_. The configured xref:servlet/authentication/architecture.adoc#servlet-authentication-authenticationentrypoint[`AuthenticationEntryPoint`] is an instance of {security-api-url}org/springframework/security/oauth2/server/resource/authentication/BearerTokenAuthenticationEntryPoint.html[`BearerTokenAuthenticationEntryPoint`], which sends a `WWW-Authenticate` header. diff --git a/docs/modules/ROOT/pages/servlet/saml2/login/overview.adoc b/docs/modules/ROOT/pages/servlet/saml2/login/overview.adoc index 2551206a09..b7a83a0daa 100644 --- a/docs/modules/ROOT/pages/servlet/saml2/login/overview.adoc +++ b/docs/modules/ROOT/pages/servlet/saml2/login/overview.adoc @@ -16,7 +16,7 @@ The figure above builds off our xref:servlet/architecture.adoc#servlet-securityf image:{icondir}/number_1.png[] First, a user makes an unauthenticated request to the `/private` resource, for which it is not authorized. -image:{icondir}/number_2.png[] Spring Security's xref:servlet/authorization/authorize-requests.adoc#servlet-authorization-filtersecurityinterceptor[`FilterSecurityInterceptor`] indicates that the unauthenticated request is _Denied_ by throwing an `AccessDeniedException`. +image:{icondir}/number_2.png[] Spring Security's xref:servlet/authorization/authorize-http-requests.adoc[`AuthorizationFilter`] indicates that the unauthenticated request is _Denied_ by throwing an `AccessDeniedException`. image:{icondir}/number_3.png[] Since the user lacks authorization, the xref:servlet/architecture.adoc#servlet-exceptiontranslationfilter[`ExceptionTranslationFilter`] initiates _Start Authentication_. The configured xref:servlet/authentication/architecture.adoc#servlet-authentication-authenticationentrypoint[`AuthenticationEntryPoint`] is an instance of {security-api-url}org/springframework/security/web/authentication/LoginUrlAuthenticationEntryPoint.html[`LoginUrlAuthenticationEntryPoint`], which redirects to <` generating endpoint>>, `Saml2WebSsoAuthenticationRequestFilter`.