目录

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是在多张表中都有呈现,所以咱们能够把它们抽离进去,有须要的实体类间接继承就能够了

@Datapublic 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,在外面配置下路由

@Controllerpublic 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">