当前位置: 首页 > 编程笔记 >

spring aop实现用户权限管理的示例

颛孙玉石
2023-03-14
本文向大家介绍spring aop实现用户权限管理的示例,包括了spring aop实现用户权限管理的示例的使用技巧和注意事项,需要的朋友参考一下

AOP 在实际项目中运用的场景主要有 权限管理(Authority Management)、事务管理(Transaction Management)、安全管理(Security)、日志管理(Logging)和调试管理(Debugging) 等。

问题源于项目开发

最近项目中需要做一个权限管理模块,按照之前同事的做法是在controller层的每个接口调用之前上做逻辑判断,这样做也没有不妥,但是代码重复率太高,而且是体力劳动,so,便有了如题所说的使用spring aop做一个切点来实现通用功能的权限管理,这样也就降低了项目后期开发的可扩展性。

权限管理的代码实现与配置文件

在最小的代码修改程度上,aop无疑是最理想的选择。项目中有各种权限的复合,相对来说逻辑复杂度比较高,所以一步步来。因为权限涉及到的是后端接口的调用所以楼主选择在controller层代码做切面,而切点就是controller中的各个方法块,对于通用访问权限,我们使用execution表达式进行排除。

只读管理员权限的实现及切点选择

对于实现排除通用的controller,楼主采用的是execution表达式逻辑运算。因为只读管理员拥有全局读权限,而对于增删改权限,楼主采用的是使用切点切入是增删改的方法,so,这个时候规范的方法命名就很重要了。对于各种与只读管理员进行复合的各种管理员,我们在代码中做一下特殊判断即可。下面是spring aop的配置文件配置方法。

<bean id="usersPermissionsAdvice"
     class="com.thundersoft.metadata.aop.UsersPermissionsAdvice"/>
  <aop:config>
    <!--定义切面 -->
    <aop:aspect id="authAspect" ref="usersPermissionsAdvice">
      <!-- 定义切入点 (配置在com.thundersoft.metadata.web.controller下所有的类在调用之前都会被拦截) -->
      <aop:pointcut
          expression="(execution(* com.thundersoft.metadata.web.controller.*.add*(..)) or
          execution(* com.thundersoft.metadata.web.controller.*.edit*(..)) or
          execution(* com.thundersoft.metadata.web.controller.*.del*(..)) or
          execution(* com.thundersoft.metadata.web.controller.*.update*(..)) or
          execution(* com.thundersoft.metadata.web.controller.*.insert*(..)) or
          execution(* com.thundersoft.metadata.web.controller.*.modif*(..))) or
          execution(* com.thundersoft.metadata.web.controller.*.down*(..))) and (
          !execution(* com.thundersoft.metadata.web.controller.FindPasswordController.*(..)) and
          !execution(* com.thundersoft.metadata.web.controller.SelfServiceController.*(..)) and
          !execution(* com.thundersoft.metadata.web.controller.HomeController.*(..)) and
          !execution(* com.thundersoft.metadata.web.controller.UserStatusController.*(..)) and
          !execution(* com.thundersoft.metadata.web.controller.DashboardController.*(..)) and
          !execution(* com.thundersoft.metadata.web.controller.MainController.*(..))))"
          id="authPointCut"/>
      <!--方法被调用之前执行的 -->
      <aop:before method="readOnly"
            pointcut-ref="authPointCut"/>
    </aop:aspect>
  </aop:config>

只读管理员权限管理代码实现

上面说了那么多,废话不多说了,下面是对只读权限与各种复合权限进行控制的切面代码实现。

