目錄
SpringSecurity權(quán)限管理系統(tǒng)實戰(zhàn)—一、項目簡介和開發(fā)環(huán)境準備
SpringSecurity權(quán)限管理系統(tǒng)實戰(zhàn)—二、日志昧碉、接口文檔等實現(xiàn)
SpringSecurity權(quán)限管理系統(tǒng)實戰(zhàn)—三、主要頁面及接口實現(xiàn)
SpringSecurity權(quán)限管理系統(tǒng)實戰(zhàn)—四阴孟、整合SpringSecurity(上)
SpringSecurity權(quán)限管理系統(tǒng)實戰(zhàn)—五晌纫、整合SpringSecurity(下)
SpringSecurity權(quán)限管理系統(tǒng)實戰(zhàn)—六、SpringSecurity整合jwt
SpringSecurity權(quán)限管理系統(tǒng)實戰(zhàn)—七永丝、處理一些問題
SpringSecurity權(quán)限管理系統(tǒng)實戰(zhàn)—八锹漱、AOP記錄用戶、異常日志
SpringSecurity權(quán)限管理系統(tǒng)實戰(zhàn)—九慕嚷、數(shù)據(jù)權(quán)限的配置
前言
博主的文筆有些差哥牍,大家多擔待
一、簡介
? 在企業(yè)應用中喝检,認證和授權(quán)是非常重要的一部分內(nèi)容嗅辣,業(yè)界最出名的兩個框架就是大名鼎鼎的 Shiro和Spring Security。本次我選取的是和SpringBoot更好兼容的SpringSecurity挠说。
二澡谭、什么是RBAC
? RBAC是Role Based Access Control的縮寫,是基于角色的訪問控制损俭。一般都是分為用戶(user)蛙奖, 角色(role),權(quán)限(permission)三個實體杆兵,角色(role)和權(quán)限(permission)是多對多的 關(guān)系雁仲,用戶(user)和角色(role)也是多對多的關(guān)系。用戶(user)和權(quán)限(permission) 之間沒有直接的關(guān)系琐脏,都是通過角色作為代理攒砖,才能獲取到用戶(user)擁有的權(quán)限缸兔。
? 以下是RBAC0的模型
三、系統(tǒng)功能
- 用戶管理:提供用戶的相關(guān)配置
- 角色管理:對權(quán)限與菜單進行分配
- 菜單管理:已實現(xiàn)菜單動態(tài)路由吹艇,后端可配置化惰蜜,支持多級菜單
- 字典管理:可維護常用一些固定的數(shù)據(jù)
- 系統(tǒng)日志:記錄用戶操作日志與異常日志
- SQL監(jiān)控:采用druid 監(jiān)控數(shù)據(jù)庫訪問性能
- 代碼生成:高靈活度生成前后端代碼,減少大量重復的工作任務
- 接口管理:方便統(tǒng)一查看管理接口
由于本系統(tǒng)是邊開發(fā)寫此文檔的掐暮,所以可能上述的功能在后續(xù)的開發(fā)中會有刪改蝎抽。
四、環(huán)境搭建
本次系統(tǒng)非前后端分離項目路克,基于SpringBoot+Layui,后臺模板選用的是Pear Admin Layui (我目前見過最漂亮的layui后臺模板樟结,放張圖片讓大家感受一下)
數(shù)據(jù)庫設(shè)計
目前先這樣,之后還會擴展精算。
在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>
在項目中把架構(gòu)搭好瓢宦,創(chuàng)建對應數(shù)據(jù)庫表的eneity、dao灰羽、service驮履、controller,非常簡單不想占用篇幅廉嚼。需要注意的就是實體類中的create_time,和update_time,由于這兩個和id是在多張表中都有出現(xiàn)玫镐,所以我們可以把它們抽離出來,有需要的實體類直接繼承就可以了
@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 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 關(guān)閉
control: false, // 是 否 開 啟 多 系 統(tǒng) 菜 單 true 開啟 false 關(guān)閉
theme: "dark-theme", // 默 認 主 題 樣 式 dark-theme 默認主題 light-theme 亮主題
index: '/console/console1', // 默 認 加 載 主 頁,這里需要該
data: 'PearAdmin/admin/data/menu.json', // 菜 單 數(shù) 據(jù) 加 載 地 址
select: '0', // 默 認 選 中 菜 單 項
notice: 'PearAdmin/admin/data/notice.json', // 消 息 列 表 數(shù) 據(jù)
auth: 'PearAdmin/admin/data/permission.json' // 前端權(quán)限限制,false 關(guān)閉該功能
};
var setting = {
elem: 'social'
}
pearSocial.render(setting);
pearAdmin.render(config);
})
</script>
</body>
</html>
因為這里默認的index界面是console1.html阳仔,所以console1.html里的資源和json也要重新引入忧陪,這里就不放出代碼了。
Pear自帶了一些json數(shù)據(jù)近范,這里我們先用他的嘶摊,把路徑改成自己項目的。新建一個HelloController顺又,在里面配置下路由
@Controller
public class HelloController {
@GetMapping(value = "/console/console1")
@ApiOperation(value = "轉(zhuǎn)發(fā)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來動態(tài)生成的等孵。之后的這個數(shù)據(jù)需要后端返回稚照,但是我先用這個假數(shù)據(jù)。我把我修改過的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": "系統(tǒng)管理",
"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": "權(quán)限管理",
"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": "樹狀結(jié)構(gòu)",
"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"
}
]
}
]
五上枕、技術(shù)棧
將會涉及到的技術(shù)棧(待完善)
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端 | |
---|---|