通用数据级别权限的框架设计与实现(3)-数据列表的权限过滤

简介: 查看上篇文章通用数据级别权限的框架设计与实现(2)-数据权限的准备工作,我们开始数据列表的权限过滤.原理:我们在做过滤列表时,根据用户权限自动注入到相关SQL中,实现相关过滤,如果拥有全部权限,则不生成相关SQL片段首先我们来分析一下数据列表的SQL能看到所有数据的SQLSELECT role.

查看上篇文章通用数据级别权限的框架设计与实现(2)-数据权限的准备工作,我们开始数据列表的权限过滤.
原理:我们在做过滤列表时,根据用户权限自动注入到相关SQL中,实现相关过滤,如果拥有全部权限,则不生成相关SQL片段

  1. 首先我们来分析一下数据列表的SQL
  • 能看到所有数据的SQL
SELECT
    role.id,
    role. CODE,
    role. NAME
FROM
    sys_auth_role role
where 1=1
  • 根据登陆角色,看到的数据的SQL
-SELECT
    role.id,
    role. CODE,
    role. NAME
FROM
    sys_auth_role role
LEFT JOIN sys_auth_role_org_rel ror ON ror.role_id = role.id
WHERE
    1 = 1
AND ror.org_id IN (123, 123456)

两者分析,差异是表的关联,及查询的条件。我们因些通过配置来生成具体的相关SQL片段

@Data
public class AuthFiledFilter {
    /**
     * 默认左连接
     */
    private String tableRel = "left join ";
    /**
     * 关联table名称
     */
    private String salveTableName;
    /**
     * 关联table别名
     */
    private String salveTableOtherName;
    /**
     * 关联table字段
     */
    private String salveTableField;

    /**
     * 主表别名
     */
    private String masterTableOtherName;
    /**
     * 默认主表关联字段
     */
    private String masterTableField = "id";

    /**
     * 查找用户ID
     */
    private String searchUserField;

    /**
     * 获取相关的关联SQL
     *
     * @return
     */
    public String getSqlRel() {
        StringBuilder sb = new StringBuilder();
        //增加一个空格,防止与主表靠得太近
        sb.append(" ");
        //sb.append(this.getMasterTableOtherName());
        sb.append(" ");
        sb.append(this.getTableRel());
        sb.append(" ");
        sb.append(this.getSalveTableName()).append("  ").append(this.getSalveTableOtherName());
        sb.append(" on ").append(this.getSalveTableOtherName()).append(".").append(this.getSalveTableField()).append("=").append(this.getMasterTableOtherName()).append(".").append(this.getMasterTableField());
        return sb.toString();
    }

    public  String getCondictionSqlIn(List userList) {

        StringBuilder sb = new StringBuilder();
        sb.append(" and ");
        sb.append(this.buildLogicIN(this.getSalveTableOtherName() + "." + this.getSearchUserField(), userList));
        return sb.toString();
    }

    public  String getCondictionSqlEq(Object userId) {

        StringBuilder sb = new StringBuilder();
        sb.append(" and ");
        sb.append(this.getSalveTableOtherName() + "." + this.getSearchUserField()).append("=").append(userId);
        return sb.toString();
    }

    /**
     * 构造in语句,若valueList超过1000时,该函数会自动拆分成多个in语句
     *
     * @param item
     * @param valueList
     * @return item in (valueList)
     */
    public String buildLogicIN(String item, List valueList) {
        int n = (valueList.size() - 1) / 1000;
        StringBuffer rtnStr = new StringBuffer();
        Object obj = valueList.get(0);
        boolean isString = false;
        if (obj instanceof Character || obj instanceof String)
            isString = true;
        String tmpStr;
        for (int i = 0; i <= n; i++) {
            int size = i == n ? valueList.size() : (i + 1) * 1000;
            if (i > 0)
                rtnStr.append(" or ");
            rtnStr.append(item + " in (");
            if (isString) {
                StringBuffer tmpBuf = new StringBuffer();
                for (int j = i * 1000; j < size; j++) {
                    tmpStr = valueList.get(j).toString().replaceAll("'", "''");
                    tmpBuf.append(",'").append(tmpStr).append("'");
                }
                tmpStr = tmpBuf.substring(1);
            } else {
                tmpStr = valueList.subList(i * 1000, size).toString();
                tmpStr = tmpStr.substring(1, tmpStr.length() - 1);
            }
            rtnStr.append(tmpStr);
            rtnStr.append(")");
        }
        if (n > 0)
            return "(" + rtnStr.toString() + ")";
        else
            return rtnStr.toString();
    }
    }

