Table des matières
Extension basée sur les annotations personnalisées de Shiro
Comment associer des pages aux interfaces API par la logique
Utilisation des auto-annotations de Shiro
Comment écrire des annotations personnalisées
Maison Java javaDidacticiel Extension des annotations personnalisées basées sur Shiro - explication détaillée avec images et texte

Extension des annotations personnalisées basées sur Shiro - explication détaillée avec images et texte

Aug 09, 2018 pm 05:19 PM
java spring

Extension basée sur les annotations personnalisées de Shiro

Ici, nous adoptons principalement la solution d'annotation personnalisée de Shiro. Cet article résout principalement les problèmes suivants.

  1. Comment associer la page à l'interface API par la logique.

  2. Utilisation de l'auto-annotation de Shiro.

  3. Comment rédiger des annotations personnalisées.

Comment associer des pages aux interfaces API par la logique

Dans la relation structurelle entre les tables, les tables de page et d'interface sont finalement associées à la table des autorisations (Pour plus de détails, veuillez consulter mon article précédent « Discussions diverses sur la conception des autorisations »).
Extension des annotations personnalisées basées sur Shiro - explication détaillée avec images et texteNous espérons désormais la remplacer par une autre solution permettant d'atteindre un faible coût tout en prenant en compte un certain degré de contrôle des autorisations. Nous introduisons ici deux concepts. Module métier, Type d'opération.

  • Module métier

    • Concept : résumer le module métier dans le système en une sorte de données, on peut l'exprimer sous forme de chaîne, par exemple : la gestion des rôles correspond à role-manage, la gestion des utilisateurs correspond à user-manage, etc. Nous divisons les modules métiers existants dans le système selon le « principe du moindre privilège » et formons enfin un lot de données distribuables.

    • Principes d'utilisation : L'interface API, la page et la fonction sont essentiellement logiquement liées au module métier. Par conséquent, nous pouvons comparer l'interface API et la page ( et. points de fonction) pour effectuer une correspondance logique afin de déterminer la relation entre la page et l'interface.

  • Type d'opération

    • Concept : Résumer tous les types d'opérations du système en un seul. peut aussi exprimer ce type de données sous forme de chaînes, par exemple : add correspond à un nouvel ajout, allot correspond à une allocation, etc. Nous divisons tous les types d'opérations dans le système via des « licences de données » en fonction des modules métier, et formons enfin un lot de données distribuables.

    • Principes d'utilisation : La page est l'affichage, le point de fonction est l'action et l'interface est la mise à disposition des ressources pour l'action finale. à appeler sont déterminés via le "module métier", le "type d'opération" détermine la manière dont la ressource est utilisée. Grâce aux deux, vous pouvez déterminer approximativement et précisément si l'interface déclenchée par le point de fonction de la page se situe dans la plage d'authentification.

Maintenant que ces deux concepts sont proposés, quelle est leur utilisation réelle finale Réfléchissons-y d'abord sous les perspectives suivantes ?

  1. Les données de la table des pages de la base de données ou de la table de l'interface API sont-elles réelles et valides ?

  2. L'utilisation réelle de la page ou de l'interface repose sur l'existence de fonctions ou l'existence de données dans la table de la base de données.

  3. Dans la structure des autorisations, le seul moyen de stocker des « objets de contrôle » est-il la base de données ?

Examinons ces problèmes depuis la conclusion. Tout d'abord, le stockage des "objets de contrôle" peut être dans la base de données, dans le code ou dans le fichier de configuration. il ne faut pas nécessairement être dans la base de données ; alors pour répondre à la deuxième question, lorsque les informations d'interface existent dans la base de données mais que le serveur n'a pas développé cette interface, il y a un problème avec les informations de la base de données elle-même, ou avec la nouvelle interface dans la base de données. doit être côté serveur Seules les interfaces qui ont été déployées peuvent prendre effet ; alors il y a la première question, alors les données de la table "objet de contrôle" dans la base de données ne sont pas forcément vraies et valides. Nous pouvons donc proposer la solution suivante

  1. Nous pouvons utiliser le formulaire d'annotation pour compléter les informations de données du "module métier" et du "type d'opération" sur le interface, les deux types d'informations peuvent être stockés dans des classes constantes.

  2. Lors de l'ajout et de la création de la structure de la table de page et de la structure de la table de fonction de page dans la base de données, ajoutez le "Module Business" et " Champs "Type d'opération".

  3. Vous pouvez stocker les informations « Module métier » et « Type d'opération » dans la table du dictionnaire de la base de données.

  4. L'ajout de modules ou d'opérations entraînera inévitablement l'ajout d'interfaces, ce qui entraînera une activité de déploiement du système. Ce coût d'exploitation et de maintenance ne peut être réduit. structure des tableaux.

