授权_从数据库查询权限信息
- 一、RBAC权限模型
- 二、准备工作
- 2.1 创建数据表
- 2.2 准备表数据
- 2.3 准备查询语句
- 2.4 创建一个实体类Menu
- 三、代码实现
- 3.1 创建一个MenuMapper
- 3.2 创建对应的mapperXML文件
- 3.3 配置mapperXML文件的位置
- 3.4 UserDetailsServiceImpl查询权限信息
- 四、测试一下
- 一键三连有没有捏~~
便于理解,前面的权限都是写死的,从这里开始是查询数据库的
一、RBAC权限模型
RBAC权限模型(Role-Based Access Control)即:基于角色的权限控制。这是目前最常被开发者使用也是相对易用、通用权限模型。
权限表跟角色表:
一个角色可以有多个权限,一个权限可以对应多个角色,所以权限表跟角色表它们是一个多对多的关系
用户表跟角色表:
一个用户可以有多个角色,比如管理员,它可以是管理员,也可以是借阅人一个角色可以有多个用户,比如公司的hr角色,大公司很多人都是hr,不单单是一个所以用户表跟角色表是一个多对多的关系
二、准备工作
2.1 创建数据表
sys_menu 权限表只需要关注三个字段:
一个是id,一个是menu_name功能菜单,一个是status菜单的状态是否可用
sys_role 角色表
一个是id,一个是name,一个是role_key,一个是status
sys_role_menu 角色权限关联表
两个表对应的id,主键是一个组合的主键
sys_user用户表
之前就创建过了,略。。。。。说
sys_user_role用户角色表
两个表对应的id,主键是一个组合的主键
建表语句如下:
/*Table structure for table `sys_menu` */DROP TABLE IF EXISTS `sys_menu`;CREATE TABLE `sys_menu` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`menu_name` varchar(64) NOT NULL DEFAULT 'NULL' COMMENT '菜单名',`path` varchar(200) DEFAULT NULL COMMENT '路由地址',`component` varchar(255) DEFAULT NULL COMMENT '组件路径',`visible` char(1) DEFAULT '0' COMMENT '菜单状态(0显示 1隐藏)',`status` char(1) DEFAULT '0' COMMENT '菜单状态(0正常 1停用)',`perms` varchar(100) DEFAULT NULL COMMENT '权限标识',`icon` varchar(100) DEFAULT '#' COMMENT '菜单图标',`create_by` bigint(20) DEFAULT NULL,`create_time` datetime DEFAULT NULL,`update_by` bigint(20) DEFAULT NULL,`update_time` datetime DEFAULT NULL,`del_flag` int(11) DEFAULT '0' COMMENT '是否删除(0未删除 1已删除)',`remark` varchar(500) DEFAULT NULL COMMENT '备注',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COMMENT='菜单表';/*Table structure for table `sys_role` */DROP TABLE IF EXISTS `sys_role`;CREATE TABLE `sys_role` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`name` varchar(128) DEFAULT NULL,`role_key` varchar(100) DEFAULT NULL COMMENT '角色权限字符串',`status` char(1) DEFAULT '0' COMMENT '角色状态(0正常 1停用)',`del_flag` int(1) DEFAULT '0' COMMENT 'del_flag',`create_by` bigint(200) DEFAULT NULL,`create_time` datetime DEFAULT NULL,`update_by` bigint(200) DEFAULT NULL,`update_time` datetime DEFAULT NULL,`remark` varchar(500) DEFAULT NULL COMMENT '备注',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='角色表';/*Table structure for table `sys_role_menu` */DROP TABLE IF EXISTS `sys_role_menu`;CREATE TABLE `sys_role_menu` (`role_id` bigint(200) NOT NULL AUTO_INCREMENT COMMENT '角色ID',`menu_id` bigint(200) NOT NULL DEFAULT '0' COMMENT '菜单id',PRIMARY KEY (`role_id`,`menu_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;/*Table structure for table `sys_user` */DROP TABLE IF EXISTS `sys_user`;CREATE TABLE `sys_user` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',`user_name` varchar(64) NOT NULL DEFAULT 'NULL' COMMENT '用户名',`nick_name` varchar(64) NOT NULL DEFAULT 'NULL' COMMENT '昵称',`password` varchar(64) NOT NULL DEFAULT 'NULL' COMMENT '密码',`status` char(1) DEFAULT '0' COMMENT '账号状态(0正常 1停用)',`email` varchar(64) DEFAULT NULL COMMENT '邮箱',`phonenumber` varchar(32) DEFAULT NULL COMMENT '手机号',`sex` char(1) DEFAULT NULL COMMENT '用户性别(0男,1女,2未知)',`avatar` varchar(128) DEFAULT NULL COMMENT '头像',`user_type` char(1) NOT NULL DEFAULT '1' COMMENT '用户类型(0管理员,1普通用户)',`create_by` bigint(20) DEFAULT NULL COMMENT '创建人的用户id',`create_time` datetime DEFAULT NULL COMMENT '创建时间',`update_by` bigint(20) DEFAULT NULL COMMENT '更新人',`update_time` datetime DEFAULT NULL COMMENT '更新时间',`del_flag` int(11) DEFAULT '0' COMMENT '删除标志(0代表未删除,1代表已删除)',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='用户表';/*Table structure for table `sys_user_role` */DROP TABLE IF EXISTS `sys_user_role`;CREATE TABLE `sys_user_role` (`user_id` bigint(200) NOT NULL AUTO_INCREMENT COMMENT '用户id',`role_id` bigint(200) NOT NULL DEFAULT '0' COMMENT '角色id',PRIMARY KEY (`user_id`,`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
2.2 准备表数据
sys_user用户表:
sys_user_role用户角色表:
sys_role角色表:
sys_role_menu角色权限表:
sys_menu权限表:
2.3 准备查询语句
SELECTDISTINCT m.`perms`
FROMsys_user_role urLEFT JOIN `sys_role` r ON ur.`role_id` = r.`id`LEFT JOIN `sys_role_menu` rm ON ur.`role_id` = rm.`role_id`LEFT JOIN `sys_menu` m ON m.`id` = rm.`menu_id`
WHEREuser_id = 2AND r.`status` = 0AND m.`status` = 0# DISTINCT 用于去重的,去掉重复的 perms,详情可以看https://blog.csdn.net/qq_39674002/article/details/108272959
2.4 创建一个实体类Menu
/*** 菜单表(Menu)实体类*/
@TableName(value = "sys_menu")
@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Menu implements Serializable {private static final long serialVersionUID = -54979041104113736L;@TableIdprivate Long id;/*** 菜单名*/private String menuName;/*** 路由地址*/private String path;/*** 组件路径*/private String component;/*** 菜单状态(0显示 1隐藏)*/private String visible;/*** 菜单状态(0正常 1停用)*/private String status;/*** 权限标识*/private String perms;/*** 菜单图标*/private String icon;private Long createBy;private Date createTime;private Long updateBy;private Date updateTime;/*** 是否删除(0未删除 1已删除)*/private Integer delFlag;/*** 备注*/private String remark;
}
三、代码实现
有一个插件,插件的名称叫做MybatisX,它可以在我们写完MenuMapper后,帮我们生产对应的XML文件,还有方法所对应的标签
3.1 创建一个MenuMapper
3.2 创建对应的mapperXML文件
3.3 配置mapperXML文件的位置
写一个测试方法,测试一下,没有问题,OK
3.4 UserDetailsServiceImpl查询权限信息
四、测试一下
测试的时候,要重新登录,为什么呢?因为redis存放的是旧的,不是最新的
登录成功之后,访问hello接口,返回的是403
因为我们的权限设置的是test333才可以访问
把hello接口的权限改成system:dept:list,就可以了