资讯专栏INFORMATION COLUMN

自定义Shiro注解

褰辩话 / 3212人阅读

摘要:自定义注解顺序创建自定义的注解资源管理器,继承,添加新注解支持拦截器,继承方法拦截器,继承权限处理器,继承,校验权限一自定义注解二权限处理器自定义权限处理器多个权限,有一个就通过三方法拦截器自定义注解的方法拦截器验证权限四切面拦截器自定义注

自定义Shiro注解 顺序

创建自定义的注解

资源管理器,继承AuthorizationAttributeSourceAdvisor,添加新注解支持

AOP拦截器,继承AopAllianceAnnotationsAuthorizingMethodInterceptor

方法拦截器,继承AuthorizingAnnotationMethodInterceptor

权限处理器,继承AuthorizingAnnotationHandler,校验权限

一、自定义注解
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Permissions {
  String[] value();
}
二、权限处理器
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.aop.AuthorizingAnnotationHandler;
import org.apache.shiro.subject.Subject;

import java.lang.annotation.Annotation;

/**
 * 自定义权限处理器
 * @author BBF
 */
public class PermissionHandler extends AuthorizingAnnotationHandler {

  public PermissionHandler() {
    super(Permissions.class);
  }

  @Override
  public void assertAuthorized(Annotation a) throws AuthorizationException {
    if (a instanceof Permissions) {
      Permissions annotation = (Permissions) a;
      String[] perms = annotation.value();
      Subject subject = getSubject();

      if (perms.length == 1) {
        subject.checkPermission(perms[0]);
        return;
      }
      // 多个权限,有一个就通过
      boolean hasAtLeastOnePermission = false;
      for (String permission : perms) {
        if (subject.isPermitted(permission)) {
          hasAtLeastOnePermission = true;
          break;
        }
      }
      // Cause the exception if none of the role match,
      // note that the exception message will be a bit misleading
      if (!hasAtLeastOnePermission) {
        subject.checkPermission(perms[0]);
      }
    }
  }
}
三、方法拦截器
import org.apache.shiro.aop.AnnotationResolver;
import org.apache.shiro.aop.MethodInvocation;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.aop.AuthorizingAnnotationMethodInterceptor;

/**
 * 自定义注解的方法拦截器
 * @author BBF
 */
public class PermissionMethodInterceptor extends AuthorizingAnnotationMethodInterceptor {
  public PermissionMethodInterceptor() {
    super(new PermissionHandler());
  }

  public PermissionMethodInterceptor(AnnotationResolver resolver) {
    super(new PermissionHandler(), resolver);
  }

  @Override
  public void assertAuthorized(MethodInvocation mi) throws AuthorizationException {
    // 验证权限
    try {
      ((PermissionHandler) getHandler()).assertAuthorized(getAnnotation(mi));
    } catch (AuthorizationException ae) {
      // Annotation handler doesn"t know why it was called, so add the information here if possible.
      // Don"t wrap the exception here since we don"t want to mask the specific exception, such as
      // UnauthenticatedException etc.
      if (ae.getCause() == null) {
        ae.initCause(new AuthorizationException("Not authorized to invoke method: " + mi.getMethod()));
      }
      throw ae;
    }
  }
}
四、切面拦截器
import org.apache.shiro.spring.aop.SpringAnnotationResolver;
import org.apache.shiro.spring.security.interceptor.AopAllianceAnnotationsAuthorizingMethodInterceptor;

/**
 * 自定义注解的AOP拦截器
 * @author BBF
 */
public class PermissionAopInterceptor extends AopAllianceAnnotationsAuthorizingMethodInterceptor {
  public PermissionAopInterceptor() {
    super();
    // 添加自定义的注解拦截器
    this.methodInterceptors.add(new PermissionMethodInterceptor(new SpringAnnotationResolver()));
  }
}
五、注解拦截器
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.springframework.core.annotation.AnnotationUtils;

