Spring Security——07,授权_从数据库查询权限信息

本文介绍了如何在基于RBAC的权限模型下,通过数据库查询获取用户权限,包括创建数据表、角色与菜单的多对多关系,以及使用Mybatis进行权限信息查询的代码实现和测试过程。
摘要由CSDN通过智能技术生成

便于理解,前面的权限都是写死的,从这里开始是查询数据库的

一、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 准备查询语句

SELECT
	DISTINCT m.`perms`	
FROM
    sys_user_role ur
    LEFT 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`
WHERE
    user_id = 2
    AND r.`status` = 0
    AND 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;
    @TableId
    private 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,就可以了

在这里插入图片描述

一键三连有没有捏~~

  • 10
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值