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;
    }
  }

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

(0)

相关推荐

  • Spring AOP实现功能权限校验功能的示例代码

    实现功能权限校验的功能有多种方法,其一使用拦截器拦截请求,其二是使用AOP抛异常. 首先用拦截器实现未登录时跳转到登录界面的功能.注意这里没有使用AOP切入,而是用拦截器拦截,因为AOP一般切入的是service层方法,而拦截器是拦截控制器层的请求,它本身也是一个处理器,可以直接中断请求的传递并返回视图,而AOP则不可以. 1.使用拦截器实现未登录时跳转到登录界面的功能 1.1 拦截器SecurityInterceptor package com.jykj.demo.filter; import

  • Java之Spring AOP 实现用户权限验证

    每个项目都会有权限管理系统 无论你是一个简单的企业站,还是一个复杂到爆的平台级项目,都会涉及到用户登录.权限管理这些必不可少的业务逻辑.有人说,企业站需要什么权限管理阿?那行吧,你那可能叫静态页面,就算这样,但你肯定也会有后台管理及登录功能. 每个项目中都会有这些几乎一样的业务逻辑,我们能不能把他们做成通用的系统呢? AOP 实现用户权限验证 AOP 在实际项目中运用的场景主要有权限管理(Authority Management).事务管理(Transaction Management).安全管

  • spring aop 拦截业务方法,实现权限控制示例

    难点:aop类是普通的java类,session是无法注入的,那么在有状态的系统中如何获取用户相关信息呢,session是必经之路啊,获取session就变的很重要.思索很久没有办法,后来在网上看到了解决办法. 思路是: i. SysContext  成员变量 request,session,response ii. Filter 目的是给 SysContext 中的成员赋值 iii.然后在AOP中使用这个SysContext的值 要用好,需要理解  ThreadLocal和  和Filter

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

    AOP 在实际项目中运用的场景主要有 权限管理(Authority Management).事务管理(Transaction Management).安全管理(Security).日志管理(Logging)和调试管理(Debugging) 等. 问题源于项目开发 最近项目中需要做一个权限管理模块,按照之前同事的做法是在controller层的每个接口调用之前上做逻辑判断,这样做也没有不妥,但是代码重复率太高,而且是体力劳动,so,便有了如题所说的使用spring aop做一个切点来实现通用功能的

  • SpringBoot2.0整合Shiro框架实现用户权限管理的示例

    GitHub源码地址:知了一笑 https://github.com/cicadasmile/middle-ware-parent 一.Shiro简介 1.基础概念 Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码和会话管理.作为一款安全框架Shiro的设计相当巧妙.Shiro的应用不依赖任何容器,它不仅可以在JavaEE下使用,还可以应用在JavaSE环境中. 2.核心角色 1)Subject:认证主体 代表当前系统的使用者,就是用户,在Shiro的认证中,

  • SpringBoot中整合Shiro实现权限管理的示例代码

    之前在 SSM 项目中使用过 shiro,发现 shiro 的权限管理做的真不错,但是在 SSM 项目中的配置太繁杂了,于是这次在 SpringBoot 中使用了 shiro,下面一起看看吧 一.简介 Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码和会话管理.使用Shiro的易于理解的API,您可以快速.轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序. 三个核心组件: 1.Subject 即"当前操作用户".但是,在 Shi

  • PHP实现权限管理功能示例

    权限管理系统,它主要是为了给不同的用户设定不同的权限,从而实现不同权限的用户登录之后使用的功能不一样. 首先先看下数据库 总共有5张表,users,roles和roleswork 3张表与另外2张表形成"w"型的关系,也是比较常见的一种权限数据库的方式,首先先做权限的设定,也就是管理层给不同用户设定不同权限. 1.管理员页面RBAC.php <!DOCTYPE html> <html> <head> <meta charset="UT

  • java web实现用户权限管理

    最近在做一个网站类型项目,主要负责后台,ui框架选型为jquery easy ui,项目架构为spring mvc + spring jdbc,简单易用好上手!搭建好框架后开始了第一个任务,设计并实现一套简单的权限管理功能. 一套最基本的权限管理包括用户.角色.资源. 实现效果: 数据库设计,设计如下: 用户:user 角色:role 用户-角色:user_role 资源:resource(包括上级菜单.子菜单.按钮等资源) 角色-资源:role_resource 标准的权限管理系统设计为以上5

  • 详解MySQL 用户权限管理

    前言: 不清楚各位同学对数据库用户权限管理是否了解,作为一名 DBA ,用户权限管理是绕不开的一项工作内容.特别是生产库,数据库用户权限更应该规范管理.本篇文章将会介绍下 MySQL 用户权限管理相关内容. 1.用户权限简介 当我们创建过数据库用户后,还不能执行任何操作,需要为该用户分配适当的访问权限. 关于 MySQL 用户权限简单的理解就是数据库只允许用户做你权利以内的事情,不可以越界.比如只允许你执行 select 操作,那么你就不能执行 update 操作.只允许你从某个 IP 上连接

  • Mysql 用户权限管理实现

    1. MySQL 权限介绍 mysql中存在4个控制权限的表,分别为user表,db表,tables_priv表,columns_priv表,我当前的版本mysql 5.7.22 . mysql权限表的验证过程为: 先从user表中的Host,User,Password这3个字段中判断连接的ip.用户名.密码是否存在,存在则通过验证. 通过身份认证后,进行权限分配,按照user,db,tables_priv,columns_priv的顺序进行验证.即先检查全局权限表user,如果user中对应的

  • MySQL数据库用户权限管理

    目录 1.用户管理 1.1.创建用户 1.2.删除用户 1.3.修改用户密码 2.权限管理 2.1.授予权限 grant 2.2.取消权限 revoke 2.3.刷新权限 flush 3.密码丢失的解决方案 1.用户管理 mysql的用户信息保存在了mysql.user中: select * from mysql.user\G *************************** 5. row *************************** Host: localhost User:

  • MySQL用户权限管理详解

    用户权限管理主要有以下作用: 1. 可以限制用户访问哪些库.哪些表 2. 可以限制用户对哪些表执行SELECT.CREATE.DELETE.DELETE.ALTER等操作 3. 可以限制用户登录的IP或域名 4. 可以限制用户自己的权限是否可以授权给别的用户 一.用户授权 复制代码 代码如下: mysql> grant all privileges on *.* to 'yangxin'@'%' identified by 'yangxin123456' with grant option;  

随机推荐