目錄
SpringSecurity許可權管理系統實戰—一、專案簡介和開發環境準備
SpringSecurity許可權管理系統實戰—二、日誌、介面文件等實現
SpringSecurity許可權管理系統實戰—三、主要頁面及介面實現
SpringSecurity許可權管理系統實戰—四、整合SpringSecurity(上)
SpringSecurity許可權管理系統實戰—五、整合SpringSecurity(下)
SpringSecurity許可權管理系統實戰—六、SpringSecurity整合jwt
SpringSecurity許可權管理系統實戰—七、處理一些問題
前言
博主的文筆有些差,大家多擔待
一、簡介
在企業應用中,認證和授權是非常重要的一部分內容,業界最出名的兩個框架就是大名鼎鼎的 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端 | |
---|---|
八、請作者喝杯咖啡
支付寶 | 微信 |
---|---|