Extension des annotations personnalisées basées sur Shiro - explication détaillée avec images et texte

Cependant, cette solution ne convient qu'aux projets d'interface de contrôle non forte. Dans les projets d'interface de contrôle forte, la page et l'interface doivent toujours être liées, même si cela entraînera d'énormes coûts d'exploitation et de maintenance. De plus, il peut également être divisé par règles de routage d'interface, par exemple : /api/page/xxxx/ (utilisé uniquement pour les pages), /api/mobile/xxxxx (utilisé uniquement pour les terminaux mobiles) classera les interfaces qui ne sont utilisées que par pages.Cette interface de classe effectue uniquement l'authentification mais pas l'autorisation, ce qui peut également atteindre cet objectif.

Utilisation des auto-annotations de Shiro

Après avoir été approuvé par une idée théorique, le reste est mis en pratique technique Nous utilisons le framework de sécurité d'Apache Shiro, appliqué dans l'environnement Spring Boot. Expliquez brièvement les annotations suivantes de Shiro.

注解名 作用
@RequiresAuthentication 作用于的类、方法、实例上。调用时,当前的subject是必须经过了认证的。
@RequiresGuest 作用于的类、方法、实例上。调用时,subject可以是guest状态。
@RequiresPermissions 作用于的类、方法、实例上。调用时,需要判断suject中是否包含当前接口中的Permission(权限信息)。
@RequiresRoles 作用于的类、方法、实例上。调用时,需要判断subject中是否包含当前接口中的Role(角色信息)。
@RequiresUser 作用于的类、方法、实例上。调用时,需要判断subject中是否当前应用中的用户。
    /**
     * 1.当前接口需要经过"认证"过程
     * @return
     */
    @RequestMapping(value = "/info",method = RequestMethod.GET)
    @RequiresAuthentication
    public String test(){
        return "恭喜你,拿到了参数信息";
    }
    
    /**
     * 2.1.当前接口需要经过权限校验(需包含 角色的查询 或 菜单的查询)
     * @return
     */
    @RequestMapping(value = "/info",method = RequestMethod.GET)
    @RequiresPermissions(value={"role:search","menu":"search"},logical=Logical.OR)
    public String test(){
        return "恭喜你,拿到了参数信息";
    }
    
    /**
     * 2.2.当前接口需要经过权限校验(需包含 角色的查询 与 菜单的查询)
     * @return
     */
    @RequestMapping(value = "/info",method = RequestMethod.GET)
    @RequiresPermissions(value={"role:search","menu":"search"},logical=Logical.OR)
    public String test(){
        return "恭喜你,拿到了参数信息";
    }
    
    /**
     * 3.1.当前接口需要经过角色校验(需包含admin的角色)
     * @return
     */
    @RequestMapping(value = "/info",method = RequestMethod.GET)
    @RequiresRoles(value={"admin"})
    public String test(){
        return "恭喜你,拿到了参数信息";
    }
    
    /**
     * 3.2.当前接口需要经过角色与权限的校验(需包含admin的角色,以及角色的查询 或 菜单的查询)
     * @return
     */
    @RequestMapping(value = "/info",method = RequestMethod.GET)
    @RequiresRoles(value={"admin"})
    @RequiresPermissions(value={"role:search","menu":"search"},logical=Logical.OR)
    public String test(){
        return "恭喜你,拿到了参数信息";
    }
Copier après la connexion

Dans notre processus d'utilisation réel, nous n'avons en fait besoin d'utiliser que @RequiresPermissions et @RequiresAuthentication. Cette annotation est suffisante à la fin de la section précédente, nous avons pris La combinaison des modules métier. et les opérations visant à découpler la relation entre les pages et les interfaces API sont exactement les mêmes que l'approche d'Apache Shiro. Mais nous essayons de ne pas utiliser @RequiresRoles autant que possible, car il y a trop de combinaisons de rôles et le nom du rôle ne peut pas être représenté de manière unique dans l'interface (il est difficile de spécifier que l'interface appartient à un certain rôle, mais vous peut certainement savoir que l'interface appartient à certains modules métier) Quelques opérations. )

