Shiro
Apache Shiro est un cadre d'authentification et d'autorisation léger. Par rapport à la sécurité du printemps, il est simple et facile à utiliser et a une grande flexibilité. Springboot lui-même prend en charge la sécurité, après tout, c'est sa propre chose. Springboot n'intégre pas Shiro pour le moment, vous devez donc le faire correspondre vous-même.
1. Ajouter des dépendances
<dependency> <proupId> org.apache.shiro </rompuprid> <letifactive> shiro-spring </ artifactid> <version> 1.2.5 </ version> </Dependency> <Dependance> <ProupId> org.apache.shiro </proupId> <Artifactid> SHIRO-EHCACHE </RIFACTID> <DERNÉRATIONS>
2. Écrivez la classe de configuration de Shiro
package com.xbz.web.system.config; import at.pollux.thymeaf.shiro.dialect.shirodialect; import org.apache.shiro.authc.Credential.CredentialSmatcher; import org.apache.shiro.authc.Credential.HashedCredentialSmatcher; import org.apache.shiro.cache.ehcache.ehcacheManager; import org.apache.shiro.codec.base64; import org.apache.shiro.session.SessionListener; import org.apache.shiro.session.mgt.SessionManager; import org.apache.shiro.session.mgt.eis.memorySessionDao; import org.apache.shiro.session.mgt.eis.Sessiondao; 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.cookierembermemanager; import org.apache.shiro.web.mgt.defaultwebsecurityManager; import org.apache.shiro.web.servlet.simplecookie; import org.apache.shiro.web.session.mgt.defaultwebssessionManager; import org.springframework.aop.framework.autoproxy.defaultAdvisorAutoproxyCreator; import org.springframework.boot.autoconfigure.condition.condition.conditionalonMissingBean; import org.springframework.context.annotation.bean; import org.springframework.context.annotation.configuration; import org.springframework.context.annotation.dependSon; import java.util.arraylist; import java.util.collection; import java.util.linkedhashmap; importation java.util.map; / ** * Classe de configuration de Shiro * Le noyau Apacheshiro implémente le contrôle et l'interception de l'autorisation via le filtre, tout comme SpringMvc utilise DispachServlet pour contrôler la distribution des demandes. * Puisqu'il utilise le filtre, c'est-à-dire le filtrage et la vérification de l'autorisation via des règles d'URL, nous devons définir une série de règles et de droits d'accès sur les URL * / @configuration de classe publique Shiroconfiguration {/ ** * DefaultAdvisorAutoproxycreator, A Bean of Spring, et le conseiller décide quelles classes de méthodes pour aop proxy. * / @Bean @conditionalonMissingBean public DefaultAdvisorAutOproxyCreator DefaultAdvisorAutOproxyCreator () {DefaultAdVisorAutOproxyCreator DefaultAap = new DefaultAdVisorAutOproxyCreator (); defaultaap.setProxyTargetClass (true); return defaultaap; } / ** * ShirofilterFactoryBean: Afin de générer du shirofilter, gérez les fichiers de ressources interceptant. * Il maintient principalement trois éléments de données, SecurityManager, filtres, filterchainDefinitionManager. * Remarque: une seule configuration ShirofilterFactoryBean est ou rapporte une erreur, car lors de l'initialisation de ShirofilterFactoryBean, il est nécessaire d'injecter: SecurityManager * * FilterChain Definition Description * 1. Une URL peut configurer plusieurs filtres, séparés par des commandes * 2. Lorsque plusieurs filtres sont définis, tous les froideurs peuvent spécifier, et ils sont adoptés, et ils sont considérés comme adoptés * 3. perms, rôles * * / @bean public shirofilterfactorybean shirofilterfactorybean () {shirofilterfactorybean shirofilterfactorybean = new shirofilterfactorybean (); ShirofilterFactoryBean.SetSecurityManager (SecurityManager ()); shirofilterfactorybean.setloginurl ("/ login"); // ne définissez pas la page login.jsp sous le répertoire racine du projet web shirofilterfactorybean.setsuccessurl ("/ index"); // la connexion pour sauter après la connexion est réussie ShirofilterfactoryBean.setUnauThorizedUrl ("" / 403 "); Jump / * // Interceptor personnalisé, paramètres pour plusieurs filtres * // map <string, filter> filters = new LinkedHashMap <> (); // LogoutFilter LogoutFilter = new LogoutFilter (); // limite le nombre de numéros en ligne du même compte en même temps. ou une seule connexion, etc. // LogoutFilter.SetRedirectUrl ("/ Login"); // filters.put ("déconnexion", null); // shirofilterfactorybean.setFilters (filtres); Map <string, string> filterChainDefinitionMap = new LinkedHashMap <> (); // FilterChainDefinitionManager doit être un liendhashmap car il doit garantir que filterChainDefinitionMap.put ("/ css / **", "anon"); // Les ressources statiques ne nécessitent pas d'autorisations, s'il y a des fichiers dans d'autres répertoires (tels que JS, IMG, etc.) et FilterChainDefinitionMap.put ("/", "anon"); filterChainDefinitionMap.put ("/ login", "anon"); // Configurez la partie de l'URL FilterChainDefinitionMap.put ("/ Logout", "Logout"); filterChainDefinitionMap.put ("/ user / **", "Authc, rôles [Role_User]"); // L'utilisateur est un rôle Role_User à accéder. Le rôle utilisateur contrôle le comportement de l'utilisateur. FilterChainDefinitionMap.put ("/ Events / **", "Authc, Rôles [Role_Admin]"); // filterChainDefinitionMap.put ("/ user / edit / **", "Authc, perms [utilisateur: edit]"); // Pour les tests, la valeur morte est fixe et elle peut également être lue à partir de la base de données ou d'autres configurations. Ici, les autorisations sont utilisées pour contrôler FilterChainDefinitionMap.put ("/ **", "Authc"); // Ressources qui doivent être connectées, généralement mettre / ** au bas ShirofilterFactoryBean.SetFilterChainDefinitionMap (filterChainDefinitionMap); retour shirofilterfactoryBean; } //region cookies and Session // ========================== Cookie and Session Management begin ========================= private static final String COOKIE_NAME = "rememberMe"; / ** Cookie Object Management * / public SimpleCookie RememberMeCookie () {// Ce paramètre est le nom du cookie, correspondant au nom de la case à cocher sur le front-end = RememberMe SimpleCookie SimpleCookie = new SimpleCookie (cookie_name); SimpleCookie.SetMaxage (604800); // N'oubliez pas que mon cookie prend effet pendant 7 jours et que l'unité est retournée SimpleCookie; } / ** Objet de gestion des cookies: Remember Me Fonction * / public CookieMembermeManager RememberMemanager () {CookieMembermeManager CookieMemberMemanager = new CookieMemberMemanager (); CookieMemberMemanager.SetCookie (RememberMecookie ()); CookieMemberMemanager.SetCiPherkey (Base64.Decode ("3AVVHMFlus0Kta3KPRSDAG ==")); // La touche de chiffrement des cookies RememberMe suggère que chaque article est une longueur d'algorithme AES par défaut (128 256 512 bits) RETOUR COOKEREMEMERMEMERMEMEAGER; } @Bean sessiondao sessiondao () {return new MemorySessionDao (); } @Bean public SessionManager SessionManager () {DefaultWebSessionManager SessionManager = new defaultWebSessionManager (); Collection <SessionListener> écouteurs = new ArrayList <> (); auditeurs.add (new BDessionListener ()); SessionManager.SetSessionListeners (auditeurs); SessionManager.SetSessionDao (SessionDao ()); Retour sessionManager; } // ===================== Cookies and Session Management End ====================== / ENDREGION / ** * SECUEanManager: Core Security Transaction Manager, Gestion de la permission * Cette classe combine la connexion, la connexion, les autorisations et le traitement des session. C'est une classe relativement importante. * / @Bean (name = "SecurityManager") public DefaultWebSecurityManager SecurityManager () {DefaultWebSecurityManager SecurityManager = new defaultWebSecurityManager (); SecurityManager.SetRealm (Shirorealm ()); SecurityManager.SetCacheManager (ehcacheManager ()); ///// Cache d'informations d'autorisation / d'authentification utilisateur, en utilisant ehcache cache // La gestion de session personnalisée utilise redis SecurityManager.SetSessionManager (sessionManager ()); // Inject Rappelez-vous mon manager; SecurityManager.SetRembermeManager (RememberMemanager ()); Retour SecurityManager; } / ** * shirorealm, il s'agit d'une classe d'authentification personnalisée, héritée de l'autorisation de la réalité, * responsable de l'authentification des utilisateurs et du traitement de l'autorisation, vous pouvez vous référer à la mise en œuvre de JDBCrealm. * / @Bean @dependSon ("LifecycleBeAnPostProcessor") public shirorealm shirorealm (Matcher d'identingalsmatcher) {shirorealm realm = new shirorealm (); RealM.SetCredentialSmatcher (Matcher); // Vérification du mot de passe implémente le royaume de retour; } / ** * ehcacheManager, CacheManager * Une fois que l'utilisateur se connecte avec succès, cache les informations de l'utilisateur et les informations d'autorisation, puis chaque fois que l'utilisateur les demande, mettez-les dans la session de l'utilisateur. Si ce bean n'est pas défini, la base de données sera interrogée une fois pour chaque demande. * / @Bean @dependSon ("LifecycleBeanPostProcessor") public ehcachemanager ehcacheManager () {ehcacheManager em = new ehcacheManager (); em.setCacheManagerConfigfile ("classPath: config / ehcache.xml"); // le chemin de configuration du chemin return Em; } / ** * LifecycleBylePostProcessor, Ceci est une sous-classe de DestructionAwareBeanPostProcessor, * est responsable du cycle de vie de l'org.apache.shiro.util.Initializable Type Bean. * est principalement une sous-classe de classe d'autorisation, ainsi que de la classe ehcacheManager. * / @Bean (name = "lifecycleBeanPostProcessor") public lifycleByleBeanPostProcessor lifecycleBylePostProcessor () {return new LifecycleBeAnPostProcessor (); } / ** * HashEdCredentialSmatcher, cette classe est pour coder le mot de passe, * empêchant clairement les mots de passe dans la base de données. Bien sûr, lors de la connexion à l'authentification, * Cette classe est également responsable de l'encodage des mots de passe saisis sous le formulaire * Traitement Processeur de correspondance de l'authentification: Si la personnalisation nécessite l'héritage de HashhedCredentialSmatcher * / @Bean (name = "HashEdRedentialSmatcher") Public HasheDedentialSMatcher CodelSmatcher = new HashEdCredentialSmatcher (); IDEDSALTICALSMatcher.sethAshalgorithMname ("MD5"); // Spécifiez la méthode de chiffrement, et vous pouvez également ajouter le cache ici. Lorsque l'utilisateur se connecte à plus de cinq erreurs de connexion, l'utilisateur est verrouillé. Il est interdit à l'utilisateur d'essayer constamment de se connecter à CredentialSmatcher.Sethashiterations (2); IDEDENTALSMATCHER.SetStoredCredentialShexEncoded (true); RETOUR CIDENTIALSSMATCER; } / ** * AutorisationAttributesourceadVisor, la classe de conseiller implémentée dans Shiro, * Utilisez AOPALLIANCEAnNOTATION AUTHORISINEMetHodInterceptor en internet pour intercepter les méthodes avec les annotations suivantes. * / @Bean Public AuthorizationAttributesourceadVisor AuthorizationAtRributesourceAdVisor () {AutorizationAtButesourceCiseVisor Advisor = Nouvelle AutorisationAtButeSourceAdVisor (); Advisor.SetSecurityManager (SecurityManager ()); Conseiller de retour; } // @bean public shirodialect shirodialect () {return new shirodialect (); }} 3. Personnaliser la classe de vérification du royaume
package com.yiyun.web.system.config; import com.yiyun.dao.master.userdao; import com.yiyun.domain.userdo; import com.yiyun.web.common.utils.shiroutils; Importer com.yiyun.web.system.service.menUservice; import org.apache.shiro.securityUtils; import org.apache.shiro.authc. *; import org.apache.shiro.authz.authorizationInfo; import org.apache.shiro.authz.simpleautautationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.session.Session; import org.apache.shiro.subject.principalCollection; import org.springframework.beans.factory.annotation.Autowired; import java.util. *; / ** * Obtenez des informations sur les rôles et l'autorisation des utilisateurs * / classe publique Shirorealm étend l'autorisation d'autorisation {// Généralement, ce qui est écrit ici est Servic @Autowired Private UserDao UserMapper; @Autowired Private MenuService MenuService; / ** * Authentification de connexion De manière générale, après s'être connectée, l'utilisateur actuel a obtenu des autorisations. Cette étape est basée sur DoGetAuthenticationInfo. Ce n'est qu'après les informations de l'utilisateur que vous pouvez déterminer s'il faut autoriser l'utilisateur en fonction du rôle de l'utilisateur et des informations d'autorisation. Par conséquent, les rôles et les autorisations voici les deux principales bases de jugement de l'utilisateur * @param authenticationToken * @return * @throws authenticationException * / @Override Protected AuthenticationInfo doGetAuthenticationInfo (AuthenticationToken AuthenticationToken) lance AuthenticationException {userAmpasswordToken token = (usernamEpasswordToKet) AutorsionThenticingt; UserDo user = userMapper.FindByName (token.getUserName ()); // Vérifiez s'il y a cet utilisateur si (utilisateur! = Null) {// S'il y en a, stockez cet utilisateur dans les informations d'authentification de connexion, et il n'est pas nécessaire de comparer le mot de passe vous-même. Shiro effectuera la comparaison et la vérification des mots de passe pour nous List <Urole> rlist = uroledao.findrolebyuid (user.getId ()); // Obtenez la liste de rôles de l'utilisateur <Upmermite> plist = upmermissiondao.FindPermissionByUID (user.getID ()); // Get User Permistrer List <String> Rolestrlist = New ArrayList <string> (); List <string> permissionsstrlist = new ArrayList <string> (); /// Collection d'autorisation de l'utilisateur pour (UROLE Role: RList) {rolestrlist.add (role.getName ()); } pour (upmermission upmermission: plist) {perminsstrlist.add (upmermission.getName ()); } user.setrolestrlist (Rolestrlist); user.setperminsstrlist (perminsstrlist); Session Session = SecurityUtils.getSubject (). GetSession (); session.setAttribute ("utilisateur", utilisateur); // en cas de succès, mettez-le en session // s'il existe, stockez cet utilisateur dans les informations d'authentification de connexion, et vous n'avez pas besoin de comparer votre mot de passe vous-même. Shiro effectuera une vérification de comparaison de mot de passe pour nous. Renvoie un nouveau SimpleAuthenticationInfo (user, user.getPassword (), getName ()); } return null; } / ** * Authentification de l'autorisation * Obtenez les informations d'autorisation de l'utilisateur, qui consiste à porter des jugements pour la prochaine étape de l'autorisation, pour obtenir le rôle actuel de l'utilisateur et les informations d'autorisation appartenant à ces rôles * @Param PrincipalCollection * @return * / @Override Protected Authorization équivalent à (String) PrincipalCollection.FromRealm (getName ()). Iterator (). Next (); // String LoginName = (String) super.GetAvailablePrincipal (PrincipalCollection); UserDo user = (userDo) PrincipalCollection.getPrimaryPrincipal (); // // Accédez à la base de données pour vérifier si cet objet est présent // utilisateur utilisateur = null; // Dans les projets réels, vous pouvez vous mettre en cache en fonction de la situation réelle. Si vous ne le faites pas, Shiro lui-même a un mécanisme d'intervalle de temps et n'exécutera pas la méthode à plusieurs reprises dans les 2 minutes // utilisateur = userMapper.findByName (LoginName); if (utilisateur! = null) {// Informations d'autorisation Informations sur l'objet, est utilisée pour stocker tous les rôles (rôle) et les autorisations (autorisation) de l'utilisateur trouvé simPleauthorizationInfo info = new SimpleAuthorizationInfo (); // la collection de rôles de l'utilisateur info.addroles (user.getRolestrList ()); // Collection d'autorisation de l'utilisateur Info.AddSstringPerMissions (user.getperminsstrlist ()); retour des informations; } // Renvoie NULL, il amènera tout utilisateur à accéder à la demande interceptée pour passer automatiquement à l'adresse spécifiée par UnauthorizedUrl; }}4. Enfin, jetez un œil au fichier de configuration d'Ehcache
<? xml version = "1.0" Encoding = "utf-8"?> <ehcache xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" xsi: nonamespaceschemalation = "http://ehcache.org/ehcache.xsd" Toolecheck = " <diskstore path = "java.io.tmpdir / tmp_ehcache" /> <! - Nom: nom de cache. MaxElementsInMemory: Nombre maximum de caches Maxelementsondisk: Nombre maximum de caches pour disque dur. Eternal: si l'objet est valable en permanence, une fois défini, le délai d'expiration ne fonctionnera pas. OverflowTodisk: Il faut économiser sur le disque, TimeToidleseconds: Définit le temps d'inactivité autorisé (unité: secondes) de l'objet avant son expiration. Utilisé uniquement si l'objet éternel = false n'est pas valable en permanence, l'attribut facultatif, la valeur par défaut est 0, ce qui signifie que le temps d'inactivité est infini. TIMETOLIVESECONDS: Définit l'heure (unité: secondes) de l'objet avant son expiration. Le temps maximum est entre le temps de création et le temps de défaillance. Utilisé uniquement si l'objet éternel = faux n'est pas valide en permanence, la valeur par défaut est 0., ce qui signifie que le temps de survie de l'objet est infini. Diskpersistent: si le magasin de disques persiste entre les redémarrages de la machine virtuelle. La valeur par défaut est fausse. DiskSpoolBuffeSizemb: Ce paramètre définit la taille du cache du disque (cache de disque). La valeur par défaut est de 30 Mo. Chaque cache devrait avoir son propre tampon. DiskExpiryThreadIntervalSeconds: L'intervalle de temps d'exécution du thread de défaillance du disque, la valeur par défaut est de 120 secondes. MemoryStoreevictionPolicy: Lorsque la limite maxelementsInMemory est atteinte, ehcache nettoiera la mémoire en fonction de la politique spécifiée. La stratégie par défaut est LRU (plus récemment utilisée). Vous pouvez le définir sur FIFO (premier dans, premier sorti) ou LFU (moins utilisé). ClearonFlush: s'il faut effacer quand la quantité de mémoire est maximale. MemoryStoreevictionPolicy: trois stratégies de compensation pour ehcache; FIFO, d'abord en premier, c'est le plus familier à tout le monde, premier en premier. LFU, moins fréquemment utilisé, est la stratégie utilisée dans l'exemple ci-dessus. Pour être franc, il s'agit de dire qu'il a été le moins utilisé de tous les temps. Comme mentionné ci-dessus, l'élément mis en cache a un attribut Hit, et la valeur de coup la plus basse sera éliminée du cache. LRU, le moins récemment utilisé, l'élément mis en cache a un horodatage. Lorsque la capacité de cache est pleine et que vous devez faire de la place pour mettre en cache de nouveaux éléments, l'élément avec le temps le plus éloigné de l'élément de cache existant sera éliminé du cache. -> <defaultCache eternal = "false" maxElementsInMemory = "1000" overflowtodisk = "false" diskpersistentant = "false" TimeToidleSEconds = "0" TimetolivesEconds = "600" MemoryStoreevictionPolicy = "lru" /> <! - Login d'enregistrement de connexion pour 10 minutes -> <cache Name = "NomdRey" maxentriesLocalHeap = "2000" eternal = "false" TimeToidleSeconds = "3600" TIMETOLIVESECONDS = "0" overflowtoDisk = "false" statistics = "true"> </ cache> </hcache>
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.