一、背景
在日常生活中,遇到的应用系统,都会带有权限功能,用来约束我们访问系统的行为。一个好的权限功能,应该具是动态的、合理的以及安全的。用一句话来描述权限,即Who(谁)对Which(某个模块)进行How(何种操作)。
权限指的是系统提供的功能和数据。可以看到,权限功能包含功能权限和数据权限。
功能权限指的是用户能够执行何种操作,包含对目录、菜单和按钮的操作。
数据权限是的是用户能够访问的数据集。
权限分配:将资源分配给角色的交互。
角色分配:将角色分配给用户的交互。
在实际业务中,权限和组织部门是息息相关的。用户是某个部门的一员。权限给到用户就是通过部门树的结构进行组织安排。
二、权限级别
一般地,可以将权限级别分为以下五类,基本可以涵盖对数据私密性的管控。
权限类别 | 权限级别 |
全部数据权限 | 1 |
部门数据及以下权限 | 2 |
部门数据权限 | 3 |
仅本人数据权限 | 4 |
自定义数据权限 | # |
三、实现权限管理功能的方法
该模块从数据库设计、到数据库CRUD的封装方法,再到真正的实践讲解。
3.1 数据库表设计
3.1.1 数据库表设计字段
在数据库表设计时候,业务表中必须存在部门ID字段和创建者字段,以便后续CRUD操作根据该字段进行过滤数据。
3.1.2 数据库表字段含义
部门ID字段用于数据权限的识别,创建者字段允许该条记录的创建者能够访问到这条数据。。
3.2 增删改查封装方法
3.2.1 查询封装方法
查询很容易理解,就是动态添加where条件
3.2.2 增加方法
插入操作时候自动拼接 where 等于表达式,如拼接 user_id = ?
3.2.3 修改、删除方法
二者封装操作和增加方法类似
我们可以得到,封装拼接条件都是在执行该类型的方法前进行,统一根据某个字段进行筛选属于某个部门或个人的记录。
3.3 基于ORM 框架的封装
无论使用哪一类ORM框架,是JPA还是Mybatis,都会有解析字符串的的工具函数,利用工具函数进行字段的拼接完成数据权限功能的设计。
以Mybatis为例,通过其插件机制对CRUD语句进行封装来开发数据权限功能。
具体到查询语句上来讲,在数据权限拦截器中,处理select
语句,
protected void processSelect(Select select, int index, String sql, Object obj) { SelectBody selectBody = select.getSelectBody(); if (selectBody instanceof PlainSelect) { this.setWhere((PlainSelect) selectBody, (String) obj); } else if (selectBody instanceof SetOperationList) { SetOperationList setOperationList = (SetOperationList) selectBody; List<SelectBody> selectBodyList = setOperationList.getSelects(); selectBodyList.forEach(s -> this.setWhere((PlainSelect) s, (String) obj)); } }