zoukankan      html  css  js  c++  java
  • Java权限管理(授权与认证)

    CRM权限管理

    有兴趣的同学也可以阅读我最近分享的:Shiro框架原理分析   (PS : 这篇博客里面介绍了使用Shiro框架的方式实现权限管理)

    https://www.cnblogs.com/yly-blog/p/9837384.html 

    如果发现分享的内容有不合理或者的不对地方,请留言,我会及时定位分析,感谢!!!

    一、概念

    权限管理就是管理用户对于资源的操作。本 CRM 系统的权限(也称作资源)是基于角色操作权限来实现的,即RBAC(Role-Based Access Control,基于角色的访问控制),就是用户通过角色与权限进行关联。简单地说,一个用户拥有若干角色,每一个角色拥有若干权限。这样,就构造成“用户-角色-权限”的授权模型。在这种模型中,用户与角色之间,角色与权限之间都是多对多的关系,为了实现表之间多对多的关系,必须将一个多对多的关系通过一个中间表分为两个一对多的关系。因此引入中间表,用户角色表和角色权限表。

    二、数据库

    权限管理模块一共涉及五张表

    1. 三张主表

        a)       用户表(t_user)、

        b)       角色表(t_role)、

        c)       资源表(t_module)、

             2.两张中间表

        a)       用户角色表(t_user_role)、

        b)       角色—资源表(t_permission)、

     

     

    三、权限管理实现

     

    1、模块、角色、用户的单表CRUD

      模块CRUD:操作t_module表

     

      角色CRUD:操作t_role表

     

      用户CRUD:操作t_role表

     

    2、授权

    角色赋予权限

      给角色赋予权限:使用ztree进行权限树结构的构建

                         a)赋权限

                                 1、先把本模块绑定;

            2、绑定父模块;

            3、绑定子模块

                         b)删权限

                                 1、先删除本模块;

            2、删除子模块;

            3、删除父模块(判断父模块是否有其他的子模块关联词角色,如果没有就取消,如果有就关联)

    a)       使用jQuery的插件zTree构建一个资源的树结构,树中的内容为表t_module中的数据

     

     

    b)       用鼠标点击zTree中的选择框操作表t_permission(角色资源表)实现给角色赋予权限

     

    用户赋予角色

      给用户赋予角色:使用的combobox多选

                         a).添加账号:直接往t_user_role插入记录

                         b).修改账号:先删除,在添加

    创建用户或者是修改用户信息时都可以通过combobox多选框给用户赋予角色操作t_user_role(用户角色表)

     

    3、认证

    思路:

      从t_permission表中获取权限值(acl_value)与页面传来的值或者与注解中明确的权限值比较,下面提供两种思路:

        1.页面传递过来Request.getParameter(“permission”);比对 根据userId查询数据库查到的权限列表  contains

        2.通过注解明确模块权限值:@requirePermission(permission=”1010”;

    后台认证:Spring AOP和自定义注解实现认证

      获取用户权限存入session,然后用户操作资源时会提交一个资源的权限值,在判断用户是否包含有此权限

      使用Spring AOP进行拦截认证

                     第一步:开启注解驱动<aop:aspectj-autoproxy />

                     第二步:创建一个代理类使用@Aspect @Component注解进行标记

                     第三步:定义一个切入点@Pointcut(" *execution('com.shsxt.controller.*.*((..))')")

                                               public void pointcut() {}

                     第四步:编写一个增强:@Around(value="pointcut()")

                            1.判定用户是否登录

                            2.获取用户权限

                            3.将权限存入session--》给前端页面判断

                            4.后台的权限校验

                            5.返回

    1. 自定义注解

     

             2.编写切面类

    定义切入点point:自拦截有权限注解的方法,更能提升性能

    //@Pointcut("execution(* com.shsxt.controller.*.*(..))")
    
        @Pointcut("@annotation(com.shsxt.annotation.RequirePermissions)")
    
        public void pointcut() {
    
          
    
        }

    通过前台传递permission参数实现: 

    List<String> permissions = permissionService.findRolePermissions(roleIds.substring(0, roleIds.lastIndexOf(",")));
    
           String permissioFront = request.getParameter("permission"); // 后台权限认证
    
           AssertUtil.isTrue(!permissions.contains(permissioFront), "您无权操作此模块");

    通过注解实现

    List<String> permissions = permissionService.findRolePermissions(roleIds.substring(0, roleIds.lastIndexOf(",")));
    
           if (requirePermissions != null) {
    
               String permission = requirePermissions.permission(); // 后台权限认证
    
               throw new UnAuthPermissionException(permission, "您无权操作此模块");
    
           }

            3.引入AOP的namepsace并开启AOP注解驱动

     

    <!-- 启用@Aspect注解 -->
    
    <aop:aspectj-autoproxy />

            4.在需要权限认证的方法上启用注解 

     

    Permission应该和module表中的act_value保持一致

    前台认证:Freemarker 内建函数判断

    获取用户权限后在前端的freemarker中利用freemarker语法去判断用户是否能够操作此资源(list?seq_contains('权限值'))

    1.SQL:

    SELECT
    
           DISTINCT p.acl_value
    
    FROM
    
           t_permission p
    
    -- LEFT JOIN t_role r ON r.id = ur.role_id
    
    left JOIN t_user_role ur on p.role_id = ur.role_id
    
    WHERE
    
           ur.user_id = 10;


    2.在AOP切面类中查询permission取出权限值列表、放入Session

     

    3.前台页面判断: 解释:利用freemarker 内建函数sql_contains判断序列是否包含参数值,包含返回true

    类似于java中集合hashmap.contains(value);

     

     

  • 相关阅读:
    第二阶段个人博客八
    第二阶段个人博客七
    第二阶段个人博客六
    第二阶段个人博客五
    第二阶段个人博客四
    第十五周学习进度表
    如何选择合适的图表类型
    参加技术会议的一些小窍门
    提高Scrum站会效率的一个小工具
    用6个字符写出任意的Javascript代码
  • 原文地址:https://www.cnblogs.com/yly-blog/p/7283541.html
Copyright © 2011-2022 走看看