/**
   * 对只读管理员以及其复合管理员进行aop拦截判断.
   * @param joinPoint 切入点.
   * @throws IOException
   */
  public void readOnly(JoinPoint joinPoint) throws IOException {

    /**
     * 获取被拦截的方法.
     */
    String methodName = joinPoint.getSignature().getName();

    /**
     * 获取被拦截的对象.
     */
    Object object = joinPoint.getTarget();
    logger.info("权限管理aop,方法名称" + methodName);
    HttpServletRequest request =((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    HttpServletResponse response =((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
    String roleFlag = GetLoginUserInfor.getLoginUserRole(request);

    /**
     * 超级管理员
     */
    if (PermissionsLabeled.super_Admin.equals(roleFlag)) {
      return;
    }

    /**
     * 只读管理员做数据更改权限的判断
     */
    if (PermissionsLabeled.reader_Admin.equals(roleFlag)) {
      logger.error("只读管理员无操作权限!");
      response.sendRedirect(request.getContextPath() + "/auth/readOnly");
    }

    /**
     * 部门管理员,且为只读管理员,
     */
    if (PermissionsLabeled.dept_reader_Admin.equals(roleFlag)) {
      if (object instanceof DepartmentController) {
        return;
      }
      if (object instanceof UserController) {
        if (methodName.contains("addAdmin")) {
          response.sendRedirect(request.getContextPath() + "/auth/readOnly");
        }
        if (methodName.contains("deleteAdmin")) {
          response.sendRedirect(request.getContextPath() + "/auth/readOnly");
        }
        if (methodName.contains("updateAdmin")) {
          response.sendRedirect(request.getContextPath() + "/auth/readOnly");
        }
        return;
      }
      if (object instanceof GroupController) {
        return;
      }
      logger.error("部门管理员,且为只读管理员无操作权限!");
      response.sendRedirect(request.getContextPath() + "/auth/readOnly");
    }

    /**
     * 应用管理员,且为只读管理员
     */
    if (PermissionsLabeled.app_reader_Admin.equals(roleFlag)) {
      if (object instanceof AppController) {
        return;
      }
      if (object instanceof AppPolicyController) {
        return;
      }
      logger.error("应用管理员,且为只读管理员无操作权限!");
      response.sendRedirect(request.getContextPath() + "/auth/readOnly");
    }

    /**
     * 部门管理员,且为应用管理员,且为只读管理员
     */
    if (PermissionsLabeled.dept_app_reader_Admin.equals(roleFlag)) {
      if (object instanceof DepartmentController) {
        return;
      }
      if (object instanceof UserController) {
        return;
      }
      if (object instanceof GroupController) {
        return;
      }
      if (object instanceof AppController) {
        return;
      }
      if (object instanceof AppPolicyController) {
        return;
      }
      logger.error("部门管理员,且为应用管理员,且为只读管理员无操作权限");
      response.sendRedirect(request.getContextPath() + "/auth/readOnly");
    }
  }

具有专门功能的管理员权限控制的切点选择

因为具有专门的管理员权限比较特殊,楼主采用的方式除了通用访问权限之外的controller全切,特殊情况在代码逻辑里面做实现即可。配置文件代码如下:

<aop:config>
    <!--定义切面 -->
    <aop:aspect id="authAspect" ref="usersPermissionsAdvice">
      <!-- 定义切入点 (配置在com.thundersoft.metadata.web.controller下所有的类在调用之前都会被拦截) -->
      <aop:pointcut
          expression="(execution(* com.thundersoft.metadata.web.controller.*.*(..)) and (
          !execution(* com.thundersoft.metadata.web.controller.FindPasswordController.*(..)) and
          !execution(* com.thundersoft.metadata.web.controller.SelfServiceController.*(..)) and
          !execution(* com.thundersoft.metadata.web.controller.HomeController.*(..)) and
          !execution(* com.thundersoft.metadata.web.controller.UserStatusController.*(..)) and
          !execution(* com.thundersoft.metadata.web.controller.DashboardController.*(..)) and
          !execution(* com.thundersoft.metadata.web.controller.MainController.*(..))))"
          id="appAuthPointCut"/>
      <!--方法被调用之前执行的 -->
      <aop:before method="appDeptAuth"
            pointcut-ref="appAuthPointCut"/>
    </aop:aspect>
  </aop:config>

##权限管理的切面代码实现

/**
   * 对应用管理员以及部门管理员进行aop拦截判断.
   * @param joinPoint 切入点.
   * @throws IOException
   */
  public void appDeptAuth(JoinPoint joinPoint) throws IOException {
    /**
     * 获取被拦截的方法.
     */
    String methodName = joinPoint.getSignature().getName();

    /**
     * 获取被拦截的对象.
     */
    Object object = joinPoint.getTarget();
    logger.info("权限管理aop,方法名称",methodName);
    HttpServletRequest request =((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    HttpServletResponse response =((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
    String roleFlag = GetLoginUserInfor.getLoginUserRole(request);

    /**
     * 超级管理员
     */
    if (PermissionsLabeled.super_Admin.equals(roleFlag)) {
      return;
    }

    /**
     * 应用管理员做数据更改权限的判断
     */
    if (PermissionsLabeled.app_Admin.equals(roleFlag)) {
      if (object instanceof AppController) {
        return;
      }
      if (object instanceof AppPolicyController) {
        return;
      }
      logger.error("应用管理员无操作权限");
      response.sendRedirect(request.getContextPath() + "/auth/readOnly");
    } else if (PermissionsLabeled.dept_Admin.equals(roleFlag)) {
      if (object instanceof DepartmentController) {
        return;
      }
      if (object instanceof UserController) {
        return;
      }

      if (object instanceof GroupController) {
        return;
      }
      if ("getAllDepartments".equals(methodName)) {
        return;
      }
      logger.error("应用管理员无操作权限");
      response.sendRedirect(request.getContextPath() + "/auth/readOnly");
    } else {
      return;
    }
  }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。

 类似资料:
  • 本文向大家介绍Spring security实现权限管理示例,包括了Spring security实现权限管理示例的使用技巧和注意事项,需要的朋友参考一下 Spring security实现权限管理示例,具体如下: 1、配置文件 1、POM.xml 2.web.xml 3.application-security.xml 4. applicationContext.xml 5.applicatio

  • 本文向大家介绍权限管理如何实现?相关面试题,主要包含被问及权限管理如何实现?时的应答技巧和注意事项,需要的朋友参考一下 1)前端控制: 前端的控制比较简单,从后台获取到用户的权限之后,可以存在session或者cookie中,然后在页面加载的时候,通过session或者cookie中存的权限来选择让该功能展现或者禁用。 前端实现代码详细参见:http://blog.csdn.net/liuweid

  • 本文向大家介绍springAop实现权限管理数据校验操作日志的场景分析,包括了springAop实现权限管理数据校验操作日志的场景分析的使用技巧和注意事项,需要的朋友参考一下 前言 作为一个写java的使用最多的轻量级框架莫过于spring,不管是老项目用到的springmvc,还是现在流行的springboot,都离不开spring的一些操作,我在面试的时候问的最多的spring的问题就是我们在

  • 主要内容:一、用户管理,二、权限管理,三、权限表,四、角色管理一、用户管理 1.创建用户 用户名参数表示新建用户的账户,由用户(User) 和主机名(Host) 构成,默认host为'%',表示所有主机(ip)都可登录,也可以使用如'lxc'@'192.168.%.%'的形式 可以不指定用户密码,无需密码登录; 2.查看用户 3.修改用户 4.删除用户 1.使用DROP USER语句来删除用户时,必须用于DROP USER权限。DROP USER语句的基本语

  • 本文向大家介绍MySQL用户权限管理详解,包括了MySQL用户权限管理详解的使用技巧和注意事项,需要的朋友参考一下 用户权限管理主要有以下作用: 1. 可以限制用户访问哪些库、哪些表 2. 可以限制用户对哪些表执行SELECT、CREATE、DELETE、DELETE、ALTER等操作 3. 可以限制用户登录的IP或域名 4. 可以限制用户自己的权限是否可以授权给别的用户 一、用户授权  •all

  • 本文向大家介绍SpringBoot中整合Shiro实现权限管理的示例代码,包括了SpringBoot中整合Shiro实现权限管理的示例代码的使用技巧和注意事项,需要的朋友参考一下 之前在 SSM 项目中使用过 shiro,发现 shiro 的权限管理做的真不错,但是在 SSM 项目中的配置太繁杂了,于是这次在 SpringBoot 中使用了 shiro,下面一起看看吧 一、简介 Apache Sh