zoukankan      html  css  js  c++  java
  • Shiro自定义注解扩展@SalmonRequiresPermission

    1.自定义注解 @SalmonRequiresPermission

     1 import java.lang.annotation.ElementType;
     2 import java.lang.annotation.Retention;
     3 import java.lang.annotation.RetentionPolicy;
     4 import java.lang.annotation.Target;
     5 
     6 import org.apache.shiro.authz.annotation.Logical;
     7 
     8 /**
     9  * SalmonRequiresPermissions is
    10  *
    11  * @author zzt
    12  * @date 2020/2/22 16:25:00
    13  */
    14 @Target({ElementType.TYPE, ElementType.METHOD})
    15 @Retention(RetentionPolicy.RUNTIME)
    16 public @interface SalmonRequiresPermissions {
    17     String[] value();
    18 
    19     Logical logical() default Logical.AND;
    20 
    21     // 描述
    22     String[] description();
    23 }

      这里只是简单的增加了一个描述,可根据需求自行扩展。

    2.自定义注解处理器,继承 AuthorizingAnnotationHandler

     1 import java.lang.annotation.Annotation;
     2 
     3 import org.apache.shiro.authz.AuthorizationException;
     4 import org.apache.shiro.authz.annotation.Logical;
     5 import org.apache.shiro.authz.annotation.RequiresPermissions;
     6 import org.apache.shiro.authz.aop.AuthorizingAnnotationHandler;
     7 import org.apache.shiro.subject.Subject;
     8 
     9 /**
    10  * SalmonPermissionAuthorizingAnnotationHandler is
    11  *
    12  * @author zzt
    13  * @date 2020/2/25 11:43:00
    14  */
    15 public class SalmonPermissionAuthorizingAnnotationHandler extends AuthorizingAnnotationHandler {
    16 
    17     // 继承父类构造器,注入SalmonRequiresPermissions注解
    18     public SalmonPermissionAuthorizingAnnotationHandler() {
    19         super(SalmonRequiresPermissions.class);
    20     }
    21 
    22     protected String[] getAnnotationValue(Annotation annotation) {
    23         SalmonRequiresPermissions srpAnnotation = (SalmonRequiresPermissions)annotation;
    24         return srpAnnotation.value();
    25     }
    26 
    27     @Override
    28     public void assertAuthorized(Annotation annotation) throws AuthorizationException {
    29         if (annotation instanceof SalmonRequiresPermissions) {
    30             SalmonRequiresPermissions srpAnnotation = (SalmonRequiresPermissions)annotation;
    31             String[] perms = this.getAnnotationValue(annotation);
    32             Subject subject = this.getSubject();
    33             if (perms.length == 1) {
    34                 subject.checkPermission(perms[0]);
    35             } else if (Logical.AND.equals(srpAnnotation.logical())) {
    36                 this.getSubject().checkPermissions(perms);
    37             } else {
    38                 if (Logical.OR.equals(srpAnnotation.logical())) {
    39                     boolean hasAtLeastOnePermission = false;
    40 
    41                     for (int i = 0; i < perms.length; ++i) {
    42                         String permission = perms[i];
    43                         if (this.getSubject().isPermitted(permission)) {
    44                             hasAtLeastOnePermission = true;
    45                         }
    46                     }
    47                     if (!hasAtLeastOnePermission) {
    48                         this.getSubject().checkPermission(perms[0]);
    49                     }
    50                 }
    51             }
    52         }
    53     }
    54 }

    3.自定义Shiro拦截处理类,继承 AuthorizingAnnotationMethodInterceptor

     1 import org.apache.shiro.aop.AnnotationResolver;
     2 import org.apache.shiro.authz.aop.AuthorizingAnnotationMethodInterceptor;
     3 
     4 /**
     5  * SalmonPermissionAuthorizingAnnotationMethodInterceptor is
     6  *
     7  * @author zzt
     8  * @date 2020/2/25 11:44:00
     9  */
    10 public class SalmonPermissionAuthorizingAnnotationMethodInterceptor extends AuthorizingAnnotationMethodInterceptor {
    11 
    12     public SalmonPermissionAuthorizingAnnotationMethodInterceptor() {
    13         super(new SalmonPermissionAuthorizingAnnotationHandler());
    14     }
    15 
    16     public SalmonPermissionAuthorizingAnnotationMethodInterceptor(AnnotationResolver annotationResolver) {
    17         super(new SalmonPermissionAuthorizingAnnotationHandler(), annotationResolver);
    18     }
    19 }

    4.自定义AOP拦截,继承 AopAllianceAnnotationsAuthorizingMethodInterceptor

     1 import org.apache.shiro.spring.aop.SpringAnnotationResolver;
     2 import org.apache.shiro.spring.security.interceptor.AopAllianceAnnotationsAuthorizingMethodInterceptor;
     3 
     4 /**
     5  * SalmonPermissionAopAllianceAnnotationsAuthorizingMethodInterceptor is
     6  *
     7  * @author zzt
     8  * @date 2020/2/25 11:45:00
     9  */
    10 public class SalmonAopAllianceAnnotationsAuthorizingMethodInterceptor extends AopAllianceAnnotationsAuthorizingMethodInterceptor {
    11 
    12     public SalmonAopAllianceAnnotationsAuthorizingMethodInterceptor() {
    13         super();
    14         this.methodInterceptors.add(
    15                 new SalmonPermissionAuthorizingAnnotationMethodInterceptor(new SpringAnnotationResolver()));
    16     }
    17 }

    5.添加新注解支持,继承 AuthorizationAttributeSourceAdvisor

     1 import java.lang.annotation.Annotation;
     2 import java.lang.reflect.Method;
     3 
     4 import org.apache.shiro.authz.annotation.RequiresAuthentication;
     5 import org.apache.shiro.authz.annotation.RequiresGuest;
     6 import org.apache.shiro.authz.annotation.RequiresPermissions;
     7 import org.apache.shiro.authz.annotation.RequiresRoles;
     8 import org.apache.shiro.authz.annotation.RequiresUser;
     9 import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
    10 import org.springframework.core.annotation.AnnotationUtils;
    11 
    12 /**
    13  * SalmonPermissionAuthorizationAttributeSourceAdvisor is
    14  *
    15  * @author zzt
    16  * @date 2020/2/25 10:49:00
    17  */
    18 public class SalmonAuthorizationAttributeSourceAdvisor extends AuthorizationAttributeSourceAdvisor {
    19 
    20     private static final Class<? extends Annotation>[] AUTHZ_ANNOTATION_CLASSES =
    21             new Class[]{SalmonRequiresPermissions.class, RequiresPermissions.class, RequiresRoles.class,
    22                     RequiresUser.class, RequiresGuest.class, RequiresAuthentication.class};
    23 
    24     public SalmonAuthorizationAttributeSourceAdvisor() {
    25         setAdvice(new SalmonAopAllianceAnnotationsAuthorizingMethodInterceptor());
    26     }
    27 
    28     @Override
    29     public boolean matches(Method method, Class targetClass) {
    30         Method m = method;
    31         if (this.isAuthzAnnotationPresent(method)) {
    32             return true;
    33         } else {
    34             if (targetClass != null) {
    35                 try {
    36                     m = targetClass.getMethod(m.getName(), m.getParameterTypes());
    37                     return this.isAuthzAnnotationPresent(m) || this.isAuthzAnnotationPresent(targetClass);
    38                 } catch (NoSuchMethodException var5) {
    39                 }
    40             }
    41 
    42             return false;
    43         }
    44     }
    45 
    46     @SuppressWarnings("Duplicates")
    47     private boolean isAuthzAnnotationPresent(Class<?> targetClazz) {
    48         Class[] authzAnnotationClasses = AUTHZ_ANNOTATION_CLASSES;
    49 
    50         for (int i = 0; i < authzAnnotationClasses.length; ++i) {
    51             Class<? extends Annotation> annClass = authzAnnotationClasses[i];
    52             Annotation a = AnnotationUtils.findAnnotation(targetClazz, annClass);
    53             if (a != null) {
    54                 return true;
    55             }
    56         }
    57 
    58         return false;
    59     }
    60 
    61     @SuppressWarnings("Duplicates")
    62     private boolean isAuthzAnnotationPresent(Method method) {
    63         Class[] authzAnnotationClasses = AUTHZ_ANNOTATION_CLASSES;
    64 
    65         for (int i = 0; i < authzAnnotationClasses.length; ++i) {
    66             Class<? extends Annotation> annClass = authzAnnotationClasses[i];
    67             Annotation a = AnnotationUtils.findAnnotation(method, annClass);
    68             if (a != null) {
    69                 return true;
    70             }
    71         }
    72 
    73         return false;
    74     }
    75 }

    6.ShiroConfig添加配置,使用自定义 AuthorizationAttributeSourceAdvisor

    1   // 添加自定义注解支持
    2     @Bean
    3     public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(
    4             DefaultWebSecurityManager securityManager) {
    5         AuthorizationAttributeSourceAdvisor advisor = new SalmonAuthorizationAttributeSourceAdvisor();
    6         advisor.setSecurityManager(securityManager);
    7         return advisor;
    8     }

    参考文章:

    https://my.oschina.net/cloudcross/blog/1924116 基于shiro的自定义注解扩展

    https://blog.csdn.net/weixin_33909059/article/details/88856993 自定义Shiro注解

    https://blog.csdn.net/u013219624/article/details/83589863 shiro源码分析之自定义注解RequiredPermission(可代替RequiresPermissions)

    https://blog.csdn.net/xiewenfeng520/article/details/89447749 apache shiro框架@RequiresPermissions源码分析

  • 相关阅读:
    HDU 1124 Factorial
    hdu 1690 Bus System
    hdu 1113 Word Amalgamation
    POJ 2482 Stars in Your Window
    hdu 1385 ZOJ 1456 Minimum Transport Cost(经典floyd)
    hdu 1907 John
    VMware 虚拟机 安装 UBuntu 9.10 命令模式转换成窗口模试
    #pragma CODE_SEG __NEAR_SEG NON_BANKED详解
    Ubuntu 下Hadoop 伪分布式 hadoop0.20.2.tar.gz 的安装
    文件拷贝代码以及疑问
  • 原文地址:https://www.cnblogs.com/tarencez/p/12361765.html
Copyright © 2011-2022 走看看