Passons maintenant en revue l'ensemble du processus de fonctionnement.

Extension des annotations personnalisées basées sur Shiro - explication détaillée avec images et texte

Comment écrire des annotations personnalisées

Mais avoir ces 5 annotations dans shiro n'est certainement pas suffisant. Dans le processus d'utilisation réel, en fonction des besoins, nous ajouterons notre propre logique métier unique à l'authentification des autorisations. Pour plus de commodité, nous pouvons utiliser des annotations personnalisées. Cette méthode n'est pas seulement applicable à Apache Shiro, mais aussi à de nombreux autres frameworks tels que : Hibernate Validator, SpringMVC, et même nous pouvons écrire un système de vérification pour vérifier les autorisations dans aop, ce qui ne pose aucun problème. Par conséquent, les annotations personnalisées ont un large éventail d’utilisations. Mais ici, je n'implémente que des annotations personnalisées adaptées basées sur shiro.

  • Définir la classe de traitement des annotations

/**
 * 用于认证的接口的注解,组合形式默认是“或”的关系
 */
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Auth {
    /**
     * 业务模块
     * @return
     */
    String[] module();
    /**
     * 操作类型
     */
    String[] action();

}
Copier après la connexion
  • Définir la classe de traitement des annotations

/**
 * Auth注解的操作类
 */
public class AuthHandler extends AuthorizingAnnotationHandler {


    public AuthHandler() {
        //写入注解
        super(Auth.class);
    }

    @Override
    public void assertAuthorized(Annotation a) throws AuthorizationException {
        if (a instanceof Auth) {
            Auth annotation = (Auth) a;
            String[] module = annotation.module();
            String[] action = annotation.action();
            //1.获取当前主题
            Subject subject = this.getSubject();
            //2.验证是否包含当前接口的权限有一个通过则通过
            boolean hasAtLeastOnePermission = false;
            for(String m:module){
                for(String ac:action){
                    //使用hutool的字符串工具类
                    String permission = StrFormatter.format("{}:{}",m,ac);
                    if(subject.isPermitted(permission)){
                        hasAtLeastOnePermission=true;
                        break;
                    }
                }
            }
            if(!hasAtLeastOnePermission){
                throw new AuthorizationException("没有访问此接口的权限");
            }

        }
    }
}
Copier après la connexion
  • Définir la classe de traitement d'interception de Shiro

/**
 * 拦截器
 */
public class AuthMethodInterceptor extends AuthorizingAnnotationMethodInterceptor {


    public AuthMethodInterceptor() {
        super(new AuthHandler());
    }

    public AuthMethodInterceptor(AnnotationResolver resolver) {
        super(new AuthHandler(), resolver);
    }

    @Override
    public void assertAuthorized(MethodInvocation mi) throws AuthorizationException {
        // 验证权限
        try {
            ((AuthHandler) this.getHandler()).assertAuthorized(getAnnotation(mi));
        } catch (AuthorizationException ae) {
            if (ae.getCause() == null) {
                ae.initCause(new AuthorizationException("当前的方法没有通过鉴权: " + mi.getMethod()));
            }
            throw ae;
        }
    }
}
Copier après la connexion
  • Définir la classe d'aspect AOP de Shiro

/**
 * shiro的aop切面
 */
public class AuthAopInterceptor extends AopAllianceAnnotationsAuthorizingMethodInterceptor {
    public AuthAopInterceptor() {
        super();
        // 添加自定义的注解拦截器
        this.methodInterceptors.add(new AuthMethodInterceptor(new SpringAnnotationResolver()));
    }
}
Copier après la connexion
  • Définir la classe de démarrage d'annotation personnalisée de Shiro

/**
 * 启动自定义注解
 */
public class ShiroAdvisor extends AuthorizationAttributeSourceAdvisor {

    public ShiroAdvisor() {
        // 这里可以添加多个
        setAdvice(new AuthAopInterceptor());
    }

    @SuppressWarnings({"unchecked"})
    @Override
    public boolean matches(Method method, Class targetClass) {
        Method m = method;
        if (targetClass != null) {
            try {
                m = targetClass.getMethod(m.getName(), m.getParameterTypes());
                return this.isFrameAnnotation(m);
            } catch (NoSuchMethodException ignored) {

            }
        }
        return super.matches(method, targetClass);
    }

