接着上个襄阳项目的需要, 目前的项目情况是,一期已经把功能权限做完了,可以对不同用户的不同权限功能做到限制,现在需要做数据的权限,不同的用户看到不同的数据。

根据目前的调研情况,有两种数据级别权限设计思路,都可以实现对人员访问的数据权限控制,从而实现不同的人员能够看到不同的数据,例如经理能够看到其部门下所有人的数据,而单个的员工只能看到自己的数据。用户拥有的权限越大,能看到的数据就越多。

第一种是使用先在网关进行权限的判断,此用户有这个操作的权限,再进行查询,查询时根据参数进行SQL的拼接。网关鉴定是否能访问以及转发请求,对SQL的拼接和处理在各微服务自己内部进行,服务A/B/C都需要自己写需要查询的参数。如下图所示

使用此方式存在一些弊端 ,使用SQL拼接的方式不利于统一管理权限,每个项目有自己的过滤方式,拼接SQL的方式,不利于统一管理,也不方便后期可能出现的规则修改,因为已经硬编码到代码中,需要各个服务自己修改一遍。

优点很明显,足够很简单,只需要根据相应的规则调整SQL就可以了。

第二种方式,专门抽离一个权限鉴定的服务,所有到达网关的请求后,网关去调用权限鉴定服务,进行访问的URL的权限判断,如果鉴定成功,则能够访问,网关转到请求到对应的服务,否则网关直接返回,提示用户没有权限访问。数据权限的控制依然需要各个微服务硬编码到各自的项目代码中去。如下图所示

目前没有什么方式能做这种通用的数据级权限控制(因为涉及到各个服务的查询SQL进行过滤,拼接,在这个权限鉴定服务中没法实现这样的功能,对各种不同的查询的SQL进行拼接,过滤)。

这种方式相对于第一种把对接口的访问权限校验抽离出来了,减轻了网关的压力,依然是各个服务自己实现数据查询的控制。

现在的思路是:

新建一个mybatis的插件, 让各个服务都依赖这个(java项目可以继承, 其他的php得服务暂时不考虑), 这个插件的作用就是对

SQL进行过滤, 拼接. 鉴权服务会对配置的数据的权限进行读取, 形成一个SQL, 以传递参数的形式, 返回给网关, 网关转发给其他的微服务, 服务获取到携带的SQL参数, 利用插件对SQL进行拼接, 过滤, 就可以查询出来数据了.进行数据的返回.

下面是目前的一部分代码, 希望能够给各位一些启示:

