项目描述
上传时间
浏览人数
权限管理框架属于系统安全的范畴,权限管理实现对用户访问系统的控制,按照安全规则用户可以访问而且只能访问自己被授权的资源。目前常见的权限框架有Shiro和Spring Security。
本文介绍的是在SpringBoot项目中仿照Shiro框架的思路,设计数据库并对Token进行配置,从Token中获得用户的姓名,并据此获得该用户的角色和权限,以实现用户访问接口时对其角色及权限的验证。
1.认证管理员身份(admin)
2.认证管理员角色(role)
3.认证管理员权限(permission)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--模板引擎-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--热加载-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
<scope>true</scope>
</dependency>
<!--mybatis技术依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<!--mysql连接依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.34</version>
<scope>runtime</scope>
</dependency>
<!--redis技术依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--加入jwt来实现token验证-->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
<!--generator代码生成器-->
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.7</version>
</dependency>
<!-- hutool工具包-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.11</version>
</dependency>
1.一键下载
https://chengzhushuo.com/public/static/stu_file/2023_04_24_cx_fakeshiro.zip
2.gitee链接
https://gitee.com/chelsea2023/fakeshiro
1.下载项目
项目目录结构(标出了较为重要的token配置文件):
2.检查POM文件和properties文件中MySQL和Redis的配置
properties文件中的一些必要配置:
# Mysql
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/shiro?useUnicode=true&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=123456
# redis
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=
spring.redis.database=0
3.数据库表及相关数据
需要创建五张表:用户表、角色表、权限表、用户角色表、角色权限表。
【用户->角色->权限】关系示意图:
初始化SQL脚本:
-- ------------------------------------------------------
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `admin`
--
DROP TABLE IF EXISTS `admin`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `admin` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(45) NOT NULL,
`password` varchar(45) NOT NULL,
`token` varchar(1000) DEFAULT NULL,
`salt` varchar(45) NOT NULL COMMENT '加密',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=25 DEFAULT CHARSET=utf8 COMMENT='管理员表';
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `admin`
--
LOCK TABLES `admin` WRITE;
/*!40000 ALTER TABLE `admin` DISABLE KEYS */;
INSERT INTO `admin` VALUES (1,'邓布利多','acfbdb1fc9093c2d82027f61feeb42a2',NULL,'r2zdw0'),(2,'斯内普','586095d2c77cdb1bc1d31970b7e890df',NULL,'ggozh0'),(3,'哈利波特','3d17d285817aa952d232ebc882293fea',NULL,'wjicqw'),(4,'海德薇','289d0e5ccee02e86ea837388afc6a318',NULL,'6zn7tw');
/*!40000 ALTER TABLE `admin` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `admin_role`
--
DROP TABLE IF EXISTS `admin_role`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `admin_role` (
`a_id` int(11) NOT NULL COMMENT '用户id',
`r_id` int(11) NOT NULL COMMENT '角色id',
KEY `r_id` (`r_id`),
KEY `u_id` (`a_id`),
CONSTRAINT `admin_role_ibfk_1` FOREIGN KEY (`r_id`) REFERENCES `t_role` (`r_id`),
CONSTRAINT `admin_role_ibfk_2` FOREIGN KEY (`a_id`) REFERENCES `t_user` (`u_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `admin_role`
--
LOCK TABLES `admin_role` WRITE;
/*!40000 ALTER TABLE `admin_role` DISABLE KEYS */;
INSERT INTO `admin_role` VALUES (1,11),(2,12),(3,13);
/*!40000 ALTER TABLE `admin_role` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `permission`
--
DROP TABLE IF EXISTS `permission`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `permission` (
`p_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(30) NOT NULL COMMENT '名称',
`permission` varchar(255) DEFAULT NULL COMMENT '权限',
`status` int(11) DEFAULT '0' COMMENT '状态 0:正常 1:删除',
PRIMARY KEY (`p_id`)
) ENGINE=InnoDB AUTO_INCREMENT=46 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `permission`
--
LOCK TABLES `permission` WRITE;
/*!40000 ALTER TABLE `permission` DISABLE KEYS */;
INSERT INTO `permission` VALUES (21,'注册','register',0),(22,'修改','update',0),(23,'删除','delete',0);
/*!40000 ALTER TABLE `permission` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `role`
--
DROP TABLE IF EXISTS `role`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `role` (
`r_id` int(11) NOT NULL COMMENT '主键',
`name` varchar(30) NOT NULL COMMENT '角色名称',
`status` int(11) DEFAULT NULL COMMENT '状态: 0:正常 1:删除 2:未启用',
PRIMARY KEY (`r_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `role`
--
LOCK TABLES `role` WRITE;
/*!40000 ALTER TABLE `role` DISABLE KEYS */;
INSERT INTO `role` VALUES (11,'校长',0),(12,'院长',0),(13,'学生',0);
/*!40000 ALTER TABLE `role` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `role_permission`
--
DROP TABLE IF EXISTS `role_permission`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `role_permission` (
`r_id` int(11) NOT NULL COMMENT '角色id',
`p_id` int(11) NOT NULL COMMENT '权限id',
KEY `r_id` (`r_id`),
KEY `p_id` (`p_id`),
CONSTRAINT `role_permission_ibfk_1` FOREIGN KEY (`r_id`) REFERENCES `t_role` (`r_id`),
CONSTRAINT `role_permission_ibfk_2` FOREIGN KEY (`p_id`) REFERENCES `permission` (`p_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `role_permission`
--
LOCK TABLES `role_permission` WRITE;
/*!40000 ALTER TABLE `role_permission` DISABLE KEYS */;
INSERT INTO `role_permission` VALUES (11,21),(11,22),(11,23),(12,21),(12,22),(13,21),(13,22);
/*!40000 ALTER TABLE `role_permission` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- ------------------------------------------------------
导入后的结构和数据(admin表中账号的密码均为123456):
4.在Controller层给需要验证角色和权限的接口添加注解
允许访问该接口的角色(role)可以是多个,允许访问该接口的权限(permission)只能有一个。
如果不需要角色验证,则只写权限验证即可:
@TokenConfig.UserLoginTokenAndPerm(perm = "修改")
例如,访问当前接口需要角色为["院长","校长"]且需要权限为"删除",则添加注解:
@GetMapping("delete")
@TokenConfig.UserLoginToken
@TokenConfig.UserLoginTokenAndPerm(role={"院长","校长"}, perm = "删除")
public Object delete(Integer id){
return adminService.delete(id);
}
不添加token,直接访问当前接口,则返回:
登录"哈利波特"的账号(admin表中账号的密码均为123456)获取token后,访问当前接口,则返回:
登录"邓布利多"的账号(admin表中账号的密码均为123456)获取token后,访问当前接口,则返回:
==========END==========