数据权限配置有两种方式:
-
通过系统配置界面,实时配置生效。
-
通过代码注解配置。
一、通过系统配置界面配置数据权限
系统配置的数据权限是通过系统配置界面将配置信息保存在数据库,然后系统启动时,将配置信息保存到Redis缓存来实现的。
1、系统管理 > 权限管理 > 数据权限,一定要选择具体需要做数据权限的接口,然后点击新建。数据权限是控制获取数据的接口请求,不是系统菜单。
2、新增数据权限规则,以及配置参数说明
参数说明:
- 数据权限名称 :自定义一个名称,方便查找和区分
- Mapper全路径 :Mapper路径配置到具体方法名称,例:com.gitegg.service.system.mapper.UserMapper.selectUserList
- 数据权限类型 :数据权限控制的不同范围,这里会和用户的角色配置相关联。实际是一个角色的数据权限范围,角色数据权限的可视范围。
只能查看本人(实现原理是在查询条件添加数据表的creator条件)
只能查看本部门 (实现原理是在查询条件添加数据表的部门条件)
只能查看本部门及子部门 (实现原理是在查询条件添加数据表的部门条件)
可以查看所有数据(不处理)
自定义(添加where子条件) - 权限主表 :需要过滤据权限的关联表,比如此例中是查询用户信息,那么权限主表就是用户表和组织机构数据权限有关联的表。
- 权限主表别名 :数据权限本质是通过自定义插件,实现SQL语句的拼接,从而过滤用户拥有的数据权限数据,所以在拼接SQL语句时,多表JOIN需要给表设置别名,那么这个字段就是设置权限主表的别名。
- 数据权限表 :用于数据权限的配置表,本例中是指t_sys_data_permission_user表(这张表里存的是组织机构和用户的关联关系,在新建用户时,会选择用户的机构,那么默认该用户是拥有该机构的权限的,如果用户拥有多个机构的数据权限,那么在新建用户之后,用户列表后面的操作按钮中选择用户的多个机构数据数据权限。),如果数据权限表没有跟需要查询的数据权限有直接的关联关系,那么需要有其他中间表来关联,那么这个中间表就是需要配置的数据权限的主表。
- 数据权限表别名 :拼接SQL语句时的表别名。
- 需排除的字段 :列级数据权限,配置没有权限查看的字段,表示该数据权限配置查询的结果中需要去除的字段。
- 仅保留的字段 :列级数据权限,配置有权限查看的字段,表示该数据权限配置查询的结果仅保留的字段。
- 自定义表达式 :有时我们可能会对数据权限进行额外的限制,此字段是拼接在where条件后面的自定义语句(做好系统安全,如果这里随便配置,那么会有SQL注入的风险)。
- 状态 :数据权限是否启用的标识。
- 备注 :对此数据权限的备注信息。
3、配置适应执行数据权限的角色(和数据权限类型字段相匹配)
通常,经典的RBAC模型中,我们角色是和资源权限相关联的,而在此处,我们将角色与数据权限类型相关联,就是在角色设计时,要考虑的就是这个角色可以查看的数据权限范围。通过配置可知,数据权限的控制是从两方面进行的,一方面是用户和组织机构的数据权限关联,一方面是角色和数据权限的类型关联的。
数据权限插件控制数据权限的流程:数据权限插件在组装SQL时,首先通过前缀匹配查询mapper的statementId是否在缓存中,如果存在,那么取出当前用户角色相匹配的数据权限类型,组装好带有数据权限类型的DataPermission缓存Key,从缓存中取出数据权限配置。
二、通过注解配置数据权限
通过注解的方式来实现数据权限配置,在开发人员进行开发的时候,可能显得方便一些,哪些接口需要进行数据权限,那么直接注解使用就可以了。但是,此种方法并不灵活,如果数据权限有变化,那么还需要修改代码并重新发布到线上环境。
1、在**Mapper.java中的接口增加@DataPermission注解
/**
* 查询用户列表
* @param page
* @param user
* @return
*/
@DataPermission(dataTableName = "t_sys_organization_user", dataTableAlias = "organizationUser", dataPermissionType = "3", innerTableName = "t_sys_organization", innerTableAlias = "orgDataPermission")
@DataPermission(dataTableName = "t_sys_organization_user", dataTableAlias = "organizationUser", dataPermissionType = "2", innerTableName = "t_sys_organization", innerTableAlias = "orgDataPermission")
@DataPermission(dataTableName = "t_sys_organization_user", dataTableAlias = "organizationUser", dataPermissionType = "1", innerTableName = "t_sys_organization", innerTableAlias = "orgDataPermission")
Page<UserInfo> selectUserList(Page<UserInfo> page, @Param("user") QueryUserDTO user);
2、@DataPermission注解参数说明
@DataPermission注解中的配置参数,可以参考配置界面中的参数说明,实现的是相同功能,只是两者的实现方式不一样:配置界面是可以实时配置实时生效的,注解的方式是在代码中,每次代码运行时,会根据注解配置进行数据权限控制。
/**
* 需要做数据权限主表
*/
String dataTableName() default "";
/**
* 需要做数据权限表的别名
*/
String dataTableAlias() default "";
/**
* 数据权限需要排除的字段
*/
String dataColumnExclude() default "";
/**
* 数据权限需要保留的字段
*/
String dataColumnInclude() default "";
/**
* 数据权限表
*/
String innerTableName() default "t_sys_organization";
/**
* 数据权限表的别名
*/
String innerTableAlias() default "dpOrg";
/**
* 数据权限类型:1只能查看本人 2只能查看本部门 3只能查看本部门及子部门 4可以查看所有数据 5 自定义
*/
String dataPermissionType() default "";
/**
* 自定义数据权限类型
*/
String customExpression() default "";