package co.filter;import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.springframework.stereotype.Component;import java.util.Properties;/*** @author zhangke* @time 2019年12月23日10:10:35*/
@Component
@Slf4j
@Intercepts({//注意看这个大花括号,也就这说这里可以定义多个@Signature对多个地方拦截,都用这个拦截器@Signature(type = Executor.class,//这是指拦截哪个接口method = "query",//这个接口内的哪个方法名,不要拼错了//这是拦截的方法的入参,按顺序写到这,不要多也不要少,如果方法重载,可是要通过方法名和入参来确定唯一的args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})
})
public class AuthorityFilterPlugin implements Interceptor {/*** 这里是每次执行操作的时候,都会进行这个拦截器的方法内** @param invocation* @return* @throws Throwable*/@Overridepublic Object intercept(Invocation invocation) throws Throwable {//对sql进行处理Object[] queryArgs = invocation.getArgs();MappedStatement mappedStatement = (MappedStatement) queryArgs[0];Object parameter = queryArgs[1];BoundSql boundSql = mappedStatement.getBoundSql(parameter);// 获取到SQL ,进行调整String sql = boundSql.getSql();if (!sql.contains("limit")) {sql = sql + "limit 1";}log.info("正在执行的sql是: {}", sql);return invocation.proceed();}/*** 主要是为了把这个拦截器生成一个代理放到拦截器链中*/@Overridepublic Object plugin(Object target) {//官方推荐写法return Plugin.wrap(target, this);}/*** 插件初始化的时候调用,也只调用一次,插件配置的属性从这里设置进来** @param properties*/@Overridepublic void setProperties(Properties properties) {}}

下面是过滤的参数的设置.

package com.curefun.authority.filter;import lombok.Data;
import java.util.List;/*** 过滤器的参数实体类,用于拼接SQL用的** question:* 1.分页怎么办? mybatis的分页插件之前执行...* 2.夺标关联查询怎么办? 别名的设置?* 3.这是单独的一个服务,获取到的sql, 可以用拼接url的形式转发给其他服务,其他服务又需要改造,添加mybatis 的插件.
4.一个查询方法对应的多个sql的时候,拼接哪一个?怎么指定?**/
@Data
public class FilterVO {private String id;/*** 服务名*/private String serviceName;/*** 请求的url*/private String requestUrl;/*** 类型 0:不启用   1:启用*/private Integer filterState;/*** 参数的具体值*/private List<ColumnDataVO> params;}package com.curefun.authority.filter;import lombok.Data;/*** 一个查询的所有要拼接的参数*/
@Data
public class ColumnDataVO<T> {/*** 列名字*/private String columnName;/*** 列值,String,Number,List,Set,类型,或者Pair的类型*/private T value;/*** 类型*/private OperationEnum operationEnum;/*** 参数类型*/private ParamTypeEnum paramEnum;/*** 排序,从0 开始,数字越小拼接就越靠前,不能为空*/private int orderNum;public ColumnDataVO(String columnName, T value, OperationEnum operationEnum, ParamTypeEnum paramEnum, int orderNum) {this.columnName = columnName;this.value = value;this.operationEnum = operationEnum;this.paramEnum = paramEnum;this.orderNum = orderNum;}public ColumnDataVO() {}}package com.curefun.authority.filter;/*** 操作类型化的美剧*/
public enum OperationEnum {EQUAL(1,"=","相等"),GT(2,">","大于"),LT(3,"<","小于"),GTE(4,">=","大于等于"),LTE(5,"<=","小于等于"),IN(6,"in","包含"),BETWEEN(7,"between","介于之间"),;private int typeCode;private String operationSymbol;private String message;OperationEnum(int typeCode, String operationSymbol, String message) {this.typeCode = typeCode;this.operationSymbol = operationSymbol;this.message = message;}public int getTypeCode() {return typeCode;}public String getOperationSymbol() {return operationSymbol;}public String getMessage() {return message;}
}package com.curefun.authority.filter;/*** 参数类型*/
public enum ParamTypeEnum {STRING(1,"字符串"),NUMBER(2,"数字"),LIST(3,"List"),SET(4,"Set"),/*** HH:mm:ss*/TIME(5,"时间"),/*** yyyy-MM-dd HH:mm:ss*/DATEtIME(6,"时间"),/*** 双值,用于between的前后范围*/PAIR(7,"双值"),;private int type;private String message;ParamTypeEnum(int type, String message) {this.type = type;this.message = message;}public int getType() {return type;}public String getMessage() {return message;}
}

未完成的部分:

1.根据FilterVO 做SQL的拼接.

2.以上的四个问题,有待于解决,

3.mybatis的过滤器中,怎么根据sql进行正确的拼接, 而且需要考虑效率问题.

5.系统配置的表设计,我这里没做,我想过一下, 但是没有把表设计出来,其实是个一对多的表设计, 两张表就够了.

好了, 就写到这里, 之所以不往下写了, 是因为业务暂时没有这方面的需求, 我这个只是属于前期的探索, 这个已经完成的项目, 还有很大的变数, 还未交付. 所以不做了. 好好复习.

这里放一个别人设计的一张表结构:

CREATE TABLE `sys_acl_data` (`id` int(11) NOT NULL,`acl_id` int(11) NOT NULL COMMENT '对应权限表主键',`status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '状态,1:可用,0:不可用',`param` varchar(20) NOT NULL DEFAULT '' COMMENT '参数',`operation` int(11) NOT NULL DEFAULT '0' COMMENT '操作类型,0;等于,1:大于,2:小于,3:大于等于,4:小于等于,5:包含,6:介于之间,。。。',`value1` varchar(100) NOT NULL DEFAULT '0',`value2` varchar(100) NOT NULL DEFAULT '0',`next_param_op` int(11) NOT NULL DEFAULT '0' COMMENT '后续有参数时连接的关系,0:没有其他参数控制,1:与&&,2:或||',`seq` tinyint(4) NOT NULL DEFAULT '0' COMMENT '顺序',PRIMARY KEY (`id`),KEY `idx_acl_id` (`acl_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='数据权限表';

有可取之处, 不过要想在实际生产环境中适用, 还有很多的工作需要做,

如果您觉得写得不多, 可以请作者喝一杯咖啡

通用数据权限的设计思路相关推荐

  1. 数据权限简单设计思路

    数据权限简单设计思路 现有权限控制分类 数据权限控制 服务架构流程 权限字段的注册 权限字段授权 权限字段鉴权 前端界面适配 动态渲染数据字段 开发注意事项及思考 权限合并 权限的叠加 规则的叠加 S ...

  2. SAP Basis DEBUG改表数据权限角色设计

    SAP Basis DEBUG改表数据权限角色设计 项目实践中,因种种原因不得不要通过debug才能解决一些特定的问题,所以就涉及到了debug权限角色的定义了. DEBUG的权限,无非就是: 1)数 ...

