Was ist Shiro
Shiro ist ein Open -Source -Berechtigungsframework für die Java -Plattform zur Authentifizierung und Zugriffsberechtigung. Insbesondere wird die Unterstützung für die folgenden Elemente erfüllt:
F: Unterstützung für die Gruppe?
A: Shiro unterstützt standardmäßig keine Berechtigungen für Gruppen.
F: Kann es den Bedürfnissen der Rollenzuweisung für Gruppen erfüllen?
A: Die Erweiterung von Realm kann die Zuweisung von Rollen an Gruppen unterstützen, die tatsächlich Berechtigungen an alle Benutzer unter der Gruppe zuweisen sollen.
F: Unterstützung für Datenberechtigungen? In einem Geschäftssystem definiert?
A: Shiro implementiert nur die Steuerung über Betriebsberechtigungen, mit denen die Front-End-Steuerelemente ausgeblendet oder angezeigt werden und die Berechtigungen der Ressourcen zu überprüfen. Datenberechtigungen sind eng mit den spezifischen Geschäftsbedürfnissen verbunden, und Shiro selbst kann die Datenberechtigungen nicht kontrollieren.
F: Dynamische Berechtigungszuweisung?
A: Erweitern Sie org.apache.shiro.realm.realm, um die dynamische Berechtigungszuweisung zu unterstützen.
F: Integrieren Sie sich in den Frühling?
A: Es kann die Integration in den Frühling unterstützen, und Shiro unterstützt auch JSP -Tags.
Im vorherigen Blog haben wir über Shiros zwei größte Funktionen, Authentifizierung und Autorisierung gesprochen. Single Sign-On ist auch Teil der Authentifizierung. Standardmäßig hat Shiro die Integration mit CAS für uns implementiert, und es wird in Ordnung sein, wenn wir einige integrierte Konfigurationen hinzufügen.
1. Fügen Sie Shiro-Cas-Paket hinzu
<!-Shiro integriert CAS-Single-Punkte-> <De vor Ort> <GroupId> org.apache.shiro </Groupid> <artifactid> shiro-cas </artifactid> <version> 1.2.4 </Version> </abhängig>
2. Fügen Sie eine einzelne Sign-On-Konfiguration hinzu
Hier habe ich alle Konfigurationen als einfache Referenz gepostet, und die Konfiguration wurden detaillierte Anweisungen hinzugefügt.
Paket com.chhliu.springboot.shiro.config; import Java.util.linkedhashMap; import Java.util.map; import Javax.servlet.filter; import org.apache.shiro.cache.ehcache.ehcacheManager; import org.apache.shiro.cas.casfilter; import org.apache.shiro.cas.cassubjectFactory; import org.apache.shiro.spring.lifecycleBeanPostProcessor; import org.apache.shiro.spring.security.interceptor.authorizationAttributesourceadvisor; import org.apache.shiro.spring.web.shirofilterfactoryBean; import org.apache.shiro.web.mgt.defaultwebSecurityManager; import org.jasig.cas.client.session.singlesignoutFilter; import org.jasig.cas.client.session.singlesignouthttpSessionListener; import org.springframework.aop.framework.autoproxy.DefaultAdvisorautoproxyCreator; import org.springframework.boot.web.servlet.filterregistrationBean; import org.springframework.boot.web.servlet.servletListenerregistrationBean; import org.springframework.context.annotation.bean; import org.springframework.context.annotation.configuration; import org.springframework.context.annotation.dependson; import org.springframework.core.Ordered; import org.springframework.core.annotation.order; import org.springframework.web.filter.delegatingFilterProxy; /*** Shiro -Konfiguration** Apache Shiro Core wird über den Filter implementiert, genau wie SpringMVC DispachServlet verwendet, um es zu steuern. Da wir * Filter verwenden, können wir allgemein vermuten, dass die Filterung und Berechtigungsüberprüfung durch URL -Regeln durchgeführt wird, sodass wir eine Reihe von Regeln und Zugriffsrechten über URLs definieren müssen. * * @Author Chhliu */@Configuration öffentliche Klasse Shiroconfiguration {// Cas Serveradresse öffentliche statische endgültige Zeichenfolge casserverurlprefix = "http://127.0.0.1"; // CAS -Anmeldeseite der Adresse öffentlich statische endgültige Zeichenfolge casloginurl = casserverurlprefix + "/login"; // CAS -Abmeldepage -Adresse öffentliche statische endgültige String -String -Caslogouturl = casserverurlprefix + "/logout"; // die aktuelle Serviceadresse, die das Projekt an die Außenwelt öffentliche statische Schluss -String -ShiroServerurlprefix = "http://127.0.1.28:8080" zur Verfügung gestellt hat; // Casfilter urlpattern public statische endgültige Zeichenfolge Casfilterurlpattern = "/index"; // Anmeldadresse public static Final String loginurl = Casloginurl + "? Service =" + shiroServerurlprefix + casfilterurlpattern; // Logout-Adresse (Casserver ermöglicht die Service-Sprungfunktion, und Sie müssen Cas.logout.Followserviceedirects = true in den WebApps/cas/web-inf/cas.Properties-Datei aktivieren. // erfolgreiche Adresse anmelden // Public static Final String loginuccessurl = "/index"; // Berechtigungsauthentifizierung fehlgeschlagener Sprungadresse öffentliche statische endgültige Zeichenfolge unauthorizedurl = "/Error/403.html"; / ** *Instanctiate SecurityManager, diese Klasse ist die Kernklasse von Shiro */ @return */ @Bean public defaultWebSecurityManager SecurityManager () {defaultWebSecurityManager SecurityManager = new DefaultWebSecurityManager (); SecurityManager.SetRealm (MyShirocasrealm ()); // <!-Benutzerautorisierung/Authentifizierungsinformationen Cache unter Verwendung von EHCACHE Cache-> SecurityManager.setCacheManager (GetehCacheManager ()); // Subjekt angeben. Wenn Sie die Funktion von CAS REMB ME ME implementieren möchten, müssen Sie das folgende CassubjectFactory verwenden und auf den SecurityManager -Subjektfaktor -SecurityManager.SetSubjectFactory (New CassubjectFactory ()) festlegen. Sicherheitsmanager zurückgeben; } / *** cache konfigurieren* @return* / @bean public ehCacheManager GetEHCACHEMANAGER () {EHCACHEMANATER EM = new EhCacheManager (); em.setCacheManAGerConFigFile ("ClassPath: config/eHcache-shiro.xml"); EM zurückgeben; } /*** Konfigurieren Sie Realm. Da wir CasRealm verwenden, wurde die einzelne Sign-On-Funktion integriert * @param cacheManager * @return */ @bean public myshirorealm myshirocasrealm () {myshirorealm Realm = new MyShirorealm (); // CAS Login Server -Adresse Präfix Real.setCasServerUrlprefix (Shiroconfiguration.CasserverurlPreFix); // Client -Rückrufadresse, Sprungadresse nach dem Anmeldung ist erfolgreich (eine eigene Serviceadresse). // Die Standardrolle nach dem Anmeldung ist erfolgreich, hier standardmäßig die Benutzerrolle Real.setDefaultroles ("Benutzer"); RECH RECHM; } /** * Register single sign-out listener * @return */ @SuppressWarnings({ "rawtypes", "unchecked" }) @Bean @Order(Ordered.HIGHEST_PRECEDENCE)// The priority is higher than Cas public ServletListenerRegistrationBean<?> singleSignOutHttpSessionListener(){ ServletListenerRegistrationBean bean = new ServletListenerregistrationBean (); bean.setListener (neuer SingleSignouthttpSessionListener ()); bean.setEnabled (true); Rückzahlung; } / ** * Registrieren Sie einzelne Anmeldefilter * @return * / @Bean public FilterregistrationBean SingleSignoutFilter () {FilterregistrationBean Bean = new FilterregistrationBean (); Bean.SetName ("SingleSignoutFilter"); Bean.SetFilter (neuer SingleSignoutFilter ()); bean.addurlpatterns ("/*"); bean.setEnabled (true); Rückzahlung; } / ** * Register delegatingFilterProxy (shiro) * / @bean public filterregistrationBean delegatingFilterProxy () {FilterregistrationBean Filterregistration = new filterregistrationBean (); filterregistration.setFilter (New DelegatingFilterProxy ("Shirofilter"); // Dieser Wert ist standardmäßig falsch und zeigt an, dass der Lebenszyklus durch SpringapplicationContext verwaltet wird. Auf True eingestellt bedeutet, dass der ServletContainer durch Filterregistration verwaltet wird. filterregistration.setenabled (true); filterregistration.addurlpatterns ("/*"); Rückgabefilterregistrierung; } / *** Diese Klasse kann sicherstellen, dass die init- oder zielgerichtete Methode des Shiro-Objekts, das die org.apache.shiro.util.Initializable-Schnittstelle implementiert, automatisch bezeichnet wird,* ohne manuell manuell die Init-Method- oder Destory-Methoden-Methode zu verwenden: Wenn diese Klasse verwendet wird, müssen Sie die Initialisierungsmethode und die Initialisierungsmethode. "LifecycleBeanPostProcessor") öffentlicher Lebenszycle -postprozessor getLifecycleBeanPostProcessor () {Return New LifecycleBeanPostProcessor (); } /*** Die folgenden zwei Konfigurationen werden hauptsächlich verwendet, um die Unterstützung der Shiro AOP -Annotation zu aktivieren. Verwenden Sie die Proxy -Methode; Sie müssen also den Code -Support aktivieren. * @return */ @bean @Dependson ("LifeCycleBeanPostProcessor") public defaultAdvisorautoproxycreator getDefaultAdvisorautoproxycreator () {defaultAdvisorautoproxycreator DAAP = new DefaultAdvisorAutoproxyCreator (); daap.setProxytargetClass (true); DAAP zurückgeben; } / ** * @param SecurityManager * @Return * / @Bean Public AuthorizationAttributeSourceAwvisor getAuthorizationAttributeSourceadvisor (DefaultWebSecurityManager SecurityManager) {AutorizationAttributeSourceAwvisor AutorizationAtRibuteSourCeadvisor = new AuthorizationAtTributesArceAdvisor (); AuthorizationAttributesourceadvisor.SetSecurityManager (SecurityManager); Return AuthorizationAttributesourceadvisor; } / *** CAS -Filter* @return* / @bean (name = "Casfilter") public Casfilter getCasFilter () {Casfilter Casfilter = new Casfilter (); Casfilter.SetName ("Casfilter"); CasFilter.SetEnabled (true); // Die URL, die nach dem Anmeldung fehlgeschlagen ist, dh Shiro führt die DogetAuthenticationInfo -Methode von Casrealm aus, um Tiket Casfilter.setFailureurl (loginurl) zu verifizieren. Casfilter zurückgeben; } / ** * Erstellen und initialisieren Shirofilter mit dem Werksmodus * @param SecurityManager * @param Casfilter * @return * / @bean (name = "shirofilter") public shirofilterFactoryBean getShiroLterfactoryBean (DefaultWebilityManager SecurityManager, CasFilter Casfilter) shirofilterFactoryBean = new ShirofilterFactoryBean (); // SecurityManager muss ShirofilterFactoryBean.SetSecurityManager (SecurityManager) festgelegt werden. // Wenn Sie die Standardeinstellung nicht festlegen, finden Sie automatisch die Seite "/login.jsp" im Root -Verzeichnis des Webprojekts ShirofilterFactoryBean.setLoginurl (Loginurl). / * * Die nach dem Anmeldung umgeleitete Verbindung ist erfolgreich. Wenn es nicht festgelegt ist, wird es standardmäßig zur vorherigen URL springen. * Zum Beispiel haben Sie zuerst http: // localhost: 8080/userlist im browser eingegeben, jetzt ist der user nicht angemeldet, sodass er zur Anmeldeseite springt. Nachdem die Anmeldeauthentifizierung übergeben wurde, springt die Seite * automatisch zur Seite http: // localhost: 8080/userlist anstelle der Indexseite nach dem erfolgreichen Anmeldung. Es wird nicht empfohlen, dieses Feld einzustellen */ // shirofilterfactoryBean.setsuSuccessurl (loginuccessurl); // unbefugten Zugriff auf die Seite ShirofilterFactoryBean.Setunauthorizedurl (nicht autorisierte) festlegen; / * * Casfilter zu Shirofilter hinzufügen. Beachten Sie, dass CasFilter vor Shirofilter platziert werden muss, um sicherzustellen, dass das Programm vor dem Eingeben von Shiro-Login-Login */ MAP <String, Filter> filters = new LinkedHasMap <> () eingeht. filters.put ("Casfilter", Casfilter); // logout wurde durch Single-Point-Logout // filters.put ("logout", logoutFilter ()) ersetzt; shirofilterFactoryBean.SetFilters (Filter); LoadshiroFilterchain (ShirofilterFactoryBean); Return ShirofilterFactoryBean; } /*** Laden Sie Shirofilter -Berechtigungssteuerungsregeln (aus der Datenbank gelesen und dann konfigurieren), Rollen- /Berechtigungsinformationen werden vom Objekt MyShirocasrealm bereitgestellt. detgetAuthorizationInfo -Implementierung. * This part of the rules will be placed in the database during production* @param shiroFilterFactoryBean */ private void loadShiroFilterChain(ShiroFilterFactoryBean shiroFilterFactoryBean){ //////////////////////////////////////// The following rules are best configured in the Konfigurationsdatei. Beachten Sie, dass der hier hinzugefügte Filter ordnungsgemäß sein muss. Verwenden Sie also LinkedHashMap ////////////////////////////////////////////////// Map <String> filterchaindefinitionmap = New LinkedHasMap <String, String> (). filterchainedefinitionmap.put (Casfilterurlpattern, "Casfilter"); // 2. Anfragen, die filterchaindefinitionMap.put nicht abfangen ("/css/**", "anon"); filterchainedefinitionmap.put ("/js/**", "anon"); filterchainedefinitionmap.put ("/login", "anon"); // Setzen Sie hier die Abmeldeseite auf Anon, nicht abmelden, da der Abmelden an einem einzigen Punkt verarbeitet wird und nicht von Shiros logoutfilter filterchainedefinitionmap.put ("/logout", "Anon") abgefangen werden muss. filterchainedefinitionmap.put ("/error", "anon"); // 3. Abgefangene Anfragen (erhalten Sie aus der lokalen Datenbank oder aus dem Auflauf (Remote -Methoden wie WebService, HTTP usw.), sehen Sie, wo Ihre Rollenberechtigungen konfiguriert sind) FilterchaNDeFinitionMap.put ("/user", "Authc"). // Anmeldung erforderlich // 4. Anmeldung fällt FilterchainDefinitionMap.put ("/**", "Authc") nicht ab; shirofilterFactoryBean.SetFilterChaindeFinitionMap (filterchainedefinitionMap); }}Einige Konfigurationsreferenz: http://shiro.apache.org/spring.html
3. Schreiben Sie Reich
Da wir die Funktionen von Single Sign-On integrieren müssen, müssen wir die Casrealm-Klasse integrieren. Diese Klasse hat die Funktionen der Einzelpunktauthentifizierung für uns implementiert. Wir müssen die Funktionen des Autorisierungsteils implementieren. Der Beispielcode lautet wie folgt:
Paket com.chhliu.springboot.shiro.config; import Javax.annotation.Resource; import org.apache.shiro.securityutils; import org.apache.shiro.authc.authenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authz.authenticationInfo; import org.apache.shiro.authz.simpleauthorizationInfo; import org.apache.shiro.cas.casrealm; import org.apache.shiro.subject.principalcollection; importieren com.chhliu.springboot.shiro.mode.syspermission; importieren com.chhliu.springboot.shiro.mode.syspermission; import com.chhliu.springboot.shiro.mode.userinfo; import com.chhliu.springboot.shiro.service.userinfoService; /*** Berechtigungsüberprüfung der Kernklasse; Da einzelne Sign-On verwendet wird, ist keine Authentifizierung erforderlich. Nur Autorisierung ist erforderlich * * @author chhliu */ public class myshirorealm erweitert Casrealm {@resource private userInfoService userInfoService; / *** 1. CAS -Authentifizierung, überprüfen Sie die Benutzeridentität* 2. Setzen Sie die Grundinformationen der Benutzer in die Sitzung für einfachen Zugriff* 3. Diese Methode kann die Authentifizierungsmethode in Casrealm direkt verwenden, die nur als Test verwendet wird Casrealm hat für uns einen einzigen Authentifizierungspunkt implementiert. AuthenticationInfo authc = super.dogetAuthenticationInfo (token); // Erhalten Sie das angemeldete Konto. Nachdem die CAS -Authentifizierung erfolgreich ist, wird das Konto gespeichert. String account = (String) authcc.getPrincipals (). GetPrimaryPrincipal (); // Benutzerinformationen in die Sitzung speichern, um eine einfache Programmakquise zu erhalten. Hier können Sie die Benutzerinformationen basierend auf dem Anmeldekonto in die Sitzung Securityutils.getSubject () einfügen. GetSession (). SetAttribute ("no", Konto); return authc; } /*** Callback wird nur ausgeführt, wenn diese Methode HasRole und HaSermission aufruft. * * Berechtigungsinformationen. (Autorisierung): 1. Wenn der Benutzer normalerweise ausgeht, wird der Cache automatisch gelöscht. 2. Wenn der Benutzer abnormal ausgeht, wird der Cache automatisch gelöscht. * 3.. Wenn wir die Berechtigungen des Benutzers ändern, der Benutzer jedoch nicht aus dem System abweist, können die geänderten Berechtigungen nicht sofort wirksam werden. (Es muss manuell implementiert werden; in Betrieb in Betrieb genommen werden) * Nachdem die Genehmigung geändert wurde, wird die Methode im Bereich aufgerufen. Realm wurde im Frühling verwaltet, daher wird die Realm -Instanz aus der Feder erhalten und die klare Methode wird genannt. *: Die Autorisierung ist autorisierte Zugriffskontrolle, die zur Autorisierung des vom Benutzer ausgeführten Vorgangs verwendet wird und beweist, ob der Benutzer den aktuellen Vorgang wie den Zugriff auf einen bestimmten Link, eine bestimmte Ressourcendatei usw. erlaubt. Konfiguration-> myshirorealm.dogetAuthorizationInfo () "); SimpleAuthorizationInfo AuthorizationInfo = new SimpleAuthorizationInfo (); // Erhalten Sie den Benutzernamen nach einer einzigen Anmeldung, Sie können ihn auch aus der Sitzung erhalten, da der Benutzername nach dem Erfolg der Authentifizierung in den Sitzungsstring username = (String) Super.GetAvailablePrincipal (Schulleiter) eingebracht wurde. // Principals.getPrimaryPrincipal (); Diese Methode kann auch den Benutzernamen erhalten // die Rolle des Benutzers und die Berechtigungsinformationen basierend auf dem Benutzernamen userInfo userInfo = userInfoService.FindbyUSERNAME (Benutzername); // Verpacken Sie die entsprechenden Rolle und Berechtigungsinformationen des Benutzers in AuthorizationInfo für (SysROL -Rolle: userInfo.getrolelist ()) {AuthorizationInfo.Addrole (rollen.getrole ()); für (sySermission p: rollen.getPermissions ()) {AuthorizationInfo.AddStringPermission (P.GetPermission ()); }} return AuthorizationInfo; }} Als nächstes können wir Verifizierungstests durchführen!
Geben Sie im Browser http: 127.0.1.28: 8080/userInfo/Benutzerliste ein und wir werden feststellen
Dann geben wir den Benutzernamen und das Kennwort ein, und es wird automatisch auf die Seite http: 127.0.1.28: 8080/userInfo/Benutzerliste einsteigen.
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, es wird für das Lernen aller hilfreich sein und ich hoffe, jeder wird Wulin.com mehr unterstützen.