SpringSecurity权限管理系统实战—一、项目简介和开发环境准备
SpringSecurity权限管理系统实战—二、日志、接口文档等实现
SpringSecurity权限管理系统实战—三、主要页面及接口实现
SpringSecurity权限管理系统实战—四、整合SpringSecurity(上)
SpringSecurity权限管理系统实战—五、整合SpringSecurity(下)
SpringSecurity权限管理系统实战—六、SpringSecurity整合JWT
SpringSecurity权限管理系统实战—七、处理一些问题
SpringSecurity权限管理系统实战—八、AOP 记录用户日志、异常日志
SpringSecurity权限管理系统实战—九、数据权限的配置
博主的文笔有些差,大家多担待,在本篇文章结尾可看已完成的效果
在企业应用中,认证和授权是非常重要的一部分内容,业界最出名的两个框架就是大名鼎鼎的 Shiro和Spring Security。本次我选取的是和SpringBoot更好兼容的SpringSecurity。
RBAC是Role Based Access Control的缩写,是基于角色的访问控制。一般都是分为用户(user), 角色(role),权限(permission)三个实体,角色(role)和权限(permission)是多对多的 关系,用户(user)和角色(role)也是多对多的关系。用户(user)和权限(permission) 之间没有直接的关系,都是通过角色作为代理,才能获取到用户(user)拥有的权限。
以下是RBAC0的模型
由于本系统是边开发写此文档的,所以可能上述的功能在后续的开发中会有删改。
本次系统非前后端分离项目,基于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端 | |
---|---|
联系客服