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源码分析

  • 相关阅读:
    log4net保存到数据库系列三、代码中xml配置log4net
    log4net保存到数据库系列二:独立配置文件中配置log4net
    log4net保存到数据库系列一:WebConfig中配置log4net
    SSIS SQLServer增量抽取至Cassandra 性能优化及踩坑
    从SVN资源库下载项目
    右键tomcat找不到项目:There are no resources that can be added or removed from the server.
    MVC模式:action、dao、model、service、util
    隐藏按钮button
    Navicat for mysql导入.sql数据库大小受限制
    MySQL数据库错误号:2003
  • 原文地址:https://www.cnblogs.com/tarencez/p/12361765.html
Copyright © 2011-2022 走看看