Felhasznált technológiák: Spring Security 3.2.5, Jetty 9.1.0.v20131115
Vannak olyan esetek, mikor ugyan Spring Security-t szeretnénk használni, azonban autentikációra meghagynánk a webkonténer, vagy az alkalmazásszerver mechanizmusát. Ilyen eset lehetséges, mikor alkalmazásszerverben van beállítva az X.509 tanúsítványok kezelése, vagy esetleg az SSO-val való integráció.
Ebben az esetben az alkalmazásszerver végzi a bejelentkeztetést, esetleg még a jogosultságok kiosztását is, de a többit a Spring Security végzi. Az alkalmazásszerver a bejelentkeztetett felhasználót és jogosultságait a szabványos módon adja át, lekérdezni a Servlet API HttpServletRequest példányának getUserPrincipal() és isUserInRole(java.lang.String role) metódusaival lehet. A Spring Security-t tehát arra kell rábeszélni, hogy a megfelelő esetekben ide delegálja a hívásait.
A Spring Security használata azért lehet hasznos ebben az esetben is, mert a Servlet API-hoz képest rengeteg plusz funkciót ad, mint pl. URL-ek védelme, amihez a jogosultságokat bonyolult kifejezésekkel adhatjuk meg. Vagy pl. az annotáció alapú deklaratív jogosultságkezelés, stb. A Spring Security-ről bővebben egy előző posztomban olvashatsz, melyet ismét frissítettem, hogy a legfrissebb verziókat tartalmazza.
Jelenlegi poszthoz egy példaprogram is letölthető a GitHub-ról. Az mvn jetty:run paranccsal indítható. Bejelentkezni az admin1/admin1 és a user1/user1 felhasználónév jelszó párosokkal lehetséges. és Egy Jetty beépített webkonténert tartalmaz, melybe fel vannak véve a felhasználók, és a hozzá tartozó szerepkörök. Első körben a Jetty Maven pluginnak kell megmondani, hogy hol található a Jetty-hez tartozó konfigurációs állomány.
Amennyiben ez megvan, az src/main/webapp/WEB-INF/jetty.xml konfigurációs állományban kell megadni, hogy mely állomány tartalmazza a felhasználókat és szerepköröket.
A src/main/webapp/WEB-INF/jetty-realm.properties egy elég egyszerű állomány, elöl a felhasználónév, majd a jelszó (plain-text-ben), majd a szerepkör. Teszteléshez tökéletes.
Majd megadjuk a web.xml-ben, hogy Basic autentikációt használjon. Ilyenkor a böngésző feldob egy ablakot, és az autentikációs információk a HTTP kérés fejlécében utaznak, plain textben. Ez már szabványos Servlet API megoldás.
Ezután már csak a Spring Security-t konfiguráltam be az applicationContext-security.xml állományban, hogy a web konténertől vegye át a felhasználót és a hozzá tartozó szerepköröket. Nézzük az ehhez tartozó konfigurációt.
Ez talán már igényelhet némi magyarázatot. Az entryPoint bean mondja meg, hogy a konténerre van bízva az autentikáció. Az authenticationProvider mondja meg, hogy honnan kell a felhasználót feltölteni. Itt egy PreAuthenticatedAuthenticationProvider példányt használunk, ami azt mondja, hogy az autentikációt már elvégezte a konténer, és ennek eredménye alapján tölthetünk be saját User példányt. Ezt a saját JpaAuthenticationUserDetailsService példányunk teszi, adatbázisból a felhasználónév alapján JPA technológiával. A preAuthFilter bean a web.xml-ben talált szerepköröket mappeli át Spring Security-sra, nagybetűsít, és alapértelmezetten hozzáfűzi a ROLE_ prefixet. tehát az admin és a user szerepkörből csinál ROLE_ADMIN és ROLE_USER szerepköröket, vagy ahogy a Spring Security hívja, granted authority-ket.
A saját JpaAuthenticationUserDetailsService lényeg része a következőképp néz ki.
A paraméterként kapott token már tartalmazza az alkalmazásszerver által meghatározott felhasználónév és szerepkör információkat, ez alapján betöltjük adatbázisból a felhasználót, és beállítjuk a szintén megkapott szerepköröket.