import java.lang.reflect.Method;

/**
 * 自定义的Shiro注解拦截器
 * @author BBF
 */

public class ShiroAdvisor extends AuthorizationAttributeSourceAdvisor {
  /**
   * Create a new AuthorizationAttributeSourceAdvisor.
   */
  public ShiroAdvisor() {
    // 这里可以添加多个
    setAdvice(new PermissionAopInterceptor());
  }

  @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) {
        //default return value is false.  If we can"t find the method, then obviously
        //there is no annotation, so just use the default return value.
      }
    }
    return super.matches(method, targetClass);
  }

  private boolean isFrameAnnotation(Method method) {
    return null != AnnotationUtils.findAnnotation(method, Permissions.class);
  }
}
六、配置shiro

替换AuthorizationAttributeSourceAdvisorShiroAdvisor

  /**
   * 启用注解拦截方式
   * @return AuthorizationAttributeSourceAdvisor
   */
  @Bean
  public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
    AuthorizationAttributeSourceAdvisor advisor = new ShiroAdvisor();
    advisor.setSecurityManager(securityManager());
    return advisor;
  }

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/69190.html

相关文章

  • 基于shiro定义注解的扩展

    摘要:的自身注解的用法。所以自定义注解的作用很广。但是在这里,我仅仅基于的来实现适用于它的自定义注解。其他的自定义的注解的编写思路和这个也是类似的。 基于shiro的自定义注解的扩展 根据我的上一篇文章,权限设计的杂谈中,涉及到了有关于前后端分离中,页面和api接口断开表与表层面的关联,另辟蹊径从其他角度找到方式进行关联。这里我们主要采取了shiro的自定义注解的方案。本篇文章主要解决以下的...

    YuboonaZhang 评论0 收藏0
  • Shiro【授权过滤器、与ehcache整合、验证码、记住我】

    摘要:为了达到很好的效果,我们使用来对的缓存进行管理配置会话管理器,对会话时间进行控制手动清空缓存由于验证用户名和密码之前,一般需要验证验证码的。 前言 本文主要讲解的知识点有以下: Shiro授权过滤器使用 Shiro缓存 与Ehcache整合 Shiro应用->实现验证码功能 记住我功能 一、授权过滤器测试 我们的授权过滤器使用的是permissionsAuthorization...

    K_B_Z 评论0 收藏0
  • 不用 Spring Security 可否?试试这个小而美的安全框架

    摘要:写在前面在一款应用的整个生命周期,我们都会谈及该应用的数据安全问题。用户的合法性与数据的可见性是数据安全中非常重要的一部分。 写在前面 在一款应用的整个生命周期,我们都会谈及该应用的数据安全问题。用户的合法性与数据的可见性是数据安全中非常重要的一部分。但是,一方面,不同的应用对于数据的合法性和可见性要求的维度与粒度都有所区别;另一方面,以当前微服务、多服务的架构方式,如何共享Sessi...

    toddmark 评论0 收藏0
  • shiro入门笔记

    摘要:当前可以是身份,不需要经过认证或者在原先的中存在记录。当前必须拥有所有指定的角色时,才能访问被该注解标注的方法。 关于 Apache Shiro 概念基本都粘自官网 http://shiro.apache.org/详细中文博客 http://wiki.jikexueyuan.com/p...与SpringBoot整合 https://segmentfault.com/a/11... ...

    yagami 评论0 收藏0
  • apache shiro框架

    摘要:框架提供的接口,是的核心,代表安全管理器对象。可以开发人员编写,框架也提供一些。在中作为应用程序和安全数据之间的桥梁或连接器。例如要求中必须同时含有和的权限才能执行方法。 apache shiro框架简介  Apache Shiro是一个强大而灵活的开源安全框架,它能够干净利落地处理身份认证,授权,企业会话管理和加密。现在,使用Apache Shiro的人越来越多,因为它相当简单,相比比Sp...

    Tecode 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<