Bevezetés az Apache Shiro-ba

1. Áttekintés

Ebben a cikkben az Apache Shiro-t, egy sokoldalú Java biztonsági keretet fogjuk megvizsgálni.

A keretrendszer nagyon testreszabható és moduláris, mivel hitelesítést, engedélyezést, titkosítást és munkamenet-kezelést kínál.

2. Függőség

Az Apache Shiro-nak sok modulja van. Ebben az oktatóanyagban azonban a shiro-mag csak műtárgy.

Tegyük hozzá a sajátunkhoz pom.xml:

 org.apache.shiro shiro-core 1.4.0 

Az Apache Shiro modulok legújabb verziója megtalálható a Maven Central oldalon.

3. A Security Manager beállítása

A SecurityManager az Apache Shiro keretrendszerének középső darabja. Az alkalmazásoknak általában egyetlen példánya fut.

Ebben az oktatóanyagban egy asztali környezetben tárjuk fel a keretrendszert. A keretrendszer konfigurálásához létre kell hoznunk a shiro.ini fájl az erőforrás mappában a következő tartalommal:

[felhasználók] felhasználó = jelszó, admin felhasználó2 = jelszó2, szerkesztő felhasználó3 = jelszó3, szerző [szerepek] admin = * szerkesztő = cikkek: * szerző = cikkek: ír, cikkek: mentés

A [felhasználók] szakasza shiro.ini A config fájl meghatározza azokat a felhasználói hitelesítő adatokat, amelyeket a SecurityManager. A formátum: orincipal (felhasználónév) = jelszó, role1, role2,…, role.

A szerepköröket és a hozzájuk tartozó engedélyeket a [szerepek] szakasz. A admin A szerepkör engedélyt és hozzáférést kap az alkalmazás minden részéhez. Ezt a helyettesítő jelzi (*) szimbólum.

A szerkesztő szerepkör minden jogosultsággal társul cikkeket amíg a szerző szerep csak összeállít és mentés egy cikket.

A SecurityManager a konfigurálására szolgál SecurityUtils osztály. Tól SecurityUtils megszerezhetjük a rendszerrel interakcióban lévő aktuális felhasználót, és hitelesítési és hitelesítési műveleteket hajthatunk végre.

Használjuk a IniRealm hogy betöltsük a felhasználói és szerepdefinícióinkat a shiro.ini fájlt, majd használja a DefaultSecurityManager tárgy:

IniRealm iniRealm = új IniRealm ("osztályút: shiro.ini"); SecurityManager securityManager = új DefaultSecurityManager (iniRealm); SecurityUtils.setSecurityManager (securityManager); Subject currentUser = SecurityUtils.getSubject ();

Most, hogy van egy SecurityManager hogy tisztában van a felhasználói hitelesítő adatokkal és a shiro.ini fájlt, folytassuk a felhasználó hitelesítésével és hitelesítésével.

4. Hitelesítés

Apache Shiro terminológiájában a Tantárgy bármely olyan entitás, amely kölcsönhatásba lép a rendszerrel. Lehet emberi, szkript vagy REST kliens.

Hívás SecurityUtils.getSubject () az aktuális példányát adja vissza Tantárgy, ez a jelenlegi felhasználó.

Most, hogy megvan a jelenlegi felhasználó Objektum, hitelesítést hajthatunk végre a mellékelt hitelesítő adatokon:

if (! currentUser.isAuthenticated ()) {UsernamePasswordToken token = new UsernamePasswordToken ("felhasználó", "jelszó"); token.setRememberMe (true); próbáld ki a {currentUser.login (token); } catch (UnknownAccountException uae) {log.error ("Felhasználónév nem található!", uae); } catch (IncorrectCredentialsException ice) {log.error ("Érvénytelen hitelesítő adatok!", jég); } catch (LockedAccountException lae) {log.error ("A fiókja zárolva van!", lae); } catch (AuthenticationException ae) {log.error ("Váratlan hiba!", ae); }}

Először ellenőrizzük, hogy az aktuális felhasználót még nem hitelesítették-e. Ezután létrehozunk egy hitelesítési tokent a felhasználó megbízójával (felhasználónév) és hitelesítő adatok (Jelszó).

Ezután megpróbálunk bejelentkezni a tokennel. Ha a megadott hitelesítő adatok helyesek, akkor minden rendben kell lennie.

Különböző esetekre különböző kivételek vonatkoznak. Lehetséges olyan egyedi kivétel is, amely jobban megfelel az alkalmazás követelményeinek. Ezt úgy tehetjük meg, hogy a AccountException osztály.

5. Engedélyezés

A hitelesítés megpróbálja érvényesíteni a felhasználó személyazonosságát, míg az engedélyezés a rendszer bizonyos erőforrásaihoz való hozzáférést próbálja ellenőrizni.

