共计 10178 个字符,预计需要花费 26 分钟才能阅读完成。
目录
SpringSecurity 权限管理系统实战—一、我的项目简介和开发环境筹备
SpringSecurity 权限管理系统实战—二、日志、接口文档等实现
SpringSecurity 权限管理系统实战—三、次要页面及接口实现
SpringSecurity 权限管理系统实战—四、整合 SpringSecurity(上 )
SpringSecurity 权限管理系统实战—五、整合 SpringSecurity(下 )
SpringSecurity 权限管理系统实战—六、SpringSecurity 整合 jwt
SpringSecurity 权限管理系统实战—七、解决一些问题
SpringSecurity 权限管理系统实战—八、AOP 记录用户日志、异样日志
前言
博主的文笔有些差,大家多担待
一、简介
在企业应用中,认证和受权是十分重要的一部分内容,业界最闻名的两个框架就是赫赫有名的 Shiro 和 Spring Security。本次我选取的是和 SpringBoot 更好兼容的 SpringSecurity。
二、什么是 RBAC
RBAC 是 Role Based Access Control 的缩写,是基于角色的访问控制。个别都是分为用户(user),角色(role),权限(permission)三个实体,角色(role)和权限(permission)是多对多的 关系,用户(user)和角色(role)也是多对多的关系。用户(user)和权限(permission)之间没有间接的关系,都是通过角色作为代理,能力获取到用户(user)领有的权限。
以下是 RBAC0 的模型
具体解释见
三、零碎性能
- 用户治理:提供用户的相干配置
- 角色治理:对权限与菜单进行调配
- 菜单治理:已实现菜单动静路由,后端可配置化,反对多级菜单
- 字典治理:可保护罕用一些固定的数据
- 系统日志:记录用户操作日志与异样日志
- SQL 监控:采纳 druid 监控数据库拜访性能
- 代码生成:高灵便度生成前后端代码,缩小大量反复的工作工作
- 接口治理:不便对立查看治理接口
因为本零碎是边开发写此文档的,所以可能上述的性能在后续的开发中会有删改。
四、环境搭建
本次零碎非前后端拆散我的项目,基于 SpringBoot+Layui, 后盾模板选用的是 Pear Admin Layui(我目前见过最丑陋的 layui 后盾模板,放张图片让大家感受一下 )
数据库设计
目前先这样,之后还会扩大。
在 idea 中新建 SpringBoot 我的项目, 导入所需依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 这里须要先把 SpringSecurity 登记 -->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-security</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!--swagger ui-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.7.RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
在我的项目中把架构搭好,创立对应数据库表的 eneity、dao、service、controller,非常简单不想占用篇幅。须要留神的就是实体类中的 create_time, 和 update_time, 因为这两个和 id 是在多张表中都有呈现,所以咱们能够把它们抽离进去,有须要的实体类间接继承就能够了
@Data
public abstract class BaseEntity<ID extends Serializable> implements Serializable {
private static final long serialVersionUID = 8925514045582235838L;
private ID id;
private Date createTime = new Date();
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime = new Date();}
再插一嘴,@Data 是 lambok 提供的一个注解,能够用于生成实体类的 get 和 set 办法。应用须要导入 maven 依赖,在 idea 中也要装置相应插件。如何装置应用应用详见
而后将 PearAdmin 的资源放入 templates 下
那么接下来咱们先把我的项目运行起来,在 index.html 中退出 thymeleaf 的命名空间,通过 thymeleaf 的语法从新引入下资源。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="stylesheet" th:href="@{/PearAdmin/component/layui/css/layui.css}" />
<link rel="stylesheet" th:href="@{/PearAdmin/admin/css/pearTab.css}" />
<link rel="stylesheet" th:href="@{/PearAdmin/admin/css/pearTheme.css}" />
<link rel="stylesheet" th:href="@{/PearAdmin/admin/css/pearLoad.css}" />
<link rel="stylesheet" th:href="@{/PearAdmin/admin/css/pearFrame.css}" />
<link rel="stylesheet" th:href="@{/PearAdmin/admin/css/pearAdmin.css}" />
<link rel="stylesheet" th:href="@{/PearAdmin/admin/css/pearNotice.css}" />
<link rel="stylesheet" th:href="@{/PearAdmin/admin/css/pearSocial.css}" />
<link rel="stylesheet" th:href="@{/PearAdmin/admin/css/pearMenu.css}" />
<style id="pearone-bg-color"></style>
</head>
<body class="layui-layout-body pear-admin">
<!-- 布局框架 -->
<div class="layui-layout layui-layout-admin">
<div class="layui-header">
<ul class="layui-nav layui-layout-left">
<li class="collaspe layui-nav-item"><a href="#" class="layui-icon layui-icon-shrink-right"></a></li>
<li class="refresh layui-nav-item"><a href="#" class="layui-icon layui-icon-refresh-1"></a></li>
</ul>
<div id="control" class="layui-layout-control"></div>
<ul class="layui-nav layui-layout-right">
<li class="layui-nav-item layui-hide-xs"><a href="#" class="fullScreen layui-icon layui-icon-screen-full"></a></li>
<li class="layui-nav-item layui-hide-xs"><a href="http://www.pearadmin.cn" class="layui-icon layui-icon-website"></a></li>
<li class="layui-nav-item layui-hide-xs" id="headerNotice"></li>
<li class="layui-nav-item" lay-unselect="">
<a href="javascript:;"><img th:src="@{/PearAdmin/admin/images/avatar.jpg}" class="layui-nav-img"> 就眠典礼 </a>
<dl class="layui-nav-child">
<dd><a href="javascript:;" class="pearson"> 个人信息 </a></dd>
<dd><a href="javascript:;"> 平安配置 </a></dd>
<dd><a href="login.html"> 登记登陆 </a></dd>
</dl>
</li>
<li class="setting layui-nav-item"><a href="#" class="layui-icon layui-icon-more-vertical"></a></li>
</ul>
</div>
<div class="layui-side layui-bg-black">
<div class="layui-logo">
<img class="logo" th:src="@{/PearAdmin/admin/images/logo.png}" />
<span class="title">Plus Admin</span>
</div>
<div class="layui-side-scroll">
<div id="sideMenu"></div>
</div>
</div>
<div class="layui-body">
<div id="content"></div>
</div>
</div>
<!-- 挪动端 遮蔽层 -->
<div class="pear-cover"></div>
<!-- 初始加载 动画 -->
<div class="loader-main">
<div class="loader"></div>
</div>
<!-- 聊天组件 -->
<div id="social" class="layui-hide-xs"></div>
<!-- 挪动端 的 膨胀适配 -->
<div class="collaspe pe-collaspe layui-hide-sm">
<i class="layui-icon layui-icon-shrink-right"></i>
</div>
<script th:src="@{/PearAdmin/component/layui/layui.js}" charset="utf-8"></script>
<script>
layui.use(['pearAdmin', 'jquery', 'pearSocial', 'layer'], function() {
var pearAdmin = layui.pearAdmin;
var $ = layui.jquery;
var layer = layui.layer;
var pearSocial = layui.pearSocial;
var pearAuth = layui.pearAuth;
var config = {
keepLoad: 2000, // 主 页 加 载 过 度 时 长 可为 false
muiltTab: true, // 是 否 开 启 多 标 签 页 true 开启 false 敞开
control: false, // 是 否 开 启 多 系 统 菜 单 true 开启 false 敞开
theme: "dark-theme", // 默 认 主 题 样 式 dark-theme 默认主题 light-theme 亮主题
index: '/console/console1', // 默 认 加 载 主 页, 这里须要该
data: 'PearAdmin/admin/data/menu.json', // 菜 单 数 据 加 载 地 址
select: '0', // 默 认 选 中 菜 单 项
notice: 'PearAdmin/admin/data/notice.json', // 消 息 列 表 数 据
auth: 'PearAdmin/admin/data/permission.json' // 前端权限限度,false 敞开该性能
};
var setting = {elem: 'social'}
pearSocial.render(setting);
pearAdmin.render(config);
})
</script>
</body>
</html>
因为这里默认的 index 界面是 console1.html,所以 console1.html 里的资源和 json 也要从新引入,这里就不放出代码了。
Pear 自带了一些 json 数据,这里咱们先用他的,把门路改成本人我的项目的。新建一个 HelloController,在外面配置下路由
@Controller
public class HelloController {@GetMapping(value = "/console/console1")
@ApiOperation(value = "转发 console1 申请")
public String console1(){return "console/console1";}
@GetMapping(value = "/system/organization")
public String organization(){return "system/organization";}
@GetMapping(value = "/system/user")
public String user(){return "system/user";}
@GetMapping(value = "/system/role")
public String role(){return "system/role";}
@GetMapping(value = "/system/power")
public String power(){return "system/power";}
@GetMapping(value = "/page/comment")
public String comment(){return "page/comment";}
}
咱们启动我的项目,看一下成果
Pear 的菜单是通过 menu.json 来动静生成的。之后的这个数据须要后端返回,然而我先用这个假数据。我把我批改过的 menu.json 贴上来,防止有些同学页面出不来。
[{
"id": 1,
"title": "工作空间",
"type": 0,
"icon": "layui-icon layui-icon-console",
"href": "","children": [{"id": 0,"title":" 管制后盾 ","icon":"layui-icon layui-icon-console","type": 1,"openType":"_iframe","href":"console/console1"}]
},
{
"id": 4,
"title": "系统管理",
"icon": "layui-icon layui-icon-set-fill",
"type": 0,
"href": "","children": [{"id": 44,"title":" 部门治理 ","icon":"layui-icon layui-icon-username","type": 1,"openType":"_iframe","href":"system/organization"},{"id": 41,"title":" 用户治理 ","icon":"layui-icon layui-icon-username","type": 1,"openType":"_iframe","href":"system/user"},
{
"id": 42,
"title": "角色治理",
"icon": "layui-icon layui-icon-user",
"type": 1,
"openType": "_iframe",
"href": "system/role"
},
{
"id": 43,
"title": "权限治理",
"icon": "layui-icon layui-icon-user",
"type": 1,
"openType": "_iframe",
"href": "system/power"
}
]
},
{
"id": 2,
"title": "扩大组件",
"icon": "layui-icon layui-icon-component",
"type": 0,
"href": "","children": [
{
"id": 22,
"title": "进阶组件",
"icon": "layui-icon layui-icon-face-smile",
"type": 0,
"href": "view/common/message.html",
"children": [
{
"id": 225,
"title": "卡片列表",
"icon": "layui-icon layui-icon-face-smile",
"type": 1,
"openType": "_iframe",
"href": "view/common/senior/card.html"
},
{
"id": 224,
"title": "树状构造",
"icon": "layui-icon layui-icon-face-smile",
"type": 1,
"openType": "_iframe",
"href": "view/common/senior/dtree.html"
}
]
}
]
},
{
"id": 3,
"title": "罕用页面",
"icon": "layui-icon layui-icon-face-cry",
"type": 0,
"href": "","children": [{"id": 302,"title":" 登录页面 ","icon":"layui-icon layui-icon-face-smile","type": 1,"openType":"_iframe","href":"login"},
{
"id": 303,
"title": "留言板",
"icon": "layui-icon layui-icon-face-smile",
"type": 1,
"openType": "_iframe",
"href": "page/comment"
}
]
},
{
"id": "error",
"title": "谬误页面",
"icon": "layui-icon layui-icon-auz",
"type": 0,
"href": "","children": [{"id": 403,"title":"403","icon":"layui-icon layui-icon-face-smile","type": 1,"openType":"_iframe","href":"view/error/403.html"},
{
"id": 404,
"title": "404",
"icon": "layui-icon layui-icon-face-cry",
"type": 1,
"openType": "_iframe",
"href": "view/error/404.html"
},
{
"id": 500,
"title": "500",
"icon": "layui-icon layui-icon-face-cry",
"type": 1,
"openType": "_iframe",
"href": "view/error/500.html"
}
]
}
]
五、技术栈
将会波及到的技术栈(待欠缺)
1、SpringBoot
2、SpringSecurity
3、MyBatis
4、Apache Log4j2
5、JWT
6、Druid
7、Swagger
8、Redis
9、Layui
10、Pear Admin Layui
等
六、阐明
以上源代码同步在 gitee 和 github 中,如果能够的话,请给我一个 star,谢谢
七、我的项目截图
Admin 端 | |
---|---|
八、请作者喝杯咖啡
支付宝 | 微信 |
---|---|
<img src=”https://imgconvert.csdnimg.cn/aHR0cHM6Ly9naXRlZS5jb20vd2l0bXkvbXktc3ByaW5nc2VjdXJpdHktcGx1cy9yYXcvbWFzdGVyL2RvY3MvaW1hZ2VzLyVFNiU5NCVBRiVFNCVCQiU5OCVFNSVBRSU5RC5qcGc?x-oss-process=image/format,png” width=”100px” hight=”100px”> | <img src=”https://imgconvert.csdnimg.cn/aHR0cHM6Ly9naXRlZS5jb20vd2l0bXkvbXktc3ByaW5nc2VjdXJpdHktcGx1cy9yYXcvbWFzdGVyL2RvY3MvaW1hZ2VzL3dlY2hhdC5wbmc?x-oss-process=image/format,png” width=”100px” hight=”100px”> |