Comment apprendre rapidement en seulement 30 minutes Shiro

Dans cette partie résume le plus de Zhang Kaitao de « Suivez-moi Shiro » Adresse originale: http: //jinnianshilongnian.iteye.com/blog/2018936

Je ne l'ai pas lu tout, il suffit de choisir la partie de la connaissance du besoin urgent pour moi d'utiliser dans le projet à l'apprentissage. Et pour la plupart du premier contact avec les étudiants Shiro, la maîtrise de ces devrait être suffisant.

Tout d'abord, l'architecture

Pour apprendre à utiliser Shiro doit commencer à parler de son architecture, en tant que conception du cadre de sécurité Shiro est assez sophistiqué. Shiro application ne dépend pas d'un conteneur qui peut être utilisé dans JavaSE. Mais le plus environnement commun ou JavaEE. En tant qu'utilisateur, par exemple les éléments suivants:

(1) en utilisant les informations de connexion de l'utilisateur pour créer un jeton

UsernamePasswordToken jeton = new UsernamePasswordToken (nom d'utilisateur, mot de passe);

jeton peut être compris comme un jeton d'utilisateur, le processus de connexion est extrait comme Shiro vérifier si le jeton a le statut juridique et les privilèges connexes.

(2) la mise en oeuvre de l'opération d'atterrissage

SecurityUtils.setSecurityManager (securityManager); // injection du SecurityManager 
Sujet Sujet SecurityUtils.getSubject = (); // obtenir l'objet Objet singleton 
subject.login (jeton); // connexion

Shiro est une partie de base SecurityManager, qui est responsable de l'authentification de sécurité et d'autorisation. Shiro lui-même a atteint tous les détails, l'utilisateur peut le compléter comme une boîte noire à l'utilisation. objet SecurityUtils est essentiellement similaire à une usine au printemps ApplicationContext. Le sujet est plus difficile à comprendre pour les objets débutants, beaucoup de gens pensent qu'il peut être assimilé à l'utilisateur, ce n'est pas. Sujet traduction chinoise: le projet, et bien compris est précisément le cas. Il est un concept abstrait que vous avez besoin actuellement conçu par des projets de protection Shiro. Par les relations symboliques (jeton) et projet (sous réserve) connexion (login), Shiro assurer la sécurité globale du projet.

(3) déterminer l'utilisateur

Shiro détenu par lui-même ne peut pas savoir si un signe de l'utilisateur légitime, car en plus du concepteur du projet, je crains que l'on peut pas savoir. Alors Royaume est l'un des rares dans les modules entiers cadres eux-mêmes doivent être mises en œuvre par le concepteur, bien sûr, Shiro offre une variété de façons d'atteindre, cet article ne décrit que le plus commun et le plus important la mise en œuvre - les requêtes de base de données.

(4) deux importantes anglais

Le premier I obstacle rencontré dans le processus d'apprentissage Shiro de ces deux objets est le nom anglais: AuthorizationInfo, AuthenticationInfo. Je ne doute pas leurs propres yeux, à long comme ils le font, non seulement comme une longue, même sens similaire.

Avant d'expliquer qu'ils doivent d'abord décrire Shiro définir la sécurité pour les utilisateurs: la plupart des systèmes d'exploitation. Les rôles utilisateur et les autorisations ont deux propriétés de base. Par exemple, mon nom d'ouverture de session Windows est learnhow, son rôle est administrateur et l'administrateur a tous les privilèges du système. Un tel learnhow ont naturellement tous les privilèges du système. Ensuite, d'autres ont besoin de se connecter à mon ordinateur comment faire, je peux ouvrir un rôle d'invité, ne peut pas fournir un nom d'utilisateur et mot de passe utilisateur inconnu peut se connecter par un invité, et le système est extrêmement limité pour les rôles d'invité d'autorisations ouvertes.

De même, les contraintes Shiro sur l'utilisateur manière un aussi utilisé. AuthenticationInfo représente des informations rôle de l'utilisateur de la collection, la collecte d'informations AuthorizationInfo au nom des rôles d'autorité. Ainsi, lorsque le concepteur du projet dans l'un des chemins URL pour permettre seulement un rôle ou des privilèges à avoir des contraintes de contrôle d'accès de temps, Shiro peut être jugé par deux ou plusieurs objets. Ici, il peut aussi être plus confus. Ne vous inquiétez pas, nous continuerons naturellement à regarder en arrière et comprendre.

En second lieu, la réalisation Realm

Comment atteindre Realm est le point fort de cet article, il fait partie plus gênant. Vous y entrer en contact avec plusieurs concepts nouveaux: la mise en cache, l'algorithme de hachage, algorithme de chiffrement. Parce que ce n'est pas consacré à ces concepts, donc ici que pour faire quelques meilleures idées qui peuvent vous aider à mieux comprendre Shiro peut être.

(1) le mécanisme de cache

Ehcache est beaucoup de cadre de la mise en cache Java utilisé dans le projet, Hibernate est l'un d'entre eux. Il est de la nature des données d'origine ne peut être stocké en mémoire par l'algorithme stocké sur le disque dur, puis tourner sur demande. Vous pouvez Ehcache comprise comme une carte <String, Object> objet, mettre sauvegarde de l'objet, puis passer à travers pour récupérer des objets.

Copiez le code
<? xml version = "1.0" encoding = "UTF-8"?> 
<ehcache name = "shirocache"> 
    <chemin diskStore = "java.io.tmpdir" /> 
    
    <cache name = "passwordRetryCache" 
           maxEntriesLocalHeap = "2000" 
           éternelle = "false" 
           timeToIdleSeconds = "1800" 
           timeToLiveSeconds = "0" 
           overflowToDisk = "false" 
           statistiques = "true"> 
    </ cache> 
</ ehcache>
Copiez le code

Ce sont le fichier ehcache.xml de configuration de base, timeToLiveSeconds est le plus grand cache du temps de survie, timeToIdleSeconds au maximum le temps d'inactivité pour le cache, quand éternel est faux et ttl TTI avant de pouvoir prendre effet. Plus qui signifie que vous pouvez configurer à la requête en ligne.

(2) Les algorithmes de hachage et des algorithmes de chiffrement

algorithme de hachage md5 sera utilisé ici, cet article ne concerne pas l'algorithme de chiffrement. Et chiffrer l'objet de hachage essentiellement une chaîne dans une chaîne de sens, après que l'objet est différent du hachage ne peut pas être annulée, un processus à sens unique. Par exemple, le cryptage des mots de passe utilise généralement un algorithme de hachage, de sorte que l'utilisateur que si vous avez oublié votre mot de passe et ne pouvez pas obtenir le mot de passe d'origine en modifiant. Mais pour les informations chiffrées est algorithme de chiffrement formel, des informations chiffrées peuvent être déchiffrées par une clé secrète et de restauration.

(3) Enregistrement de l'utilisateur

S'il vous plaît noter que, bien que les problèmes de sécurité que nous avons parlé de connexion de l'utilisateur, mais quand il vient à l'utilisateur de connexion de l'utilisateur est d'abord enregistré. Comment faire en sorte que les informations d'enregistrement de l'utilisateur ne soit pas perdu, non-divulgation est au centre de la conception du projet.

Copiez le code
{Class PasswordHelper publique 
    privée RandomNumberGenerator RandomNumberGenerator new new SecureRandomNumberGenerator = (); 
    Private AlgorithmName String = "MD5"; 
    hashIterations finale privée int = 2; 

    EncryptPassword public void (l'utilisateur de l' utilisateur) { 
        // l'objet utilisateur contient les champs de base Nom d' utilisateur et mot de passe 
        utilisateur. les setSalt (randomNumberGenerator.nextBytes () toHex (.)); 
        // le mot de passe d'enregistrement utilisateur algorithme de mot de passe haché est remplacé par de nouvelles données stockées dans une des utilisations du procédé de hachage irréversible 
        chaîne newPassword = new SimpleHash (AlgorithmName, utilisateur .getPassword (), 
                ByteSource.Util.bytes (user.getCredentialsSalt ()), hashIterations) .toHex (); 
        user.setPassword (newPassword); 
    } 
}
Copiez le code

Si vous ne savez pas ce processus de sel appelé Hash peut être ignoré, aussi longtemps que vous connaissez le mot de passe stocké dans la base de données selon une nouvelle chaîne est entrée lorsque le mot de passe d'enregistrement utilisateur généré par celui-ci. Après avoir remplacé les mots de passe lors de l'enregistrement haché mot de passe de l'utilisateur, l'utilisateur enregistré dans la base de données. UserService reste du travail qu'il reste à traiter.

Donc, ce a apporté un nouveau problème, puisque l'algorithme de hachage n'est pas rétabli lorsqu'un mot de passe lorsque les utilisateurs se connectent à l'aide de l'enregistrement original, comment devrions-nous juger? La réponse est à nouveau nécessaire dans le même algorithme de hachage une fois le mot de passe de l'utilisateur, puis comparer la chaîne stockée dans la même base de données.

(4) convient

CredentialsMatcher est une fonction d'interface est utilisée pour faire correspondre les utilisateurs de jeton et la base de données enregistrées Connectez-vous avec les matches d'information de l'utilisateur. Bien sûr, sa fonction est non seulement. Cet article est d'introduire une classe qui implémente cette interface: HashedCredentialsMatcher

Copiez le code
RetryLimitHashedCredentialsMatcher extends HashedCredentialsMatcher {public class 
    // déclare une interface de cache qui fait partie de la gestion du cache Shiro, sa mise en œuvre spécifique peut être injecté à travers le récipient extérieur 
    privé du cache <String, de AtomicInteger> passwordRetryCache; 

    RetryLimitHashedCredentialsMatcher public (CacheManager CacheManager) { 
        passwordRetryCache = CacheManager .getCache ( "passwordRetryCache"); 
    } 

    @Override 
    publique Boolean doCredentialsMatch (jeton AuthenticationToken, informations AuthenticationInfo) { 
        chaîne username = (String) token.getPrincipal (); 
        de AtomicInteger retrycount = passwordRetryCache.get (nom d' utilisateur); 
        IF (== null retrycount ) { 
            RetryCount de nouveaux AtomicInteger nouveaux = (0); 
            passwordRetryCache.put (nom d' utilisateur, retrycount); 
        } 
        // un processus de validation personnalisée: Lorsque l'utilisateur continue d'entrer dans le mot de passe erroné cinq fois ou plus une période de temps empêche les utilisateurs de se connecter 
        IF (retryCount.incrementAndGet ()> 5) { 
            le ExcessiveAttemptsException de lancer une nouvelle nouvelle (); 
        } 
        Boolean = match super.doCredentialsMatch (jeton, info), 
        IF (jeu) { 
            passwordRetryCache.remove (nom d' utilisateur); 
        } 
        match retour; 
    } 
}
Copiez le code

Vous pouvez le voir, ce n'est atteint dans le concepteur ajoute un juge ne permet pas d'erreur continue journal. Ou au processus réel de correspondant à son parent direct à complète. erreurs de connexion en continu de jugement cache Ehcache repose à atteindre. Il est évident que le rendement correspond vrai pour un match réussi.

(5) pour obtenir le rôle et les autorisations de l'information de l'utilisateur

Cela dit que notre seul domaine de mise au point, si vous comprenez Shiro pour les utilisateurs enregistrés correspondant et le chiffrement de l'ensemble du processus, pour parvenir à une véritable compréhension du royaume, mais relativement simple. Nous devons retourner deux objets très similaires AuthorizationInfo et AuthenticationInfo mentionnés ci-dessus. Parce que domaine local est de fournir ces deux objets.

Copiez le code
UserRealm public class étend AuthorizingRealm { 
    informations de caractère correspondant aux informations de l' autorité de l' utilisateur // sont stockés dans la base de données, les données acquises par UserService 
    Private UserService nouvelles nouvelles UserServiceImpl que UserService = (); 

    / ** 
     * renvoie les informations à fournir les informations de l' autorité de l' utilisateur 
     * / 
    @Override 
    protégé doGetAuthorizationInfo authorizationInfo (PrincipalCollection les directeurs d' école sont) { 
        chaîne username = (String) principals.getPrimaryPrincipal (); 
        SimpleAuthorizationInfo authorizationInfo = new new SimpleAuthorizationInfo (); 
        // rôle de requête de nom d'utilisateur de l'utilisateur actuel possède 
        Set <role> rôles = userService.findRoles ( nom d' utilisateur) , 
        le Set <String> = new new HashSet noms de rôle <String> (); 
        } 
        pour (rôle Rôle: rôles) {
            roleNames.add (role.getRole ()); 
    @Override
        // noms de rôle seront fournis aux informations 
        authorizationInfo.setRoles (noms de rôle); 
        // requête le nom d'utilisateur des autorisations utilisateur en cours à 
        l'ensemble <autorisation> = userService.findPermissions les permissions (nom d' utilisateur), 
        le Set <String> = permissionNames new new HashSet <String> () ; 
        pour (l'autorisation de permission: autorisations) { 
            permissionNames.add (permission.getPermission ()); 
        } 
        // le nom de l'autorité fournie aux informations 
        authorizationInfo.setStringPermissions (permissionNames); 

        retour authorizationInfo; 
    } 

    / ** 
     * renvoie les informations d'authentification pour fournir des informations de compte 
     * /
    AuthenticationInfo doGetAuthenticationInfo protégé (jeton AuthenticationToken) lancers francs de AuthenticationException { 
        chaîne username = (String) token.getPrincipal (); 
        l'utilisateur Utilisateur = userService.findByUsername (nom d' utilisateur); 
        IF (utilisateur == null) { 
            // nom d'utilisateur n'existe pas encore jeté un 
            jet UnknownAccountException nouvelle nouvelle (); 
        } 
        IF (user.getLocked () == 0) { 
            // utilisateur administrateur est verrouillé une exception est levée 
            le jet nouvelle nouvelle LockedAccountException (); 
        } 
        SimpleAuthenticationInfo authenticationInfo = new new SimpleAuthenticationInfo (user.getUsername (), 
                user.getPassword (), ByteSource.Util.bytes (user.getCredentialsSalt () ), getName ()); 
        retour authenticationInfo; 
    } 
}
Copiez le code

La relation des idées de conception avant Shiro, l'utilisateur et de rôle plusieurs entre le rôle et l'autorité est beaucoup à beaucoup. Il est donc nécessaire d'établir la base de données cinq tables sont table utilisateur (stocke le nom d'utilisateur, mot de passe, le sel, etc.), le rôle de la table (rôle nom, description, etc.), table d'autorisation (nom d'autorisation, description, etc.), l'utilisateur - rôle le, le rôle correspondant table intermédiaire (rôle ID et l'ID d'utilisateur en tant que clé primaire) - la table de correspondance d'autorisation intermédiaire (à l'ID de rôle et l'identifiant d'autorisation en tant que clé primaire). dao spécifiques et les mises en œuvre de services article ne fournit pas. En conclusion courte est que, Shiro requis si le nom d'utilisateur et mot de passe pour vous connecter d'abord déterminer l'utilisateur légitime, puis autorisé aux utilisateurs légitimes. Et ce processus est le royaume du processus de mise en œuvre.

Session (6)

authentification unique est la première session, Shiro peut également remplacer conteneurs tels que Tomcat session de gestion de l'utilisateur. Le but est que lorsqu'un séjour d'utilisateur sur une page pour un long moment aucune action quand, une fois l'accès à tout lien sera redirigé vers la page de connexion demandé à entrer de nouveau votre nom d'utilisateur et mot de passe sans qu'il soit nécessaire pour les programmeurs de garder à l'Servlet déterminer si la session objet utilisateur contient. Une autre utilisation est activée la gestion des sessions Shiro peut prendre différentes sessions pour les différents modules de traitement. Taobao, par exemple, après Taobao utilisateurs enregistrés peuvent choisir de se rappeler le nom d'utilisateur et mot de passe. Après la visite à nouveau sans y atterrir. Mais si vous voulez accéder à péage ou panier et d'autres liens nécessite encore l'utilisateur de confirmer l'identité. Bien sûr, Shiro peut également créer session utiliser le conteneur pour atteindre le plus.

Troisièmement, l'intégration avec SpringMVC

Avec module de support de modules enregistrés et Realm, voici comment intégrer le développement et SpringMVC. Cadre intégré avait des étudiants expérimentés doivent connaître, soi-disant intégré essentiellement un groupe de configuration de fichier xml, Shiro pas exception.

(1) filtres frontaux de configuration

Permettez-moi de parler une digression, le filtre est un filtre, intercepteur intercepteurs. Sur la base de l'ancienne fonction de rappel, vous devez compter sur des supports de conteneurs. En raison du récipient besoin assemblé l'ensemble FilterChain et un par un appel. La dernière mise en œuvre à base d'agents, appartiennent à la catégorie des AOP.

Si vous voulez utiliser Shiro doit d'abord être configuré dans le fichier web.xml dans l'environnement WEB

Copiez le code
<xml version = "1.0" encoding = "UTF-8"?> 
<xmlns web-app: xsi = "http://www.w3.org/2001/XMLSchema-instance" 
    xmlns = "http: // java .sun.com / xml / ns / JavaEE " 
    xsi: schemaLocation =" http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0 xsd » 
    id = "WebApp_ID" version = "3.0"> 
    <display-name> Shiro_Project </ display-name> 
    <welcome-file-list> 
        <welcome-file> index.jsp </ fichier de bienvenue> 
    </ accueil -file-list> 
    <servlet> 
        <servlet-name> SpringMVC </ servlet-name> 
        <servlet-class> org.springframework.web.servlet.DispatcherServlet </ servlet-class> 
        <init-param> 
            <param-name> contextConfigLocation </ param-name>
            <param-value> classpath: springmvc.xml </ param-value> 
        </ init-param> 
        <load-on-startup> 1 </ load-on-startup> 
        <async supporté> true </ async appuyé> 
    </ servlet> 
    <servlet-mapping> 
        <servlet-name> SpringMVC </ servlet-name> 
        <url-pattern> / </ url-pattern> 
    </ servlet-mapping> 
    <listener> 
        <listener-class> org.springframework .web.context.ContextLoaderListener </ auditeur-class> 
    </ auditeur> 
    <listener> 
        <listener-class> org.springframework.web.util.Log4jConfigListener </ auditeur-class> 
    </ auditeur> 
    <context-param>
        <param-name> contextConfigLocation </ param-name> 
        <- -将Shiro的配置文件交给printemps监听器初始化!> 
        <param-value> classpath: spring.xml, classpath: printemps-Shiro-web.xml </ param-value> 
    </ context-param> 
    <context-param> 
        <param-name> log4jConfigLoaction </ param-name> 
        <param-value> classpath: log4j.properties </ param-value> 
    </ context-param > 
    <! - Shiro配置开始-> 
    <filtre> 
        <nom-filtre> shiroFilter </ filter-name> 
        <filtre class> org.springframework.web.filter.DelegatingFilterProxy </ filtre classe> 
        <async-prise en charge > true </ async soutenu>
        <init-param> 
            <param-name> targetFilterLifecycle </ param-name>
            <param-value> true </ param-value> 
        </ init-param> 
    </ filter> 
    <filter-mapping> 
        <filter-name> shiroFilter </ filter-name> 
        <url-pattern> / * </ url- motif> 
    </ filter-mapping> 
    <! - Shiro配置结束-> 
</ web-app>
Copiez le code

Familiariser les étudiants configuration Spring peuvent regarder la partie de mise au point d'un commentaire de mot vert, ici il est la clé de l'entrée en vigueur de Shiro. Parce que la gestion du projet au cours du printemps, de sorte que toutes les directives de configuration sont remis au printemps. fonction ressort DelegatingFilterProxy est d'informer tous les filtres à la gestion ShiroFilter.

Ensuite, le fichier de configuration printemps-Shiro-web.xml dans le classpath

Copiez le code
<haricots xmlns = "http://www.springframework.org/schema/beans" 
    xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns: p = "http: // www .springframework.org / schéma / p » 
    xmlns: contexte = "http://www.springframework.org/schema/context" 
    xmlns: CVM = "http://www.springframework.org/schema/mvc" 
    xsi: schemaLocation = "http://www.springframework.org/schema/beans     
                        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd     
                        http://www.springframework.org/schema/context     
                        http : //www.springframework.org/schema/context/spring-context-3.1.xsd     
                        http://www.springframework.org/schema/mvc    
                        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd "> 

    <! -缓存管理器使用Ehcache实现-> 
    <bean id =" "class =" CacheManager org.apache. shiro.cache.ehcache.EhCacheManager "> 
        <property name =" « value = "cacheManagerConfigFile classpath: ehcache.xml"/> 
    </ bean> 

    <-凭证匹配器->! 
    <bean id = "class credentialsMatcher"= "utils.RetryLimitHashedCredentialsMatcher"> 
        <constructeur-arg ref = "CacheManager" /> 
        <property name = valeur "hashAlgorithmName" = "md5" /> 
        <property name = valeur "de hashIterations" = "2" /> 
        <property name = "storedCredentialsHexEncoded" value = "true" /> 
    </ bean> 

    <! - Royaume实现->
    <bean id = "userRealm" class = "utils.UserRealm"> 
        <property name = "credentialsMatcher" ref = "credentialsMatcher" /> 
    </ bean> 

    <! -安全管理器-> 
    <bean id = "securityManager" class = "org.apache.shiro.web.mgt.DefaultWebSecurityManager"> 
        <property name = "royaume" ref = "userRealm" /> 
    </ bean> 

    <! - Shiro的Web过滤器-> 
    <bean id = "shiroFilter" class = "org.apache.shiro.spring.web.ShiroFilterFactoryBean"> 
        <property name = "securityManager" ref = "securityManager" /> 
        <property name = value "loginUrl" = "/" />
        <property name = value "unauthorizedUrl" = "/" /> 
        <property name = "filterChainDefinitions"> 
            <value>
                / authc / admin = rôles [admin] 
                / authc / ** = authc 
                / ** = anon 
            </ value> 
        </ property> 
    </ bean> 

    <bean id = classe "lifecycleBeanPostProcessor" = "org.apache.shiro.spring .LifecycleBeanPostProcessor »/> 
</ beans>
Copiez le code

Remarque filterChainDefinitions chemin de filtre est agencé pour séquentiel, lorsque l'entrée correspondante se trouve dans le conteneur ne continuera pas à la recherche. Ainsi, le chemin d'être sur le dos avec des jokers. Signification trois configurations sont: / authc / admin exige que l'utilisateur soit des privilèges d'administrateur utiles, / authc / ** Les utilisateurs doivent se connecter à l'accès, / ** tous les autres chemins sont accessibles par quiconque.

Cela dit, nous devons nous préoccuper de la fin comment écrire le code pour se connecter au printemps après l'introduction de Shiro il.

Copiez le code
@Controller 
public class LoginController { 
    @Autowired 
    UserService privé UserService; 

    @RequestMapping ( "login") 
    connexion ModelAndView publique (@RequestParam ( "nom d' utilisateur") nom d' utilisateur String, @RequestParam ( "mot de passe") Mot de passe String) { 
        UsernamePasswordToken jeton = new UsernamePasswordToken (nom d' utilisateur, mot de passe); 
        Sujet subject = SecurityUtils.getSubject (); 
        try { 
            subject.login (jeton); 
        } Catch (glace IncorrectCredentialsException) { 
            //捕获密码错误异常
            ModelAndView mv = new ModelAndView ( "erreur"); 
            mv.addObject ( "message", "erreur de mot de passe!");
        Le} catch (UnknownAccountException EAU) { 
            // inconnu capture nom d' utilisateur exception 
            ModelAndView Music Videos new new ModelAndView = ( "erreur"); 
            mv.addObject ( "Message", "erreur de nom d' utilisateur!"), De 
            retour Vidéo Clips; 
        } les prises (ExcessiveAttemptsException EAE) { 
            // erreur capture journal sur un trop grand nombre anormal 
            ModelAndView mv = new new ModelAndView ( "erreur"); 
            mv.addObject ( "le message", "erreur Times"), 
            mv de retour; 
        } 
        l'utilisateur l'utilisateur = userService.findByUsername (nom d' utilisateur); 
        Objet. le getSession () le setAttribute ( "utilisateur", utilisateur) ;. 
        retour nouvelle nouvelle ModelAndView ( "succès"); 
    } 
}
Copiez le code

Une fois l'enregistrement terminé, les informations sont enregistrées dans la session utilisateur en cours. Cette session par session objet Shiro a réussi à obtenir doit encore passer Shiro. objet utilisateur n'existe pas dans la session traditionnelle.

Copiez le code
@Controller 
@ RequestMapping ( "authc") 
public class AuthcController { 
    // / authc / ** = authc par toute forme d'accès utilisateur peut connecter 
    @ RequestMapping ( "anyuser") 
    ModelAndView publique anyuser () { 
        Sujet Sujet = SecurityUtils.getSubject (), 
        l'utilisateur utilisateur = (l'utilisateur) subject.getSession () le getAttribute ( "utilisateur") ;. 
        System.out.println (utilisateur); 
        return new nouveau ModelAndView ( "intérieur"); 
    } 

    // / authc / utilisateur ADMIN = [ admin] seuls les utilisateurs ayant le rôle d'admin accès peut, sinon la demande sera redirigé vers l'écran de connexion 
    @ RequestMapping ( « admin ») 
    admin ModelAndView public () { 
        Sujet Sujet = SecurityUtils.getSubject (), 
        l'utilisateur l'utilisateur = (l'utilisateur) Sujet .getSession ().getAttribute ( "user");
        System.out.println (utilisateur); 
        return new ModelAndView ( "intérieur"); 
    } 
}
Copiez le code

IV Résumé

Shiro est une fonction du cadre est complet, il est également très facile à utiliser, mais pour faire un bon usage, il est assez difficile. Le code source complet du projet est pas le cas ici, nous devons étudiants en échange peuvent me donner un message ou un accès direct au blog Zhang Kaitao. Si vous pensez que je peux écrire, je veux aussi donner des commentaires.

V recommandée

Ceci est un site shiro apprentissage, que le système d'apprendre les élèves peuvent aller .

Sixième, melon vendre

Shiro veulent savoir l' intégration Springboot des petits partenaires se trouve dans un autre texte de l' article: « 30 minutes pour comprendre l' intégration Springboot Shiro »

Je suppose que tu aimes

Origine www.cnblogs.com/DuJiu/p/12563447.html
conseillé
Classement