    private boolean isFrameAnnotation(Method method) {
        return null != AnnotationUtils.findAnnotation(method, Auth.class);
    }
}
Copier après la connexion
Séquence globale d'idées : définir une classe d'annotation (Définir variables pouvant être utilisées par l'entreprise) -> Définir classe de traitement d'annotations (effectuer le traitement de la logique métier via des variables dans les annotations) -> Définir intercepteur d'annotations -> ;Définir Classe d'aspect d'aop->Définissez enfin la classe d'activation d'annotations personnalisée de Shiro. Les idées d'écriture pour d'autres annotations personnalisées sont similaires à celle-ci.

Recommandations associées :

Explication détaillée de la méthode d'importation de la bibliothèque de balises personnalisées thinkPHP21 de mappage d'annotations personnalisées

À propos des annotations personnalisées en Java Détaillées introduction

Explication détaillée de la mise en œuvre de l'autorisation shiro

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Comment déverrouiller tout dans Myrise
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Nombre parfait en Java Nombre parfait en Java Aug 30, 2024 pm 04:28 PM

Guide du nombre parfait en Java. Nous discutons ici de la définition, comment vérifier le nombre parfait en Java ?, des exemples d'implémentation de code.

Générateur de nombres aléatoires en Java Générateur de nombres aléatoires en Java Aug 30, 2024 pm 04:27 PM

Guide du générateur de nombres aléatoires en Java. Nous discutons ici des fonctions en Java avec des exemples et de deux générateurs différents avec d'autres exemples.

Weka en Java Weka en Java Aug 30, 2024 pm 04:28 PM

Guide de Weka en Java. Nous discutons ici de l'introduction, de la façon d'utiliser Weka Java, du type de plate-forme et des avantages avec des exemples.

Numéro de Smith en Java Numéro de Smith en Java Aug 30, 2024 pm 04:28 PM

Guide du nombre de Smith en Java. Nous discutons ici de la définition, comment vérifier le numéro Smith en Java ? exemple avec implémentation de code.

Questions d'entretien chez Java Spring Questions d'entretien chez Java Spring Aug 30, 2024 pm 04:29 PM

Dans cet article, nous avons conservé les questions d'entretien Java Spring les plus posées avec leurs réponses détaillées. Pour que vous puissiez réussir l'interview.

Break or Return of Java 8 Stream Forach? Break or Return of Java 8 Stream Forach? Feb 07, 2025 pm 12:09 PM

Java 8 présente l'API Stream, fournissant un moyen puissant et expressif de traiter les collections de données. Cependant, une question courante lors de l'utilisation du flux est: comment se casser ou revenir d'une opération FOREAK? Les boucles traditionnelles permettent une interruption ou un retour précoce, mais la méthode Foreach de Stream ne prend pas directement en charge cette méthode. Cet article expliquera les raisons et explorera des méthodes alternatives pour la mise en œuvre de terminaison prématurée dans les systèmes de traitement de flux. Lire plus approfondie: Améliorations de l'API Java Stream Comprendre le flux Forach La méthode foreach est une opération terminale qui effectue une opération sur chaque élément du flux. Son intention de conception est

Horodatage à ce jour en Java Horodatage à ce jour en Java Aug 30, 2024 pm 04:28 PM

Guide de TimeStamp to Date en Java. Ici, nous discutons également de l'introduction et de la façon de convertir l'horodatage en date en Java avec des exemples.

Créer l'avenir : programmation Java pour les débutants absolus Créer l'avenir : programmation Java pour les débutants absolus Oct 13, 2024 pm 01:32 PM

Java est un langage de programmation populaire qui peut être appris aussi bien par les développeurs débutants que par les développeurs expérimentés. Ce didacticiel commence par les concepts de base et progresse vers des sujets avancés. Après avoir installé le kit de développement Java, vous pouvez vous entraîner à la programmation en créant un simple programme « Hello, World ! ». Une fois que vous avez compris le code, utilisez l'invite de commande pour compiler et exécuter le programme, et « Hello, World ! » s'affichera sur la console. L'apprentissage de Java commence votre parcours de programmation et, à mesure que votre maîtrise s'approfondit, vous pouvez créer des applications plus complexes.

See all articles