  3. ML之LGBMRegressor(Competition):2018年全国大学生计算机技能应用大赛《住房月租金预测大数据赛》——设计思路以及核心代码—191017再次更新

    ML之LGBMRegressor(Competition):2018年全国大学生计算机技能应用大赛<住房月租金预测大数据赛>--设计思路以及核心代码-191017再次更新 目录 竞赛相关信 ...

  4. java 数据权限_通用数据权限的思考与设计

    1.数据权限概述 1.1.什么是数据权限? 如果想学习Java工程化.高性能及分布式.深入浅出.微服务.Spring,MyBatis,Netty源码分析的朋友可以加我的Java高级交流:7877071 ...

  5. 数据权限设计思路_后台权限管理设计思路:三种模型分析

    编辑导语:任何系统/产品搭建时,最先考虑的都应该是权限管理模块,而且权限管理模块的清晰.稳定是平台产品健康发展的基石,权限管理核心考虑的问题是用户与权限的关系.本文作者对三种不同权限管理的版本展开了梳 ...

  6. 经验总结|一个移动端数据产品的设计思路

    在企业内部或者入驻电商平台的商家.业务方,每天有大量的人在查看大量的指标,用于监控.分析业务的发展.同时,又有着能够随时随地,方便快捷的查看分析数据的诉求.本文想简单介绍下可以随时随地查看数据.分析数 ...

  7. 网络安全等级保护测评——岗位职责、权限划分设计思路(三权分立)

    一.设计思路 1.1三权指什么? 配置.授权.审计 1.2 三员及权限的理解 系统管理员:主要负责系统的资源和运行进行配置.控制和管理,包括用户身份.系统资源配置.系统加载和启动.系统运行的异常处理. ...

  8. 等保测评--- 岗位职责、权限划分设计思路(三权分立)

    一.设计思路 1.1三权指什么? 配置.授权.审计 1.2 三员及权限的理解 系统管理员:主要负责系统的资源和运行进行配置.控制和管理,包括用户身份.系统资源配置.系统加载和启动.系统运行的异常处理. ...

  9. 常见的大数据平台架构设计思路

    近年来,随着IT技术与大数据.机器学习.算法方向的不断发展,越来越多的企业都意识到了数据存在的价值,将数据作为自身宝贵的资产进行管理,利用大数据和机器学习能力去挖掘.识别.利用数据资产.如果缺乏有效的 ...

  10. Service Mesh中的通用数据平面API设计

    原文地址:https://blog.envoyproxy.io/the-universal-data-plane-api-d15cec7a 作者:Matt Klein 译者:敖小剑 校对:宋净超 正如 ...

最新文章

  1. 口袋中的xmind如何添加优先等级图标
  2. spring boot基础配置
  3. HTML5学习笔记简明版(9):变化的元素和属性
  4. 前端学习(1816):前端面试题之作用域和值类型传递的参数1
  5. Even Three is Odd
  6. Twisted中的putChild和getChild
  7. 电脑不能打字_书记员速录如何提高打字速度和正确率
  8. SpreadJS 在 Angular2 中支持哪些事件?
  9. STM32F429HAL库UART学习笔记
  10. 南山驿站机器人_fc机器人大战钢铁之魂攻略
  11. 如何让RS485总线挂接更多数量的设备?
  12. android 代码缩进,Android缩进和悬挂缩进
  13. 2020 不忘初心 继续前行
  14. LNMP+coreseek(sphinx+mmseg3)搭建全文索引库_sgk
  15. Jackson ImmunoResearch 蛋白质印迹指南丨膜清洗
  16. UI设计师和美工有哪些区别?
  17. lottie轻松实现复杂动画(抽奖举例)
  18. 世界著名人工岛,中国有三个很多人都不知道?
  19. 宝藏网站!机器学习概念可视化;LeetCode面试必看清单;104个Python数据科学实战项目;必应超清壁纸;前沿论文 | ShowMeAI资讯日报
  20. FlexRay通信协议概述

热门文章

  1. WX系列无线漫游的配置
  2. qpython3 l_QPython 3(com.hipipal.qpy3) - 3.0.0 - 应用 - 酷安网
  3. u盘启动linux出现grub,开机出现grub rescue报错如何解决 通用pe工具箱u盘启动盘制作工具教你...
  4. 产品设计:axure的基本使用
  5. Axure RP 介绍
  6. django商城项目之历史浏览记录
  7. 博士毕业论文英文参考文献换行_Endnote教程丨本科研究生毕业论文参考文献格式模板,一键搞定...
  8. 洛谷p3764签到题3
  9. shell编程三大神器之awk
  10. 爬虫一:用正则表达式爬取图片