通用数据级别权限的框架设计与实现(3)-数据列表的权限过滤
查看上篇文章通用数据级别权限的框架设计与实现(2)-数据权限的准备工作,我们开始数据列表的权限过滤.
原理:我们在做过滤列表时,根据用户权限自动注入到相关SQL中,实现相关过滤,如果拥有全部权限,则不生成相关SQL片段
- 首先我们来分析一下数据列表的SQL
- 能看到所有数据的SQL
SELECTrole.id,role. CODE,role. NAME
FROMsys_auth_role role
where 1=1
- 根据登陆角色,看到的数据的SQL
-SELECTrole.id,role. CODE,role. NAME
FROMsys_auth_role role
LEFT JOIN sys_auth_role_org_rel ror ON ror.role_id = role.id
WHERE1 = 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() + ")";elsereturn 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*/@Overridepublic 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的能看到全部数据,其他要做过滤.
- 数据列表的mapper方法改造为如下:
<select id="list" resultMap="BaseResultMap">select role.id,role.code,role.namefrom sys_auth_role role<if test="authModel != null">${authModel.relSql}</if>where1=1<if test="authModel != null">${authModel.condictionSql}</if></select>
- 权限列表的生成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
- 权限过滤调用的方法改写成如下:
/*** 权限过滤查找相关角色* @return*/public List<SysAuthRole> list(){AuthModel authModel= AuthValidatorUtil.getAuthModel(SysAuthRole.class.getName(),true);return authRoleMapper.list(authModel);}
至此,我们列表权限过滤的架子已经搭建完成.
个人代码已经完成,如需要请打赏后通知我。谢谢.
如果你觉得该文章对你有帮助,麻烦点赞。
欢迎继续查看下篇文章-通用数据级别权限的框架设计与实现(4)-单条记录的权限控制
通用数据级别权限的框架设计与实现(3)-数据列表的权限过滤相关推荐
- 通用数据级别权限的框架设计与实现(4)-单条记录的权限控制
查看上篇文章通用数据级别权限的框架设计与实现(3)-数据列表的权限过滤,我们开始在原来的基础上实现单条权记录的权限控制. 相信前面的列表权限控制,很多系统都可以做到,但如何在上面列表的权限过滤中实现通 ...
- 痞子衡嵌入式:嵌入式里通用微秒(microseconds)计时函数框架设计与实现
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是嵌入式里通用微秒(microseconds)计时函数框架设计与实现. 在嵌入式软件开发里,计时可以说是非常基础的功能模块了,其应用也非常 ...
- 这可能是史上功能最全的Java权限认证框架!
点击关注公众号,Java干货及时送达 今天给大家推荐的这个开源项目超级棒,可能是史上功能最全的 Java 权限认证框架! 这个开源项目就是:sa-token . Sa-Token是什么? sa-tok ...
- Spring Security太复杂?试试这个轻量、强大、优雅的权限认证框架!
各位程序猿小伙伴们,中秋快乐~在节日欢快的气氛中大家是不是还在奋笔疾书.沉浸在学习的海洋中呢? 小编这两天休息在家一直在想一个问题,那就是我们在开发SpringBoot项目的时候,该怎么做好权限认证呢 ...
- .NET Core实战项目之CMS 第七章 设计篇-用户权限极简设计全过程
写在前面 这篇我们对用户权限进行极简设计并保留其扩展性.首先很感谢大家的阅读,前面六章我带着大家快速入门了ASP.NET Core.ASP.NET Core的启动过程源码解析及配置文件的加载过程源码解 ...
- 数据自治开放应用平台设计与实践
数据自治开放应用平台设计与实践 陈德华, 潘乔, 王梅, 乐嘉锦 东华大学计算机科学与技术学院,上海 201620 摘要:围绕数据自治开放的数据管理新模式,提出了一套面向数据自治开放应用的整体解决方案 ...
- 前端埋点的缺点_【埋点学习埋点质量】埋点的框架设计及其准确性
是新朋友吗?记得先点蓝字关注我哦- 通过前两章<送你一份埋点需求分析&设计埋点方案><一份规范的埋点需求文档该如何写?>,我们已经足够了解埋点,并且能够输出埋点文档了. ...
- SpringBoot集成权限认证框架(Sa-Token)
SpringBoot集成权限认证框架(Sa-Token) 介绍 身份验证又称"验证"."鉴权",是指通过一定的手段,完成对用户身份的确认. 身份验证的目的是确认 ...
- 滴滴青桔单车跨端技术方案和业务技术架构,及框架设计和性能提升实践
导读:经过将近两年的发展,小程序已经深入用户的日常生活,小程序应用数量超过了百万量级,覆盖众多细分行业,日活用户达到两个亿.青桔单车是日活相对较高的小程序,这也要求我们对小程序的性能.稳定性及安全有较 ...
最新文章
- 专家认为自动驾驶汽车需要很多年的五个原因
- python 函数装饰器_python函数装饰器的用法
- 如何用图表控件实现点击图例图标隐藏图表序列
- 大数据分析中国冬季重度雾霾的成因(一)
- Spring Shedule Task之注解实现 (两次启动Schedule Task 的解决方案)
- 微信读书android换到ios,Android 微信读书本周推荐传送带列表实现
- 全国数据中心分布图上线 轻轻松松找机房
- 02_MySQL约束课堂笔记
- 自己的 「 代码制造 check list 」
- 洛谷P1589 泥泞路
- 建站基础知识之CSS 究竟什么来头?
- 并发网站压力测试工具
- bex5执行oracle语句,BeX5
- 2021-08-14
- 我的编程之路点滴记录(二)
- 2021CCPC女生专场
- 小马智行与速腾聚创展开全面战略合作
- MySql如何储存和获取ip地址?以及mysql储存和获取ip地址的底层实现原理!!
- 百度云主机只能访问首页,bcloud_nginx_user.conf配置
- 使用Maya和Substance Painter制作一辆越野赛车(1)