上述类中,生成的SQL片段方法为getSqlRel,getCondictionSqlIn,getCondictionSqlEq方法。
2.我们来生成各种权限校验的规则,Key用类的对象来实现


/**
 * @description: 权限的全局配置
 * @author: starmark
 * @create: 2018-05-17 16:22
 **/
public class AuthConfig {
    //全局校验数据规则
    public static Map<String,AuthValidatorModel> authMap=new HashMap();

    /**
     * 增加权限校验对象
     * @param authValidatorModel
     */
    public static void add(AuthValidatorModel authValidatorModel){
        authMap.put(authValidatorModel.classModel,authValidatorModel);
    }

    /**
     *获取权限校验规则
     * @param classModel
     * @return
     */
    public static AuthValidatorModel get(String classModel){
        return authMap.get(classModel);
    }
}

在service类初始化时,将权限规则注入进去

public class SysAuthRoleServiceImpl   implements ISysAuthRoleService,InitializingBean {...
 /**
     * 初始化权限校验模型
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        AuthValidatorModel authValidatorModel=new AuthValidatorModel(SysAuthRole.class.getName());
        //角色user1与角色user2能看到所有数据
         authValidatorModel.getRoles().add("user1");
         authValidatorModel.getRoles().add("user2");
        //构造关联查询的对象
        AuthFiledFilter authFiledFilter=new AuthFiledFilter();
        //主表别名
        authFiledFilter.setMasterTableOtherName("role");
        //从表表名
        authFiledFilter.setSalveTableName("sys_auth_role_org_rel");
        //从表另名
        authFiledFilter.setSalveTableOtherName("ror");
        //关联字段
        authFiledFilter.setSalveTableField("role_id");
        //查找用户字段接口
        authFiledFilter.setSearchUserField("org_id");
        authValidatorModel.setAuthFiledFilter(authFiledFilter);
        AuthConfig.add(authValidatorModel);

    }
    }

上述初始化了权限校验的规则及关联字段,判断拥有角色user1及user2的能看到全部数据,其他要做过滤.

  1. 数据列表的mapper方法改造为如下:
 <select id="list" resultMap="BaseResultMap">
        select role.id,role.code,role.name
        from sys_auth_role role
        <if test="authModel != null">
            ${authModel.relSql}
        </if>
        where
        1=1
        <if test="authModel != null">
            ${authModel.condictionSql}
        </if>
    </select>
  1. 权限列表的生成authModel方法如下:

/**
 * @description: 校验工具类
 * @author: starmark
 * @create: 2018-05-17 21:24
 **/
public class AuthValidatorUtil {

    public static AuthModel getAuthModel(String classModel, boolean isIn) {
        AuthValidatorModel authValidatorModel = AuthConfig.get(classModel);
        if (authValidatorModel == null) {
            return null;
        }
        boolean isAuth = authValidatorModel.getRoles().stream().anyMatch(role -> UserUtil.containRole(role));
        if (isAuth) {
            return null;
        }
        AuthModel authModel = new AuthModel();
        authModel.setRelSql(authValidatorModel.getAuthFiledFilter().getSqlRel());
        if (isIn) {
            authModel.setCondictionSql(authValidatorModel.getAuthFiledFilter().getCondictionSqlIn(UserUtil.getOrgIds()));

        } else {
            authModel.setCondictionSql(authValidatorModel.getAuthFiledFilter().getCondictionSqlEq(UserUtil.getUserId()));
        }
        return authModel;
    }
}

上述该工具类用于做判断,看是否需要生成相关SQL

