Architektura rámce Acegi Security™ je poměrně komplexní a poskytuje tak mnoho možností, jak přizpůsobit chování rámce vývojářovým potřebám. Představíme si její základní prvky.
Klíčovým bodem celé architektury je samozřejmě reprezentace
cíle, ke kterému chceme řídit přístup. Pro reprezentaci
vyvolání metody objektu servisní vrstvy je
použita třída
org.aopalliance.intercept.MethodInvocation
standardu AOP Alliance™ (viz „Pokyny (advices)“) a pro řízení přístupu je využito standardní
AOP funkcionality rámce
Spring™, popsané v předchozí
kapitole.
Druhým typem chráněného cíle je webový
zdroj reprezentovaný třídou
org.acegisecurity.intercept.web.FilterInvocation.
Objekt této třídy obsahuje aktuální HTTP požadavek,
tedy objekt třídy
javax.servlet.http.HttpServletRequest, aktuální
HTTP odpověď, tedy objekt třídy
javax.servlet.http.HttpServletResponse a seznam
aplikovaných filtrů rámcem Acegi
Security™ (viz „Ochrana přístupu k webovým zdrojům“).
Pro řízení přístupu k doménovým objektům se
využívá služeb sofistikovaného AOP rámce
AspectJ™ a reprezentací chráněného doménového objektu je AspectJ
třída org.aspectj.lang.JoinPoint.
Každý chráněný cíl je definován prostřednictvím konfiguračního
XML souboru aplikačního kontextu rámce
Spring™ a pro každý chráněný cíl jsou
definovány přístupové atributy. Každý přístupový atribut je reprezentován instancí
rozhraní org.acegisecurity.ConfigAttribute, při
čemž při defaultní implementaci jde v podstatě o pouhé zapouzdření
řetězce. K danému chráněnému cíli má tedy přístup pouze uživatel
(reprezentovaný objektem Authentication - viz
následující oddíl), jemuž byly přiřazeny přístupové atributy
definované pro tento cíl.
Stav autentizace aktuálního uživatele je
reprezentován rozhraním
org.acegisecurity.Authentication. Jde v
podstatě o objekt, jenž obsahuje předloženou identitu
uživatele (většinou uživatelské jméno), která je označována jako
principál (principal), předložený důkaz
identity (většinou heslo) a informaci, zda tyto údaje již byly
ověřeny. Byly-li již ověřeny, pak objekt
Authentication obsahuje i této identitě
systémem přidělená oprávnění (přístupové atributy).
Objekt Authentication musí být k
dispozici při každém přístupu k chráněným zdrojům, ale zároveň není
vhodné, aby tento objekt byl předáván z metody do metody
prostřednictvím parametru metody. Z toho důvodu je objekt
Authentication při svém vytvoření uložen do
objektu s rozhraním
org.acegisecurity.context.SecurityContext a ten
pak do objektu
org.acegisecurity.context.SecurityContextHolder,
který zajistí svázání objektu Authentication s
aktuálním vláknem programu prostřednictvím funkcionality třídy
java.lang.ThreadLocal. Odtud je pak kdykoliv
dostupný pomocí statického volání
SecurityContextHolder.getContext().getAuthentication().
Při každém přístupu k chráněnému cíli je vyvolána metoda
authenticate objektu rozhraní
org.acegisecurity.AuthenticationManager. Této
metodě je předán objekt Authentication, získaný
z objektu SecurityContextHolder. Metoda v databázi,
LDAP záznamech či jinde ověří správnost identity a
důkazu a jsou-li správné, získá z databáze, LDAP
záznamů či odjinud všechna bezpečnostní oprávnění (přístupové
atributy) pro danou identitu. Tato oprávnění pak vloží do předloženého
objektu Authentication. Staronový objekt
Authentication je opět uložen do objektu
SecurityContextHolder. Nejsou-li identita a
důkaz správné, je vyhozena výjimka.
Je-li uživatel úspěšně autentizován, dochází k ověření jeho
oprávnění přistoupit k danému chráněnému cíli. To má na starost objekt
rozhraní
org.acegisecurity.AccessDecisionManager, jehož
metodě decide je předložena reprezentace
chráněného cíle, ke kterému chceme přistoupit, objekt
Authentication, jenž obsahuje přístupové
atributy aktuálního uživatele, a seznam přístupových atributů
definovaných pro daný chráněný cíl. Rozhodne-li
AccessDecisionManager kladně, chráněný cíl je
uživateli zpřístupněn.
V přiložené vzorové aplikaci představuje třída
cz.morosystems.sportportal.spring.FirstWinAccessDecisionManager
okomentovaný příklad implementace rozhraní
AccessDecistionManager.