Emlékezzünk arra, hogy egy vagy több szerepet rendelünk minden felhasználóhoz, amelyet a shiro.ini fájl. Ezenkívül a szerepkörök részben minden engedélyhez különböző engedélyeket vagy hozzáférési szinteket határozunk meg.

Most nézzük meg, hogyan használhatjuk ezt alkalmazásunkban a felhasználói hozzáférés-ellenőrzés kikényszerítésére.

Ban,-ben shiro.ini fájlt, az admin rendszernek teljes hozzáférést biztosítunk a rendszer minden részéhez.

A szerkesztő teljes hozzáféréssel rendelkezik minden egyes erőforráshoz / művelethez cikkeket, és a szerző csak a komponálásra és a mentésre korlátozódik cikkeket csak.

Üdvözöljük a jelenlegi felhasználót szerep alapján:

if (currentUser.hasRole ("admin")) {log.info ("Welcome Admin"); } else if (currentUser.hasRole ("szerkesztő")) {log.info ("Üdvözlünk, szerkesztő!"); } else if (currentUser.hasRole ("szerző")) {log.info ("Welcome, Author"); } else {log.info ("Üdvözöllek, Vendég"); }

Most nézzük meg, hogy a jelenlegi felhasználó mit tehet a rendszerben:

if (currentUser.isPermitted ("articles: compose")) {log.info ("Készíthet cikket"); } else {log.info ("Nem írhatsz cikket!"); } if (currentUser.isPermitted ("cikkek: mentés")) {log.info ("Menthet cikkeket"); } else {log.info ("Nem lehet cikkeket menteni"); } if (currentUser.isPermitted ("cikkek: közzététel")) {log.info ("Cikkeket közzétehet"); } else {log.info ("Nem tehet közzé cikkeket"); }

6. A tartomány beállítása

Valódi alkalmazásokban szükségünk lesz arra, hogy a felhasználói hitelesítő adatokat adatbázisból, nem pedig az adatbázisból szerezzük be shiro.ini fájl. Itt jelenik meg a Realm koncepciója.

Apache Shiro terminológiájában a Realm egy DAO, amely a hitelesítéshez és az engedélyezéshez szükséges felhasználói hitelesítő adatok tárolására mutat.

A birodalom létrehozásához csak a Birodalom felület. Ez unalmas lehet; a keretrendszer azonban alapértelmezett megvalósításokkal érkezik, amelyekből alosztályokat adhatunk. Az egyik ilyen megvalósítás az JdbcRealm.

Létrehozunk egy kiterjedt, egyedi birodalmi megvalósítást JdbcRealm osztály és felülbírálja a következő módszereket: doGetAuthenticationInfo (), doGetAuthorizationInfo (), getRoleNamesForUser () és getPermissions ().

Hozzunk létre egy birodalmat a JdbcRealm osztály:

