Qu'est-ce que Shiro
Shiro est un cadre d'autorisation open source pour la plate-forme Java pour l'authentification et l'autorisation d'accès. Plus précisément, le support des éléments suivants est rempli:
Q: Prise en charge du groupe?
R: Shiro ne prend pas en charge la définition des autorisations pour les groupes par défaut.
Q: Peut-il répondre aux besoins de l'allocation des rôles pour les groupes?
R: L'extension du royaume peut prendre en charge l'attribution de rôles à des groupes, qui consiste en fait à attribuer des autorisations à tous les utilisateurs du groupe.
Q: Prise en charge des autorisations de données? Défini dans un système commercial?
R: Shiro implémente uniquement le contrôle des autorisations d'opération, qui est utilisée pour masquer ou afficher les éléments de contrôle frontal et vérifier les autorisations d'accès aux ressources. Les autorisations de données sont étroitement liées à des besoins commerciaux spécifiques et Shiro lui-même ne peut pas contrôler les autorisations de données.
Q: Allocation d'autorisation dynamique?
R: étendre org.apache.shiro.realm.realm pour prendre en charge l'allocation d'autorisation dynamique.
Q: Intégrer au printemps?
R: Il peut prendre en charge l'intégration avec Spring, et Shiro prend également en charge les balises JSP.
Dans le blog précédent, nous avons parlé des deux plus grandes fonctionnalités de Shiro, l'authentification et l'autorisation. L'authentification unique fait également partie de l'authentification. Par défaut, Shiro a implémenté l'intégration avec CAS pour nous, et ce sera OK si nous ajoutons des configurations intégrées.
1. Ajouter un package Shiro-Cas
<! - Shiro intègre le point unique CAS -> <dependency> <proupId> org.apache.shiro </prôdId> <Ertifactid> shiro-Cas </ artifactid> <version> 1.2.4 </-version> </dependency>
2. Ajouter une configuration de connexion unique
Ici, j'ai publié toutes les configurations pour une référence facile et des instructions détaillées ont été ajoutées à la configuration.
package com.chhliu.springboot.shiro.config; import java.util.linkedhashmap; importation 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.sses.SingleSignoutFilter; import org.jasig.cas.client.session.SingleSignouthTTSSessionListener; import org.springframework.aop.framework.autoproxy.defaultAdvisorAutoproxyCreator; import org.springframework.boot.web.servlet.filterRegistrationBean; import org.springframework.boot.web.servlet.servletListeRegrationBean; 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; / ** * CONFIGURATION SHIRO * * APACHE SHIRO CORE est implémenté via Filtre, tout comme SpringMvc utilise DispachServlet pour le contrôler. Puisque nous utilisons * Filtre, nous pouvons généralement deviner que le filtrage et la vérification de l'autorisation se font via des règles d'URL, nous devons donc définir une série de règles et des droits d'accès sur les URL. * * @author chhliu * / @configuration classe publique shiroconfiguration {// Adresse du serveur CAS public statique final statique CasserverLprefix = "http://127.0.0.1"; // CAS de page de connexion Adresse publique statique final string casloginurl = CasserVerUrlPrefix + "/ Login"; // Cas Logout Page Adresse publique statique final String CaslogOutl = CasserVerUrlPrefix + "/ Logout"; // L'adresse de service actuelle fournie par le projet à la chaîne finale statique publique extérieure shiroserverurlprefix = "http://127.0.1.28:8080"; // CasFilter UrlPattern public static final String CasFilterUlPattern = "/ index"; // Adresse de connexion publique statique finale statique Loginurl = Casloginurl + "? Service =" + shiroServerurlPrefix + CasFilterLpattern; // Adresse de déconnexion (Casserver Active la fonction de saut de service, et vous devez activer Cas.logout.SollowServicereDirects = TRUE dans le fichier WebApps / Cas / Web-Inf / Cas.Properties) Public Static String LogouTurl = CasLogUturl + "? Service =" + Loginurl; // Connexion Adresse réussie // Public Static Final String LoginSuccressUrl = "/ index"; // Authentification autorisation a échoué Adresse de saut publique Statique statique Final String UnauthorizedUrl = "/Error/403.html"; / ** * Instanciate SecurityManager, cette classe est la classe principale de Shiro * / @return * / @bean public DefaultWebSecurityManager SecurityManager () {defaultWebSecurityManager SecurityManager = new defaultWebSecurityManager (); SecurityManager.SetRealm (MyshiroCasrealm ()); // <! - Cache d'informations sur l'autorisation / authentification de l'utilisateur, en utilisant ehcache cache -> SecurityManager.SetCacheManager (getEHCacheManager ()); // Spécifiez SubjectFactory. Si vous souhaitez implémenter la fonction Remember Me of CAS, vous devez utiliser le CassubjectFactory suivant et le définir sur SecurityManager SubterFactory SecurityManager.SetSubjectFactory (new CassubjectFactory ()); Retour SecurityManager; } / ** * Configurer le cache * @return * / @bean public ehcacheManager GetEhcacheManager () {ehcacheManager em = new ehcacheManager (); em.setCacheManagerConfigfile ("classPath: config / ehcache-shiro.xml"); retourner EM; } / ** * Configurer le royaume. Depuis que nous utilisons Casrealm, la fonction de connexion unique a été intégrée * @param cacheManager * @return * / @bean public myshirorealm myshirocasrealm () {myshirorealm royaume = new myshirorealm (); // Adresse du serveur CAS Préfixe RealM.SetCasserVerUrlPrefix (shiroconfiguration.casserVerUrlPrefix); // Adresse de rappel client, adresse de saut après la connexion est réussie (sa propre adresse de service) RealM.SetCasservice (shiroconfiguration.shiroserverurlprefix + shiroconfiguration.casfilterurlpattern); // Le rôle par défaut après la connexion est réussi, ici par défaut, le rôle de l'utilisateur RealM.SetDefaulTROLS ("utilisateur"); REALD REALM; } / ** * Enregistrer l'écouteur de déconnexion unique * @return * / @SuppressWarnings ({"RawTypes", "Unchecked"}) @Bean @Order (ordonné.Highest_precedence) // La priorité est supérieure à CAS PublicLetLeListRenergrationBean <? ServletListEnergistrationBean (); bean.setListener (New SingleSignouthTTSSessionListener ()); bean.setEnabled (true); Retour haricot; } / ** * Enregistrer le filtre de déconnexion unique * @return * / @bean public filterRegistrationBean singleSignoutFilter () {filterRegistrationBean Bean = new FilterRegistrationBean (); bean.setName ("singleSignoutFilter"); bean.setFilter (nouveau singleSignoutFilter ()); bean.addurlpatterns ("/ *"); bean.setEnabled (true); Retour haricot; } / ** * Enregistrer la délégation de FilterProxy (Shiro) * / @Bean Public FilterRegistrationBean DelegatingFilterProxy () {FilterRegistrationBean FilterRegistration = new FilterRegistingBean (); FilterRegistration.SetFinter (nouveau déléguationFilterProxy ("shirofilter")); // Cette valeur est fausse par défaut, indiquant que le cycle de vie est géré par SpringApplicationContext. Défini sur True signifie que le servletContainer est géré par filterRegtration.AdDinitParameter ("TargetFilterLifecycle", "true"); FilterRegistration.SetEnabled (true); filterRegistration.addurlPatterns ("/ *"); Retour filtrage; } / ** * Cette classe peut s'assurer que la méthode init ou destory de l'objet Shiro qui implémente l'interface org.apache.shiro.util.initializable est automatiquement appelée, * sans spécifier manuellement la méthode d'initialisation ou la méthode d'initialisation et la méthode de détruire, sinon une erreur se produit * @retRun "LifecycleBeanPostProcessor") public LifecycleBeanPostProcessor getlifecycleBylepostProcessor () {return New LifecycleBylePostProcessor (); } / ** * Les deux configurations suivantes sont principalement utilisées pour activer le support d'annotation SHIRO AOP. Utiliser la méthode proxy; Vous devez donc activer la prise en charge du code; * @return * / @bean @dependSon ("LifecycleBeanPostProcessor") Public DefaultAdvisorAutoproxycreator getDefaultAdvisorAutoproxyCreator () {DefaultAdvisorAutoproxycreator DAAP = new defaultVisorAutoproxycreator (); daap.setProxyTargetClass (true); retour daap; } / ** * @param SecurityManager * @return * / @Bean AutorisationAttributesourceAdvisor getAuthorizationAtButeSourceAdvisor (DefaultWebSecurityManager SecurityManager) {AutorisationAttributeSourceAdvisor AuthorizationAtriButeSourceAdVisor = new AuthorizationAtTRiButeSourCeadVisor (); AutorisationAtTributesourceadVisor.SetSecurityManager (SecurityManager); Retour autorisationAtTributesourceadVisor; } / ** * CAS Filter * @return * / @bean (name = "Casfilter") public Casfilter getCasFilter () {CasFilter Casfilter = new CasFilter (); CasFilter.SetName ("Casfilter"); CasFilter.SetEnabled (true); // L'URL qui saute après l'échec de la connexion, c'est-à-dire que Shiro exécute la méthode DoGetAuthenticationInfo de Casrealm pour vérifier Tiket Casfilter.SetFailureUrl (Loginurl); // Nous choisissons d'ouvrir la page de connexion après l'authentification Casfilter.SetLoginurl (Loginurl); retour en casfilter; } / ** * Créer et initialiser le shirofilter en utilisant le mode d'usine * @param SecurityManager * @param Casfilter * @return * / @bean (name = "shirofilter") public shirofilterfactorybean getShirofilterFactoryBean (DefaultweburityManager SecurityManAger, casfilter casfilter) {shirofilterfactoryBeanBeanBean Casfilter) {ShirofilterFactoryBeanBeanBean casfilter) {ShiroFilterfactorbeanBeanBean Casfilter) {ShiroFilterfactorbeanBeanBean Casfilter) {ShiroFilterfactorbeanBeanBean Casfilter) ot shirofilterFactoryBean = new ShirofilterFactoryBean (); // SecurityManager doit être défini ShirofilterFactoryBean.SetSecurityManager (SecurityManager); // Si vous ne définissez pas la valeur par défaut, il trouvera automatiquement la page "/login.jsp" dans le répertoire racine du projet Web ShirofilterFactoryBean.setLoginurl (Loginurl); / * * La connexion à rediriger après la connexion est réussie. S'il n'est pas défini, il passera à l'URL précédente par défaut. * Par exemple, vous avez d'abord entré http: // localhost: 8080 / utilisateur dans le navigateur, mais maintenant l'utilisateur n'est pas connecté, il passera donc à la page de connexion. Une fois l'authentification de connexion passée, la page * sautera automatiquement à la page http: // localhost: 8080 / userList au lieu de la page d'index après la connexion réussie. Ce champ n'est pas recommandé d'être défini * / // ShirofilterFactoryBean.SetSucCessUrl (LoginSucCessUrl); // Définit un accès non autorisé à la page ShirofilterFactoryBean.SetUnAuthorizeDUrl (UnauthorizedUrl); / * * Ajouter Casfilter à Shirofilter. Notez que Casfilter doit être placé devant le shirofilter * pour s'assurer que le programme entrera l'authentification en un seul point avant d'entrer dans la connexion de la connexion Shiro * / map <String, filter> filters = new LinkedHashMap <> (); filters.put ("Casfilter", Casfilter); // La déconnexion a été remplacée par une connexion à un point // filters.put ("Logout", LogoutFilter ()); shirofilterfactorybean.setFilters (filtres); LoadShirofilterChain (ShirofilterFactoryBean); retour shirofilterfactoryBean; } / ** * Chargez les règles de contrôle d'autorisation de shirofilter (lire dans la base de données puis configurer), les informations sur le rôle / l'autorisation sont fournies par l'objet Myshirocasrealm. Implémentation DoGetAuthorizationInfo. * 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 configuration déposer. Notez que le filtre ajouté ici doit être ordonné, alors utilisez Linkedhashmap ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////DRANT FilterChainDefinitionMap.put (CasfilterurlPattern, "Casfilter"); // 2. Demandes qui n'interceptent pas FilterChainDefinitionMap.put ("/ css / **", "anon"); filterChainDefinitionMap.put ("/ js / **", "anon"); filterChainDefinitionMap.put ("/ login", "anon"); // Ici, définissez la page de déconnexion sur anon, pas la déconnexion, car la déconnexion est traitée par un seul point, et elle n'a pas besoin d'être interceptée par LogoutFilter FilterChainDefinitionMap.put de Shiro ("/ Logout", "anon"); filterChainDefinitionMap.put ("/ error", "anon"); // 3. Demandes interceptées (obtenir de la base de données locale ou du Casserver (méthodes distantes telles que WebService, http, etc.), voir où vos autorisations de rôle sont configurées) filterChainDefinitionMap.put ("/ user", "authc"); // Connexion requise // 4. La connexion n'intercepte pas FilterChainDefinitionMap.put ("/ **", "authc"); ShirofilterFactoryBean.SetFilterChainDefinitionMap (FilterChainDefinitionMap); }}Quelques références de configuration: http://shiro.apache.org/spring.html
3. Écrivez le royaume
Étant donné que nous devons intégrer les fonctions de connexion unique, nous devons intégrer la classe Casrealm. Cette classe a implémenté les fonctions d'authentification à point unique pour nous. Ce que nous devons faire, c'est implémenter les fonctions de la partie d'autorisation. L'exemple de code est le suivant:
package 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.simpleautautationInfo; import org.apache.shiro.cas.casrealm; import org.apache.shiro.subject.principalCollection; import com.chhliu.springboot.shiro.mode.syspermission; import com.chhliu.springboot.shiro.mode.syspermission; import com.chhliu.springboot.shiro.mode.userinfo; import com.chhliu.springboot.shiro.service.UserInfoservice; / ** * Classe de base de vérification d'autorisation; Étant donné que la connexion unique est utilisée, il n'est pas nécessaire de s'authentifier, la simple autorisation est requise * * @Author Chhliu * / classe publique Myshirorealm étend Casrealm {@Resource Private UserInfoService userInfoService; / ** * 1. Authentification CAS, vérifiez l'identité de l'utilisateur * 2. Définissez les informations de base de l'utilisateur dans la session pour un accès facile * 3. Cette méthode peut directement utiliser la méthode d'authentification dans Casrealm, qui est uniquement utilisée comme test * / @Override Protected AuthenticationInfo DOGGETAUTENTICTIONINFO (AuthenticationToken Token) {// La méthode d'authentification dans la classe parent. Casrealm a mis en œuvre un seul point d'authentification pour nous. AuthenticationInfo authc = super.DoGetAuthenticationInfo (token); // Obtenez le compte connecté. Une fois l'authentification CAS réussie, le compte sera enregistré. String Account = (String) Authc.GetPrincipals (). GetPrimaryPrincipal (); // Enregistrer les informations de l'utilisateur dans la session pour une acquisition de programme facile. Ici, vous pouvez mettre les informations utilisateur interrogées en fonction du compte de connexion dans la session SecurityUtils.getSubject (). Getession (). SetAttribute ("non", compte); return authc; } / ** * Le rappel ne sera effectué que lorsque cette méthode appelle Hasrole et Haspermission. * * Informations d'autorisation. (Autorisation): 1. Si l'utilisateur sort normalement, le cache sera automatiquement effacé; 2. Si l'utilisateur quitte anormalement, le cache sera automatiquement effacé; * 3. Si nous modifions les autorisations de l'utilisateur mais que l'utilisateur ne se déconnecte pas du système, les autorisations modifiées ne peuvent pas prendre effet immédiatement. (Il doit être implémenté manuellement; mettre en service pour l'appel) * Une fois l'autorisation modifiée, la méthode dans le royaume est appelée. Le royaume a été géré par le printemps, donc l'instance de royaume est obtenue à partir de Spring et la méthode en clear est appelée; *: L'autorisation est un contrôle d'accès autorisé, utilisé pour autoriser l'opération effectuée par l'utilisateur, prouvant si l'utilisateur autorise l'opération actuelle, telle que l'accès à un certain lien, un certain fichier de ressources, etc. * * @param principes * @return * / @Override Protected AuthorizationInfo dogetAuthorizonInfo (PrincipalCollection Principals) {System.out.PrintLn ("Permission permission Configuration -> Myshirorealm.DoGetAuthorizationInfo () "); SimpleAuthorizationInfo AuthorizationInfo = new SimpleAuthorizationInfo (); // obtient le nom d'utilisateur après une connexion unique, vous pouvez également l'obtenir à partir de la session, car une fois l'authentification réussie, le nom d'utilisateur a été placé dans le nom d'utilisateur de la chaîne de session = (String) super.GetAvailablePrincipal (directeurs); // directeurs.getPrimaryPrincipal (); Cette méthode peut également obtenir le nom d'utilisateur // obtenir le rôle de l'utilisateur et les informations d'autorisation en fonction du nom d'utilisateur userInfo userInfo = userInfoservice.FindByUsername (nom d'utilisateur); // Package des informations correspondantes et d'autorisation correspondantes de l'utilisateur dans AuthorizationInfo pour (Sysrole Role: userInfo.getRoleList ()) {AuthorizationInfo.Addrole (Role.Getrole ()); pour (syspermission p: role.getPerMissions ()) {AuthorizationInfo.AddStringPermission (p.getPermission ()); }} return AuthorizationInfo; }} Ensuite, nous pouvons effectuer des tests de vérification!
Entrez HTTP: 127.0.1.28: 8080 / UserInfo / UserList dans le navigateur et nous constaterons qu'il passera automatiquement à la page de connexion à point unique
Ensuite, nous entrons le nom d'utilisateur et le mot de passe et il passera automatiquement à la page HTTP: 127.0.1.28: 8080 / userInfo / UserList.
Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.