1. 背景需求
在流程管理系统中,需要对权限进行控制,包括流程权限、菜单权限,
其中
- 菜单权限是对用户能看到的菜单进行控制。
- 流程权限是指对用户的流程显示、流程处理进行控制,因同一流程涉及到不同的系统,所以用户根据拥有系统的角色而对流程的权限也不尽相同。如下表为列为系统角色所拥有的流程权限,行为工单所有权限。除此之外不同部门下有不同的系统,不同部门之间数据不互通,即不允许查看跨部门系统的相关流程。
2. 菜单权限
-
目标
菜单权限的目标
将菜单按菜单权限过滤后向用户展示。
用户的菜单权限与角色相关
管理员可以指定用户的角色
管理员可以为角色分配菜单
- 现有菜单分类
现有菜单包括:
一级菜单:运维平台
二级菜单:任务操作、流程管理…
三级菜单:事件管理、问题管理…
四级菜单:事件流程、信息问询…
- 菜单权限设计
采取,“用户-角色-菜单”的对应关系维护用户的菜单权限,
将现有菜单保存到数据库中,菜单表:
Field | Type | Comment |
menu_id | bigint NOT NULL | ID |
pid | bigint NULL | 上级菜单ID |
sub_count | int NULL | 子菜单数目 |
type | int NULL | 菜单类型 |
title | varchar(255) NULL | 菜单标题 |
menu_sort | int NULL | 排序 |
path | varchar(255) NULL | 链接地址 |
permission | varchar(255) NULL | 权限 |
panel_name | varchar(255) NULL | 三级菜单的外层panel名称 |
create_by | varchar(255) NULL | 创建者 |
update_by | varchar(255) NULL | 更新者 |
create_time | datetime NULL | 创建日期 |
update_time | datetime NULL | 更新时间 |
Eg:
新增加一个页面菜单管理页面,对所有的菜单进行维护。
- 菜单权限实现
菜单权限的页面过滤:Index页面获取用户菜单,动态添加菜单。
菜单权限的后台过滤:在controller层添加注解@PreAuthorize("“),使用springsecurity进行权限过滤。
例如:
@PreAuthorize("hasPermission('/duty.html','sys:duty:query')")
继承PermissionEvaluator实现方法
hasPermission (Authentication authentication, Object targetUrl, Object targetPermission)
在方法内进行权限认证,遍历用户的角色并获得角色拥有的菜单全集,将菜单中permission与访问方法增加的permission进行比较得出是否拥有权限。
3. 流程访问权限(数据权限)
- 目标
数据权限的目标:
将运维工作平台的数据按权限向用户展示。
管理员可对用户进行数据权限的配置。
- 现有数据分类
现有数据包括:
- 任务数据:已按照团队管理进行任务数据的控制
-
流程数据:尚未进行控制,现有系统与组的对应关系,系统属于组;系统与用户的关系包括负责人、参与人和开发人员。
-
管理类数据:任务策略、流程配置、接口规则配置、用户管理等,权限只开放给管理员。
目前需要做的是将流程数据管理起来,用户拥有其所负责和参与的系统流程数据的访问权限。
- 数据权限实现方案
| 方案1 | 方案2 | 方案3 |
说明 | 使用mybatis动态sql,将权限拼接进去。 | 使用拦截器方式,在sql执行之前 | 每项功能代码中,逻辑都增加权限过滤 |
优点 |
|
|
|
缺点 | 1. 需要用到mapper.xml进行配置,与项目不兼容 | 1. 需要对sql进行解析和拼接。处理后的sql容易有语法错误。 2. 容易产生分页错误 | 1. 每一个业务功能项都需要增加权限过滤,代码改动量大。 2. 如果新增过滤项则需要修改每项业务逻辑,扩展性差。 |
与项目结合情况 | 目前项目sql操作方式采用mybatis-plus的方式操作数据库,对具体的sql不感知,未使用mapper.xml配置的方式,所以方案修改量较大 | 适用 | 适用 |
- 详细实现方案(方案2)
在上节中,方案一不适用本系统,方案三保存数据权限后可直接在业务逻辑中填加过滤,不需过多设计,本节着重分析方案二。
- 流程
1. 管理员用户对普通用户的数据权限进行配置。管理员可以初始化所有用户权限,默认为其所负责和参与的全部系统;初始化一次后不再执行初始化操作,可对用户进行修改数据权限。
2. 普通用户登录根据用户数据权限进行数据过滤。
- 数据权限保存方式
方式1:数据库Puser表增加字段data_scope varchar(1000) 用于保存用户的数据权限。
方式2:单独设立数据权限表,包含字段data_scope,与用户表一一对应。
data_scope 详细说明:
Json格式存储数据权限
属性及含义(可进行扩展,后续如果需要根据其他属性进行数据过滤可以增加过滤属性):
System:用户可访问系统id的数组
Admin:用户是否拥有全部权限
Department:用户可访问部门id的数组
Eg:
{
system:[272,301],
admin:false
}
备注:方法1不能对puser表过滤,因为过滤的时候需要获取用户信息,而获取用户信息的过程中又被拦截到进行过滤,会发生死循环。
拦截器实现
Mybatis支持的拦截接口
- 拦截点:Mybatis-plus需要在Executor处进行拦截,项目中用到的是mybatis-plus分页(分页本身基于StatementHandler拦截器实现)需要在分页前进行拦截。
拦截器拦截到后进行sql解析和增加权限过滤
- 拦截规则:配置需要拦截的表和表中的系统id。后续如有需要可以增加配置文件,将拦截信息置入到配置文件中。
Eg:
- 解析器:Sql解析采用CCJSqlParser,避免发生修改后sql语法错误问题。当前项目已集成该插件。
4. 流程控制权限
- 流程控制权限的目标
实现对iso20000流程的控制权限的维护
- 流程控制权限设计
采取,“用户-系统-角色”的对应关系维护用户的流程控制权限,“角色-工单权限”维护工单权限与角色的关系。
form_permission_dictionary工单权限字典
字段名称 | 字段类型 | 默认值 | 字段长度 | 备注信息 |
id | BIGINT |
| 19 | 工单权限字典id |
name | VARCHAR |
| 255 | 权限名称(新建,驳回等) |
role_form_permission角色工单权限
字段名称 | 字段类型 | 默认值 | 字段长度 | 备注信息 |
id | BIGINT |
| 19 | 角色工单权限id |
role_id | BIGINT |
| 19 | 角色id |
role_name | VARCHAR |
| 255 | 角色名称 |
form_permission_id | BIGINT |
| 19 | 工单权限id |
form_permission_name | VARCHAR |
| 255 | 工单权限名称 |
form_type | VARCHAR |
| 255 | 工单类型 |
form_nick | VARCHAR |
| 255 | 工单名称 |
user_sys_role(人员-系统-角色)表
字段名称 | 字段类型 | 默认值 | 字段长度 | 备注信息 |
id | BIGINT |
| 19 | (人员-系统-角色)表id |
user_id | BIGINT |
| 19 | 用户id |
user_name | VARCHAR |
| 255 | 用户名称 |
system_id | BIGINT |
| 19 | 系统id |
system_name | VARCHAR |
| 255 | 系统名称 |
role_id | BIGINT |
| 19 | 角色id |
role_name | VARCHAR |
| 255 | 角色名称 |
- 流程控制权限实现
将关系维护在数据库中,在页面中控制流程控制按钮的显示。