nyilvános osztály A MyCustomRealm kiterjeszti a JdbcRealm {// ...}

Az egyszerűség kedvéért használjuk java.util.Térkép az adatbázis szimulálásához:

privát térkép hitelesítő adatok = új HashMap (); privát térkép szerepek = new HashMap (); privát térkép perm = új HashMap (); {credentials.put ("felhasználó", "jelszó"); credentials.put ("felhasználó2", "jelszó2"); credentials.put ("user3", "password3"); szerepek.put ("felhasználó", új HashSet (tömbök.lista ("admin"))); szerepek.put ("user2", új HashSet (Arrays.asList ("szerkesztő"))); szerepek.put ("user3", új HashSet (tömbök.Lista ("szerző"))); perm.put ("admin", új HashSet (Arrays.asList ("*"))); perm.put ("editor", új HashSet (Arrays.asList ("articles: *"))); perm.put ("author", új HashSet (Arrays.asList ("articles: compose", "articles: save"))); }

Folytassuk és felülírjuk a doGetAuthenticationInfo ():

védett AuthenticationInfo doGetAuthenticationInfo (AuthenticationToken token) dobja az AuthenticationException {UsernamePasswordToken uToken = (UsernamePasswordToken) tokent; if (uToken.getUsername () == null || uToken.getUsername (). isEmpty () ||! credentials.containsKey (uToken.getUsername ())) {dobjon új UnknownAccountException ("felhasználónév nem található!"); } return new SimpleAuthenticationInfo (uToken.getUsername (), credentials.get (uToken.getUsername ()), getName ()); }

Először leadtuk a AuthenticationToken feltéve, hogy FelhasználónévPasswordToken. Tól uToken, kivonjuk a felhasználónév (uToken.getUsername ()), és használja a felhasználói hitelesítő adatok (jelszó) lekérésére az adatbázisból.

Ha nincs találat - dobunk egy UnknownAccountException, különben a hitelesítő adatokat és a felhasználónéveket használjuk a SimpleAuthenticatioInfo a metódusból visszaadott objektum.

Ha a felhasználói hitelesítési adatok sóval vannak kivágva, akkor vissza kell adnunk a SimpleAuthenticationInfo a hozzá tartozó sóval:

adja vissza az új SimpleAuthenticationInfo (uToken.getUsername (), credentials.get (uToken.getUsername ()), ByteSource.Util.bytes ("só", getName ());

Felül kell írnunk a doGetAuthorizationInfo (), továbbá getRoleNamesForUser () és getPermissions ().

Végül csatlakoztassuk az egyéni tartományt a securityManager. Csak annyit kell tennünk, hogy kicseréljük a IniRealm fenti tartományunkkal, és adjuk át a DefaultSecurityManagerKivitelezője:

Birodalom birodalma = new MyCustomRealm (); SecurityManager securityManager = új DefaultSecurityManager (tartomány);

A kód minden más része megegyezik az előzőekkel. Ez az, amire szükségünk van a securityManager egyedi birodalommal rendesen.

Most az a kérdés - hogyan egyezik a keretrendszer a hitelesítő adatokkal?

Alapértelmezés szerint a JdbcRealm használja a SimpleCredentialsMatcher, amely pusztán ellenőrzi az egyenlőséget azáltal, hogy összehasonlítja a AuthenticationToken és a AuthenticationInfo.

Ha elválasztjuk a jelszavakat, akkor tájékoztatnunk kell a keretrendszert az a használatáról HashedCredentialsMatcher helyette. A kivonatolt jelszavakkal rendelkező tartományok INI konfigurációi itt találhatók.

7. Kijelentkezés

Most, hogy hitelesítettük a felhasználót, itt az ideje a kijelentkezés végrehajtásának. Ez egyszerűen egyetlen módszer meghívásával történik - ami érvényteleníti a felhasználói munkamenetet és kijelenti a felhasználót:

currentUser.logout ();

8. Üléskezelés

A keretrendszer természetesen a munkamenet-kezelő rendszerével jár. Ha webes környezetben használják, akkor alapértelmezés szerint a HttpSession végrehajtás.

Önálló alkalmazáshoz a vállalati munkamenet-kezelő rendszert használja. Előnye, hogy asztali környezetben is használhat munkamenetobjektumot, mint egy tipikus webes környezetben.

Nézzünk meg egy gyors példát, és lépjünk kapcsolatba az aktuális felhasználó munkamenetével:

Munkamenet = currentUser.getSession (); session.setAttribute ("kulcs", "érték"); Karakterlánc értéke = (Karakterlánc) session.getAttribute ("kulcs"); if (érték.egyenlő ("érték")) {log.info ("A helyes értéket kapta meg! [" + érték + "]"); }

9. Shiro egy tavaszi webalkalmazáshoz

Eddig felvázoltuk az Apache Shiro alapstruktúráját, és asztali környezetben valósítottuk meg. Folytassuk úgy, hogy integráljuk a keretrendszert egy Spring Boot alkalmazásba.

Ne feledje, hogy itt a fő hangsúly a Shiro, nem pedig a Spring alkalmazás - ezt csak egy egyszerű példaalkalmazás működtetésére fogjuk felhasználni.

9.1. Függőségek

Először hozzá kell adnunk a Spring Boot szülői függőséget a sajátunkhoz pom.xml:

 org.springframework.boot spring-boot-starter-parent 2.2.6.KÖZLEMÉNY 

Ezután hozzá kell adnunk a következő függőségeket ugyanahhoz pom.xml fájl:

 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-freemarker org.apache.shiro shiro-spring-boot-web-starter $ {apache-shiro-core-version} 

9.2. Konfiguráció

A shiro-spring-boot-web-starter függőség a mi pom.xml alapértelmezés szerint konfigurálja az Apache Shiro alkalmazás egyes szolgáltatásait, például a SecurityManager.

Azonban még mindig konfigurálnunk kell a Birodalom és a Shiro biztonsági szűrők. Ugyanazt a fent meghatározott egyéni tartományt fogjuk használni.

Tehát a fő osztályban, ahol a Spring Boot alkalmazás fut, tegyük hozzá a következőket Bab definíciók:

@Bean public Realm birodalom () {return new MyCustomRealm (); } @Bean public ShiroFilterChainDefinition shiroFilterChainDefinition () {DefaultShiroFilterChainDefinition filter = new DefaultShiroFilterChainDefinition (); filter.addPathDefinition ("/ biztonságos", "authc"); filter.addPathDefinition ("/ **", "anon"); visszatérő szűrő; }

Ban,-ben ShiroFilterChainDefinition, alkalmaztuk a hiteles szűrni / biztonságos utat és alkalmazta a mindjárt szűrni más utakon az Ant minta segítségével.

Mindkét hiteles és mindjárt szűrők alapértelmezés szerint jönnek a webes alkalmazásokhoz. További alapértelmezett szűrők itt találhatók.

Ha nem definiáltuk a Birodalom bab, ShiroAutoConfiguration alapértelmezés szerint egy IniRealm megvalósítás, amely várhatóan megtalálja a shiro.ini fájl src / main / resources vagy src / main / resources / META-INF.

Ha nem definiáljuk a ShiroFilterChainDefinition Bean, a keretrendszer biztosítja az összes utat, és a bejelentkezési URL-t állítja be login.jsp.

Megváltoztathatjuk ezt az alapértelmezett bejelentkezési URL-t és egyéb alapértelmezéseket, ha a következő bejegyzéseket hozzáadjuk a webhelyünkhöz alkalmazás.tulajdonságok:

shiro.loginUrl = / login shiro.successUrl = / biztonságos shiro.unauthorizedUrl = / login

Most, hogy a hiteles szűrőt alkalmaztuk / biztonságos, az adott útvonalra vonatkozó összes kérelemhez űrlap hitelesítésre van szükség.

9.3. Hitelesítés és engedélyezés

Hozzunk létre egy ShiroSpringController a következő útleképezésekkel: /index, / login, / logout és / biztonságos.

A Belépés() módszer az, ahol valós felhasználói hitelesítést valósítunk meg a fent leírtak szerint. Ha a hitelesítés sikeres, a felhasználót átirányítják a biztonságos oldalra:

Subject subject = SecurityUtils.getSubject (); if (! subject.isAuthenticated ()) {felhasználónévPasswordToken token = új felhasználónévPasswordToken (cred.getUsername (), cred.getPassword (), cred.isRememberMe ()); próbáld ki a {subject.login (token); } catch (AuthenticationException ae) {ae.printStackTrace (); attr.addFlashAttribute ("hiba", "Érvénytelen hitelesítő adatok"); return "redirect: / login"; }} return "átirányítás: / biztonságos";

És most a biztonságos () végrehajtása, az jelenlegi felhasználó a SecurityUtils.getSubject (). A felhasználó szerepét és engedélyeit továbbítják a biztonságos oldalra, valamint a felhasználó megbízóját:

Subject currentUser = SecurityUtils.getSubject (); Karakterlánc = "", engedély = ""; if (currentUser.hasRole ("admin")) {role = role + "Ön rendszergazda"; } else if (currentUser.hasRole ("editor")) {role = role + "Szerkesztő vagy"; } else if (currentUser.hasRole ("szerző")) {role = role + "Ön szerző vagy"; } if (currentUser.isPermitted ("articles: compose")) {engedély = engedély + "Készíthet cikket"; } else {engedély = engedély + "Ön nem írhat cikket !,"; } if (currentUser.isPermitted ("cikkek: mentés")) {engedély = engedély + "Menthet cikkeket,"; } else {engedély = engedély + "\ nA cikkeket nem lehet menteni,"; } if (currentUser.isPermitted ("cikkek: közzététel")) {engedély = engedély + "\ nCikkeket közzétehet"; } else {engedély = engedély + "\ nCikkeket nem tehet közzé"; } modelMap.addAttribute ("felhasználónév", currentUser.getPrincipal ()); modelMap.addAttribute ("engedély", engedély); modelMap.addAttribute ("szerep", szerep); visszatér "biztonságos";

És készen vagyunk. Így integrálhatjuk az Apache Shiro-t egy Spring Boot alkalmazásba.

Vegye figyelembe azt is, hogy a keretrendszer további megjegyzéseket kínál, amelyek felhasználhatók a szűrőlánc-definíciók mellett az alkalmazásunk biztonsága érdekében.

10. JEE integráció

Az Apache Shiro integrálása a JEE alkalmazásba csak a web.xml fájl. Szokás szerint a konfiguráció elvárja shiro.ini hogy az osztályúton legyen. A részletes konfigurációs példa itt érhető el. A JSP címkék itt találhatók.

11. Következtetés

Ebben az oktatóanyagban megvizsgáltuk az Apache Shiro hitelesítési és engedélyezési mechanizmusait. Arra is összpontosítottunk, hogy miként definiálhatunk egy egyedi birodalmat és csatlakoztathatjuk azt a SecurityManager.

Mint mindig, a teljes forráskód elérhető a GitHubon.


$config[zx-auto] not found$config[zx-overlay] not found