  1. 权限过滤调用的方法改写成如下:
    /**
     * 权限过滤查找相关角色
     * @return
     */
    public List<SysAuthRole> list(){
        AuthModel authModel= AuthValidatorUtil.getAuthModel(SysAuthRole.class.getName(),true);
      return   authRoleMapper.list(authModel);
    }

至此,我们列表权限过滤的架子已经搭建完成.

个人代码已经完成,如需要请打赏后通知我。谢谢.
如果你觉得该文章对你有帮助,麻烦点赞。
欢迎继续查看下篇文章-通用数据级别权限的框架设计与实现(4)-单条记录的权限控制

相关文章
|
存储 开发框架 前端开发
ModStartCMS v5.5.0 页面标签支持,用户逻辑优化
ModStart 是一个基于 Laravel 模块化极速开发框架。模块市场拥有丰富的功能应用,支持后台一键快速安装,让开发者能快的实现业务功能开发。
【自然框架】之通用权限(八):权限到字段(列表、表单、查询)
 通用权限想要写的文章目录:(这是第八章)   1、 简介、数据库的总体结构2、 介绍人员表组3、 介绍组织结构表组4、 介绍角色表组5、 介绍“项目自我描述表组”6、 权限到节点7、 权限到按钮8、 权限到列表(表单、查询)9、 权限的验证10、 资源方面的权限11、 角色管理的程序(给客户用的)12、 权限下放13、 个性化设置A、 【自然框架】之通用权限(外传):杂谈     列表 myGrid 先说一下myGrid,我会根据Manage_FunListCol表和Manage_Columns表的内容,绘制出来一个table,就是的HTML。
928 0
“关联表单”组件文本数据筛选只支持包含条件的解决方案
在“关联表单”中使用数据筛选功能筛选文本时条件只有”包含“,此文章通过增加一个”下拉单选“组件,变相解决这个问题。
214 0
|
SQL 缓存 Java
hibernate(八) Hibernate检索策略(类级别,关联级别,批量检索)详解
很多看起来很难的东西其实并不难,关键是看自己是否花费了时间和精力去看,如果一个东西你能看得懂,同样的,别人也能看得懂,体现不出和别人的差距,所以当你觉得自己看了很多书或者学了很多东西的时候,你要想想,你花费的也就那么一点时间,别人花你这么多时间也能够学到你所学到的东西,所以还是要继续努力。既然不是天才,唯有靠勤奋来弥补。
204 0
|
数据安全/隐私保护
通用数据级别权限的框架设计与实现
个人花了不到2天时间,写了一个通用数据级别权限的框架设计与实现。 欢迎提意见及评论。有空请打赏! 通用数据级别权限的框架设计与实现(1)-相关业务场景的分析 通用数据级别权限的框架设计与实现(2)-数据权限的准备工作 通用数据级别权限的框架设计与实现(3)-数据列表的权限过滤 通用数据级别权限的框架设计与实现(4)-单条记录的权限控制 通用数据级别权限的框架设计与实现(5)-总结与延伸思考 个人代码已经完成,如需要请打赏后通知我。
2359 0
|
SQL 数据库
【自然框架】之通用权限(六):权限到节点
      “直率没有错,但是也要考虑对方的承受能力呀!对方都承受不了了,你还直率,那就是你的错了!”  ——我的名言,呵呵。     ====================我就是传说中的,可爱的、无奈的、笑笑而过的分割线====================         继续,这是第六章了。
1003 0
|
安全
【自然框架】 权限 的视频演示(二): 权限到字段、权限到记录
继续。这里演示权限到字段和权限到记录。            权限到字段有两种安全级别,      1、低安全级别。有些项目不需要做到控制每一个字段是否显示,那么就可以采用这种级别。低安全级别就是:如果一个节点里面没有设置可以访问哪些字段,那么就默认为不需要做到控制字段的程度,就是说节点里的字段都是可以访问的。
1251 0
|
数据库
【自然框架】之通用权限(九):权限的验证
继续,这是第九章了。本来这张应该好好写的,不过还是先简单介绍一下吧,以后有空再补上详细说明吧。 通用权限想要写的文章目录:(这是第九章)   1、 简介、数据库的总体结构2、 介绍人员表组3、 介绍组织结构表组4、 介绍角色表组5、 介绍“项目自我描述表组”6、 权限到节点7、 权限到...
800 0
【自然框架】之通用权限(七):权限到按钮
      继续,这是第七章了。我已经到了无话可说的地步了。哎,在坚持几章就结束了。第七章到第十章,我打算采用简单说明的方式来做,因为我感觉我这么写好像大家都不打感兴趣,或者说都比较忙,没有时间细看,或者说我写的太乱了,看不明白。
886 0
|
Web App开发
【自然框架】通用权限的视频演示(一):添加角色,权限到功能节点和按钮
写了几个关于权限的东东,好像大家都不大理解,也不太清楚我的权限到底能做什么,所以想来想去还是弄点视频吧,就是屏幕录像,这样大家看起来就方便了吧。      为了大家便于观看视频,我先说一下视频的步骤。
1191 0

热门文章

最新文章