springboot、shiro、vue、elementUI CDN模式前后端分离的权限管理demo 附源码

2 篇文章 0 订阅
1 篇文章 0 订阅

整体效果

springboot、shiro、vue、elementUI CDN模式前后端分离的权限管理demo

源码下载地址

https://github.com/Aizhuxueliang/springboot_shiro.git
open

前提你电脑的安装好这些工具:jdk8、idea、maven、git、mysql

shiro的主要概念

  1. Shiro是一个强大的简单易用的Java安全框架,主要用来更便捷的认证、授权、加密、会话管理、与Web集成、缓存等;
  2. Shiro使用起来小而简单;
  3. spring中有spring security ,是一个权限框架,它和spring依赖过于紧密,没有shiro使用简单;
  4. shiro不依赖于spring,shiro不仅可以实现web应用的权限管理,还可以实现c/s系统,分布式系统权限管理;

在应用程序角度来观察如何使用Shiro完成工作

subject

Subject:主体,代表了当前“用户”,这个用户不一定是一个具体的人,与当前应用交互的任何东西都是Subject,如网络爬虫,机器人等;即一个抽象概念;所有Subject 都绑定到SecurityManager,与Subject的所有交互都会委托给SecurityManager;可以把Subject认为是一个门面;SecurityManager才是实际的执行者;

SecurityManager:安全管理器;即所有与安全有关的操作都会与SecurityManager 交互;且它管理着所有Subject;可以看出它是Shiro 的核心,它负责与后边介绍的其他组件进行交互,如果学习过SpringMVC,你可以把它看成DispatcherServlet前端控制器;

Realm:域,Shiro从从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看成DataSource,即安全数据源。

shiro官方文档

https://shiro.apache.org/architecture.html

前端CDN的方式使用elementUI、vue、vue-router、axios画页面

CDN(内容分发网络)本身是指一种请求资源的方式。说白了就是在本地,通过script头去请求对应的脚本资源的一种方式。我在这里要说的就是直接引用 (demo是直接引用的,注意电脑联网)或者下载Vue.js和elementUI.js放在本地,进行项目开发的方式。而不是通过npm包管理工具去下载vue包。

cdn方式引入elementui 官方API:https://element.eleme.cn/#/zh-CN/component/installation
在这里插入图片描述
cdn方式引入vue-router官方API:https://router.vuejs.org/zh/guide/#html
router

DEMO的整体流程设计

技术层面了解完就该设计业务流程了,如图:
process

demo整体结构

如图:
struct

主要功能页面

1、登录
login

2、用户查询
query_user

3、分配角色
allot_role

4、删除角色
remove_role

5、新建用户
create_user
create_user_1

6、分配权限
allot_permission

7、新建角色
create_role

主要代码

com/example/demo/controller/UserCtrl.java

package com.example.demo.controller;

import com.example.demo.entity.Role;
import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Map;

/**
 * 控制层
 */
@RestController
@RequestMapping("/user")
public class UserCtrl {

    @Autowired
    private UserService userService;

    /**
     * 登录接口
     *
     * @param user user
     * @return resultMap
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public Map<String, Object> login(@RequestBody User user) {
        //拿到主体
        Subject subject = SecurityUtils.getSubject();
        try {
            UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(user.getUsername(), user.getPassword());
            subject.login(usernamePasswordToken);
            Object permissions = subject.getSession().getAttribute("permissions");
            subject.getSession().removeAttribute("permissions");
            return userService.resultMap("permissions", permissions, "token",  subject.getSession().getId(), "", "");
        }catch (Exception e){
            e.printStackTrace();
            return userService.resultMap("error", e.getMessage(), "",  "", "", "");
        }
    }

    /**
     * 获取用户的角色类型
     *
     * @param user user
     * @return resultMap
     */
    @RequestMapping(value = "/findRoleListByUserId", method = RequestMethod.POST)
    public Map<String, Object> findRoleListByUserId(@RequestBody User user) {
        try{
            return userService.findRoleListByUserId(user.getId());
        }catch (Exception e){
            e.printStackTrace();
            return userService.resultMap("error", e.getMessage(), "",  "", "", "");
        }
    }

    /**
     * 获取角色的权限类型
     *
     * @param role role
     * @return resultMap
     */
    @RequestMapping(value = "/findPermissionListByRoleId", method = RequestMethod.POST)
    public Map<String, Object> findPermissionListByRoleId(@RequestBody Role role) {
        try{
            return userService.findPermissionListByRoleId(role.getId());
        }catch (Exception e){
            e.printStackTrace();
            return userService.resultMap("error", e.getMessage(), "",  "", "", "");
        }
    }

    /**
     * 更新角色具有的权限
     *
     * @param role role
     * @return resultMap
     */
    @RequestMapping(value = "/updateRolePermission", method = RequestMethod.POST)
    public Map<String, Object> updateRolePermission(@RequestBody Role role) {
        try{
            return userService.updateRolePermission(role);
        }catch (Exception e){
            e.printStackTrace();
            return userService.resultMap("error", e.getMessage(), "",  "", "", "");
        }
    }

    /**
     * 删除角色
     *
     * @param role role
     * @return resultMap
     */
    @RequestMapping(value = "/removeRole", method = RequestMethod.POST)
    public Map<String, Object> removeRole(@RequestBody Role role) {
        try{
            return userService.removeRole(role);
        }catch (Exception e){
            e.printStackTrace();
            return userService.resultMap("error", e.getMessage(), "",  "", "", "");
        }
    }

    /**
     * 添加角色
     *
     * @param role role
     * @return resultMap
     */
    @RequestMapping(value = "/addRole", method = RequestMethod.POST)
    public Map<String, Object> addRole(@RequestBody Role role) {
        try{
            return userService.addRole(role);
        }catch (Exception e){
            e.printStackTrace();
            return userService.resultMap("error", e.getMessage(), "",  "", "", "");
        }
    }

    /**
     * 更新用户具有的角色
     *
     * @param user user
     * @return resultMap
     */
    @RequestMapping(value = "/updateUserRole", method = RequestMethod.POST)
    public Map<String, Object> updateUserRole(@RequestBody User user) {
        try{
            return userService.updateUserRole(user);
        }catch (Exception e){
            e.printStackTrace();
            return userService.resultMap("error", e.getMessage(), "",  "", "", "");
        }
    }

    /**
     * 根据用户提供的条件分页查询用户
     *
     * @param user user
     * @return resultMap
     */
    @RequestMapping(value = "/queryUserListPage", method = RequestMethod.POST)
    public Map<String, Object> queryUserListPage(@RequestBody User user) {
        try{
            return userService.queryUserListPage(user);
        }catch (Exception e){
            e.printStackTrace();
            return userService.resultMap("error", e.getMessage(), "",  "", "", "");
        }
    }

    /**
     * 删除用户
     *
     * @param user user
     * @return resultMap
     */
    @RequestMapping(value = "/removeUser", method = RequestMethod.POST)
    public Map<String, Object> removeUser(@RequestBody User user) {
        try{
            return userService.removeUser(user);
        }catch (Exception e){
            e.printStackTrace();
            return userService.resultMap("error", e.getMessage(), "",  "", "", "");
        }
    }

    /**
     * 新增用户
     *
     * @param user user
     * @return resultMap
     */
    @RequestMapping(value = "/insertUser", method = RequestMethod.POST)
    public Map<String, Object> insertUser(@RequestBody User user) {
        try{
            return userService.insertUser(user);
        }catch (Exception e){
            e.printStackTrace();
            return userService.resultMap("error", e.getMessage(), "",  "", "", "");
        }
    }

}

com/example/demo/service/UserService.java

package com.example.demo.service;

import com.example.demo.entity.Permission;
import com.example.demo.entity.Role;
import com.example.demo.entity.User;
import com.example.demo.mapper.PermissionMapper;
import com.example.demo.mapper.UserMapper;
import com.example.demo.mapper.RoleMapper;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 服务层
 */
@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private PermissionMapper permissionMapper;

    public User findUserByName(String userName) {
        User user = userMapper.findUserByName(userName);
        //用户角色的集合
        List<Role> roleList = roleMapper.findRoleListByUserId(user.getId());
        user.setRoleList(roleList);
        return user;
    }

    public Map<String, Object> findRoleListByUserId(int userId){
        //用戶具有的角色集合
        List<Role> beRoleList = roleMapper.findRoleListByUserIdNotPermission(userId);
        //用戶没有的角色集合
        List<Role> notRoleList = roleMapper.findNotRoleListByUserIdNotPermission(userId);
        //所有角色集合
        Collection<?> allRoleList = CollectionUtils.union(beRoleList, notRoleList);
        return this.resultMap("beRoleList", beRoleList, "notRoleList", notRoleList, "allRoleList", allRoleList);
    }

    @Transactional(rollbackFor = {Exception.class})
    public Map<String, Object> updateUserRole(User user){
        int removeUserRole = userMapper.removeUserRoleByUserId(user.getId());
        int addUserRole = 0;
        if (user.getRoleList().size()!=0 && user.getRoleList()!=null){
            addUserRole = userMapper.addUserRole(user);
        }
        return this.resultMap("removeUserRole", removeUserRole, "addUserRole", addUserRole, "", "");
    }

    public Map<String, Object> findPermissionListByRoleId(int roleId){
        //角色具有的权限集合
        List<Permission> bePermissionList = permissionMapper.findByPermissionListByRoleId(roleId);
        //角色没有的权限集合
        List<Permission> notPermissionList = permissionMapper.findNotPermissionListByRoleId(roleId);
        //所有权限集合
        Collection<?> allPermissionList = CollectionUtils.union(bePermissionList, notPermissionList);
        return this.resultMap("bePermissionList", bePermissionList, "notPermissionList", notPermissionList, "allPermissionList", allPermissionList);
    }

    @Transactional(rollbackFor = {Exception.class})
    public Map<String, Object> updateRolePermission(Role role){
        int removeRolePermission = roleMapper.removeRolePermissionByRoleId(role.getId());
        int addRolePermission = 0;
        if (role.getPermissionList().size()!=0 && role.getPermissionList()!=null){
            addRolePermission = roleMapper.addRolePermission(role);
        }
        return this.resultMap("removeRolePermission", removeRolePermission, "addRolePermission", addRolePermission, "", "");
    }

    @Transactional(rollbackFor = {Exception.class})
    public Map<String, Object> removeRole(Role role){
        int removeRolePermission = roleMapper.removeRolePermissionByRoleId(role.getId());
        int removeRole = roleMapper.removeRoleByRoleId(role.getId());
        int removeUserRole = userMapper.removeUserRoleByRoleId(role.getId());
        return this.resultMap("removeRolePermission", removeRolePermission, "removeRole", removeRole, "removeUserRole", removeUserRole);
    }

    public Map<String, Object> queryUserListPage(User user){
        //当前页页码
        int pageNow = user.getReserve1() < 1 ? 1 : user.getReserve1();
        //当前页第一行索引
        user.setReserve1(5*(pageNow - 1));
        List<User> userListPage = userMapper.queryUserListPage(user);
        int userRowCount = userMapper.getUserRowCount(user);
        return this.resultMap("userListPage", userListPage, "userRowCount",  userRowCount, "", "");
    }

    public Map<String, Object> addRole(Role role){
        int addRole = roleMapper.addRole(role);
        return this.resultMap("addRole", addRole, "",  "", "", "");
    }

    @Transactional(rollbackFor = {Exception.class})
    public Map<String, Object> removeUser(User user){
        int removeUser = userMapper.removeUserByUserId(user.getId());
        int removeUserRole = userMapper.removeUserRoleByUserId(user.getId());
        return this.resultMap("removeUser", removeUser, "removeUserRole", removeUserRole, "", "");
    }

    public Map<String, Object> insertUser(User user) {
        int addUser = userMapper.insertUser(user);
        return this.resultMap("addUser", addUser, "", "", "", "");
    }

    public Map<String, Object> resultMap(String str1, Object obj1, String str2, Object obj2, String str3, Object obj3){
        Map<String, Object> resultMap = new HashMap<>();
        if (!"".equals(str1) || !"".equals(obj1))
            resultMap.put(str1, obj1);
        if (!"".equals(str2) || !"".equals(obj2))
            resultMap.put(str2, obj2);
        if (!"".equals(str3) || !"".equals(obj3))
            resultMap.put(str3, obj3);
        return resultMap;
    }

}

CDN模式下的vue、vue-router、template模板挂载操作

参考:src/main/resources/static/index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <!-- import CSS -->
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
</head>
<body>
<div id="app">
    <router-view></router-view>
</div>
<template id="sign">
    <div class="handle">
        <div class="handle-input">
            <div class="high70">
                <span>用户名称:</span>
                <el-input
                        v-model="username"
                        placeholder="请输入用户名称"
                        clearable></el-input>
            </div>
            <div class="high70">
                <span>密码:</span>
                <el-input
                        v-model="password"
                        placeholder="请输入密码"
                        clearable
                        show-password></el-input>
            </div>
            <el-button @click="login" plain>登录</el-button>
        </div>
    </div>
</template>
<template id="manager">
    <el-tabs :tab-position="tabPosition">
        <el-tab-pane label="用户设置" v-if="permissionsFlag.query_user || permissionsFlag.add_user || permissionsFlag.allot_roles || permissionsFlag.remove_user">
            <el-row type="flex" justify="center">
                <el-col :span="18">
                    <div class="handle-area">
                        <div class="demo-input" v-show="permissionsFlag.query_user || permissionsFlag.add_user || permissionsFlag.allot_roles || permissionsFlag.remove_user">
                            <span>用户ID:</span>
                            <el-input
                                    v-model="id"
                                    placeholder="请输入用户ID"
                                    type="number"
                                    size="medium"
                                    clearable></el-input>
                            <span>用户名称:</span>
                            <el-input
                                    v-model="username"
                                    placeholder="请输入用户名称"
                                    size="medium"
                                    clearable></el-input>
                            <el-button
                                    :plain="true"
                                    @click="queryUserList"
                                    icon="el-icon-search"
                                    size="medium">查询用户</el-button>
                        </div>
                        <el-button
                                v-show="permissionsFlag.add_user"
                                :plain="true"
                                @click="handleAddUser"
                                icon="el-icon-user"
                                size="medium">新建用户</el-button>
                    </div>
                    <el-table
                            :data="tableData"
                            border
                            highlight-current-row>
                        <el-table-column
                                prop="id"
                                label="用户ID">
                        </el-table-column>
                        <el-table-column
                                prop="username"
                                label="用户名称">
                        </el-table-column>
                        <el-table-column
                                label="操作">
                            <template slot-scope="scope">
                                <el-button
                                        v-show="permissionsFlag.allot_roles"
                                        type="text"
                                        icon="el-icon-set-up"
                                        @click="handleEditUser(scope.$index, scope.row)">分配角色
                                </el-button>
                                <el-button
                                        v-show="permissionsFlag.remove_user"
                                        type="text"
                                        icon="el-icon-remove-outline"
                                        @click="handleDeleteUser(scope.$index, scope.row)">删除用户
                                </el-button>
                            </template>
                        </el-table-column>
                    </el-table>
                    <el-pagination
                            layout="total, prev, pager, next, jumper"
                            :total="userRowCount"
                            :page-size="5"
                            :current-page.sync="currentPage"
                            @current-change="queryUserListPage"
                            :hide-on-single-page="hidePageFlag"
                            background>
                    </el-pagination>
                </el-col>
            </el-row>
            <el-dialog :title="roleTitle" :visible.sync="dialogEditUser" :before-close="handleClose">
                <el-transfer
                        v-model="transferValue"
                        :data="transferData"
                        :titles="['待分配角色', '已分配角色']">
                </el-transfer>
                <span slot="footer" class="dialog-footer">
			        <el-button @click="handleClose">取 消</el-button>
			        <el-button type="primary" @click="assignRoles">确 定</el-button>
		        </span>
            </el-dialog>
            <el-dialog title="新建用户" :visible.sync="dialogAddUser" :before-close="handleClose">
                <div class="high70">
                    <span>用户名称:</span>
                    <el-input
                            v-model="username"
                            placeholder="请输入用户名称"
                            size="medium"
                            clearable></el-input>
                </div>
                <div class="high70">
                    <span>密码:</span>
                    <el-input
                            v-model="password"
                            placeholder="请输入密码"
                            size="medium"
                            clearable
                            show-password></el-input>
                </div>
                <div class="high70">
                    <span>再次输入密码:</span>
                    <el-input
                            v-model="password1"
                            placeholder="请再次输入密码"
                            size="medium"
                            show-password></el-input>
                </div>
                <div class="high70">
                    <span>备注:</span>
                    <el-input
                            v-model="reserve"
                            placeholder="请输入用户备注"
                            size="medium"></el-input>
                </div>
                <span slot="footer" class="dialog-footer">
			        <el-button @click="handleClose">取 消</el-button>
			        <el-button type="primary" @click="insertUser">确 定</el-button>
		        </span>
            </el-dialog>
        </el-tab-pane>

        <el-tab-pane label="角色设置" v-if="permissionsFlag.allot_roles || permissionsFlag.query_role || permissionsFlag.add_role || permissionsFlag.remove_role || permissionsFlag.allot_permission">
            <el-row type="flex" justify="center">
                <el-col :span="18">
                    <div class="handle-area">
                        <el-button
                                v-show="permissionsFlag.allot_roles || permissionsFlag.query_role || permissionsFlag.add_role || permissionsFlag.remove_role || permissionsFlag.allot_permission"
                                :plain="true"
                                @click="queryRoleList"
                                icon="el-icon-search"
                                size="medium">角色查询</el-button>
                        <el-button
                                v-show="permissionsFlag.add_role"
                                :plain="true"
                                @click="handleAddRole"
                                icon="el-icon-circle-plus-outline"
                                size="medium">新建角色</el-button>
                    </div>
                    <el-table
                            :data="roleData"
                            border
                            highlight-current-row>
                        <el-table-column
                                prop="id"
                                label="角色ID">
                        </el-table-column>
                        <el-table-column
                                prop="name"
                                label="角色名称">
                        </el-table-column>
                        <el-table-column
                                prop="description"
                                label="角色描述">
                        </el-table-column>
                        <el-table-column
                                label="操作">
                            <template slot-scope="scope">
                                <el-button
                                        v-show="permissionsFlag.allot_permission"
                                        type="text"
                                        icon="el-icon-s-operation"
                                        @click="handleEditRole(scope.$index, scope.row)">分配权限
                                </el-button>
                                <el-button
                                        v-show="permissionsFlag.remove_role"
                                        type="text"
                                        icon="el-icon-remove-outline"
                                        @click="handleDeleteRole(scope.$index, scope.row)">删除角色
                                </el-button>
                            </template>
                        </el-table-column>
                    </el-table>
                </el-col>
            </el-row>
            <el-dialog :title="permissionsTitle" :visible.sync="dialogEditRole" :before-close="handleClose">
                <el-checkbox-group v-model="checkedPermissions" class="el-checkbox-group-dialog">
                    <el-checkbox v-for="permission in permissions" :label="permission.name" :key="permission.name">{{permission.description}}</el-checkbox>
                </el-checkbox-group>
                <span slot="footer" class="dialog-footer">
			        <el-button @click="handleClose">取 消</el-button>
			        <el-button type="primary" @click="assignPermissions">确 定</el-button>
		        </span>
            </el-dialog>
            <el-dialog title="新建角色" :visible.sync="dialogAddRole" :before-close="handleClose">
                <div class="high70">
                    <span>角色名称:</span>
                    <el-input
                            v-model="name"
                            placeholder="请输入角色名称"
                            size="medium"></el-input>
                </div>
                <div class="high70">
                    <span>角色描述:</span>
                    <el-input
                            v-model="description"
                            placeholder="请输入角色描述"
                            size="medium"></el-input>
                </div>
                <span slot="footer" class="dialog-footer">
			        <el-button @click="handleClose">取 消</el-button>
			        <el-button type="primary" @click="insertRole">确 定</el-button>
		        </span>
            </el-dialog>
        </el-tab-pane>

        <el-tab-pane label="权限列表" v-if="permissionsFlag.allot_permission">
            <el-row type="flex" justify="center">
                <el-col :span="18">
                    <div class="handle-area">
                        <el-button
                                v-show="permissionsFlag.allot_permission"
                                :plain="true"
                                @click="queryPermissionList"
                                icon="el-icon-search"
                                size="medium">权限查询</el-button>
                    </div>
                    <el-table
                            :data="permissionData"
                            border
                            highlight-current-row>
                        <el-table-column
                                prop="id"
                                label="权限ID">
                        </el-table-column>
                        <el-table-column
                                prop="name"
                                label="权限名称">
                        </el-table-column>
                        <el-table-column
                                prop="description"
                                label="权限描述">
                        </el-table-column>
                    </el-table>
                </el-col>
            </el-row>
        </el-tab-pane>
    </el-tabs>
</template>
</body>
<!-- import Vue before Element -->
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
<!-- import JavaScript -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<!-- import Axios -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<!-- import Router -->
<script src="https://cdn.staticfile.org/vue-router/2.7.0/vue-router.min.js"></script>
<script>
    const Sign = {
        props: ['todo'],
        template: '#sign',
        data() {
            return {
                username: '',
                password: '',
                permissionsStr: [],
                token: ''
            }
        },
        methods: {
            login() {
                axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
                axios({
                    method: 'post',
                    url: '/user/login',
                    data: JSON.stringify({
                        username: this.username,
                        password: this.password
                    })
                }).then(response => {
                    if(typeof response.data.error !== 'undefined' || response.data.error != null){
                        this.username = '';
                        this.password = '';
                        ELEMENT.Notification.error({
                            title: '登录失败!',
                            message: response.data.error,
                            position: 'top-right',
                            showClose: false,
                            offset: 110
                        });
                        return;
                    }
                    this.permissionsStr = response.data.permissions;
                    this.token = response.data.token;
                    this.$router.push({
                        name: 'manager',
                        params: {
                            token: this.token,
                            permissionsStr: this.permissionsStr
                        }
                    });
                }).catch(error => {
                    console.log(error);
                    ELEMENT.Message(error);
                });
            }
        },
        mounted() {
            console.log('组件Sign被挂载了');
        }
    };
    const Manager = {
        // todo-item 组件现在接受一个
        // "prop",类似于一个自定义 attribute。
        // 这个 prop 名为 todo。
        props: ['todo'],
        template: '#manager',
        data() {
            return {
                // 角色信息
                roleData: [],
                roleId: null,
                name: '',
                description: '',
                dialogEditRole: false,
                dialogAddRole: false,
                permissions: [],
                checkedPermissions: [],
                permissionList: [],
                permissionsTitle: '',
                // 权限信息
                permissionData: [],
                // 穿梭框
                transferValue: [],
                transferData: [],
                // 表格及分页
                tableData: [],
                tabPosition: 'top',
                userRowCount: 0,
                currentPage: 0,
                hidePageFlag: true,
                // 弹框
                dialogEditUser: false,// 分配角色弹框
                dialogAddUser: false,// 新建用户弹框
                // 用户信息
                allRoleList: [],
                roleList: [],
                id: null,
                username: '',
                password: '',
                password1: '',
                reserve: '',
                roleTitle: '',
                permissionsStr: [],
                permissionsFlag: {
                    query_user: false,
                    add_user: false,
                    remove_user: false,
                    allot_roles: false,
                    query_role: false,
                    add_role: false,
                    remove_role: false,
                    allot_permission: false
                },
                token: ''

            }
        },
        methods: {
            queryPermissionList() {
                axios.defaults.headers.token = this.token;
                axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
                axios({
                    method: 'post',
                    url: '/user/findPermissionListByRoleId',
                    data: JSON.stringify({
                        id: 0
                    })
                }).then(response => {
                    if(typeof response.data.error !== 'undefined' || response.data.error != null){
                        ELEMENT.Notification.error({
                            title: '查询失败!',
                            message: response.data.error,
                            position: 'top-right',
                            showClose: false,
                            offset: 110
                        });
                        return;
                    }
                    this.permissionData = response.data.allPermissionList;
                }).catch(error => {
                    console.log(error);
                    ELEMENT.Message(error);
                });
            },
            queryRoleList() {
                axios.defaults.headers.token = this.token;
                axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
                axios({
                    method: 'post',
                    url: '/user/findRoleListByUserId',
                    data: JSON.stringify({
                        id: 0
                    })
                }).then(response => {
                    if(typeof response.data.error !== 'undefined' || response.data.error != null){
                        ELEMENT.Notification.error({
                            title: '查询失败!',
                            message: response.data.error,
                            position: 'top-right',
                            showClose: false,
                            offset: 110
                        });
                        return;
                    }
                    this.roleData = response.data.allRoleList;
                }).catch(error => {
                    console.log(error);
                    ELEMENT.Message(error);
                });

            },
            handleEditRole(index, row){
                axios.defaults.headers.token = this.token;
                axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
                axios({
                    method: 'post',
                    url: '/user/findPermissionListByRoleId',
                    data: JSON.stringify({
                        id: row.id
                    })
                }).then(response => {
                    console.log(response.data);
                    if(typeof response.data.error !== 'undefined' || response.data.error != null){
                        ELEMENT.Notification.error({
                            title: '查询失败!',
                            message: response.data.error,
                            position: 'top-right',
                            showClose: false,
                            offset: 110
                        });
                        return;
                    }
                    this.permissions = response.data.allPermissionList;
                    for(let item of response.data.bePermissionList){
                        this.checkedPermissions.push(item.name);
                    }
                    this.roleId = row.id;
                    this.name = row.name;
                    this.permissionsTitle = '为角色'+row.name+'分配权限';
                    this.dialogEditRole = true;
                }).catch(error => {
                    console.log(error);
                    ELEMENT.Message(error);
                });
            },
            handleDeleteRole(index, row){
                ELEMENT.MessageBox.confirm('此操作将永久删除角色'+row.name+', 是否继续?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    axios.defaults.headers.token = this.token;
                    axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
                    axios({
                        method: 'post',
                        url: '/user/removeRole',
                        data: JSON.stringify({
                            id: row.id
                        })
                    }).then(response => {
                        if(typeof response.data.error !== 'undefined' || response.data.error != null){
                            ELEMENT.Notification.error({
                                title: '角色'+row.name+',删除失败!',
                                message: response.data.error,
                                position: 'top-right',
                                showClose: false,
                                offset: 110
                            });
                            return;
                        }
                        if (response.data.removeRolePermission >= 0 && response.data.removeRole >= 0 && response.data.removeUserRole >= 0) {
                            this.queryRoleList();
                            ELEMENT.Notification({
                                title: '删除成功',
                                message: '角色'+row.name+',删除成功!',
                                type: 'success',
                                position: 'top-right',
                                showClose: false,
                                offset: 110
                            });
                        }
                    }).catch(error => {
                        ELEMENT.Message({ type: 'info', message: error});
                    });
                }).catch(() => {
                    ELEMENT.Message({ type: 'info', message: '已取消删除'});
                });
            },
            handleAddRole(){
                this.dialogAddRole = true;
                this.name = '';
                this.description = '';
            },
            insertRole(){
                axios.defaults.headers.token = this.token;
                axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
                axios({
                    method: 'post',
                    url: '/user/addRole',
                    data: JSON.stringify({
                        name: this.name,
                        description: this.description
                    })
                }).then(response => {
                    if(typeof response.data.error !== 'undefined' || response.data.error != null){
                        ELEMENT.Notification.error({
                            title: '角色'+this.name+',添加失败!',
                            message: response.data.error,
                            position: 'top-right',
                            showClose: false,
                            offset: 110
                        });
                        this.dialogAddRole = false;
                        this.name = '';
                        this.description = '';
                        return;
                    }
                    if(response.data.addRole > 0) {
                        this.queryRoleList();
                        ELEMENT.Notification({
                            title: '添加成功',
                            message: '角色'+this.name+',添加成功!',
                            type: 'success',
                            position: 'top-right',
                            showClose: false,
                            offset: 110
                        });
                        this.dialogAddRole = false;
                        this.name = '';
                        this.description = '';
                    }
                    console.log(response.data);
                }).catch(error => {
                    ELEMENT.Message({ type: 'info', message: error});
                });
            },
            assignPermissions(){
                for(let item of this.permissions){
                    for(let i in this.checkedPermissions){
                        if (this.checkedPermissions[i] == item.name) {
                            this.permissionList.push(item);
                        }
                    }
                }
                axios.defaults.headers.token = this.token;
                axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
                axios({
                    method: 'post',
                    url: '/user/updateRolePermission',
                    data: JSON.stringify({
                        id: this.roleId,
                        permissionList: this.permissionList,
                    })
                }).then(response => {
                    if(typeof response.data.error !== 'undefined' || response.data.error != null){
                        this.dialogEditRole = false;
                        ELEMENT.Notification.error({
                            title: '为角色'+this.name+',分配权限失败!',
                            message: response.data.error,
                            position: 'top-right',
                            showClose: false,
                            offset: 110
                        });
                        this.roleId = null;
                        this.name = null;
                        this.permissions = [];
                        this.checkedPermissions = [];
                        this.permissionList = [];
                        this.permissionsTitle = '';
                        return;
                    }
                    if (response.data.removeRolePermission >= 0 && response.data.addRolePermission >= 0) {
                        this.dialogEditRole = false;
                        ELEMENT.Notification({
                            title: '更新成功',
                            message: '为角色'+this.name+',分配权限成功!',
                            type: 'success',
                            position: 'top-right',
                            showClose: false,
                            offset: 110
                        });
                        this.roleId = null;
                        this.name = null;
                        this.permissions = [];
                        this.checkedPermissions = [];
                        this.permissionList = [];
                        this.permissionsTitle = '';
                    }
                    console.log(response.data);
                }).catch(error => {
                    console.log(error);
                    ELEMENT.Message(error);
                });
            },
            // ------------------------用户设置部分--------------
            queryUserList() {
                axios.defaults.headers.token = this.token;
                axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
                axios({
                    method: 'post',
                    url: '/user/queryUserListPage',
                    data: JSON.stringify({
                        id: this.id,
                        username: this.username
                    })
                }).then(response => {
                    if(typeof response.data.error !== 'undefined' || response.data.error != null){
                        ELEMENT.Notification.error({
                            title: '查询用户失败!',
                            message: response.data.error,
                            position: 'top-right',
                            showClose: false,
                            offset: 110
                        });
                        return;
                    }
                    console.log(response.data);
                    this.tableData = response.data.userListPage;
                    this.userRowCount = response.data.userRowCount;
                    if(this.userRowCount > 5) {
                        this.hidePageFlag = false;
                    } else {
                        this.hidePageFlag = true;
                    }
                    this.currentPage = 1;
                }).catch(error => {
                    console.log(error);
                    ELEMENT.Message(error);
                });
            },
            queryUserListPage() {
                axios.defaults.headers.token = this.token;
                axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
                axios({
                    method: 'post',
                    url: '/user/queryUserListPage',
                    data: JSON.stringify({
                        id: this.id,
                        username: this.username,
                        reserve1: this.currentPage
                    })
                }).then(response => {
                    if(typeof response.data.error !== 'undefined' || response.data.error != null){
                        ELEMENT.Notification.error({
                            title: '查询用户失败!',
                            message: response.data.error,
                            position: 'top-right',
                            showClose: false,
                            offset: 110
                        });
                        return;
                    }
                    console.log(response.data);
                    this.tableData = response.data.userListPage;
                    this.userRowCount = response.data.userRowCount;
                    if(this.userRowCount > 5) {
                        this.hidePageFlag = false;
                    } else {
                        this.hidePageFlag = true;
                    }
                }).catch(error => {
                    console.log(error);
                    ELEMENT.Message(error);
                });
            },
            handleEditUser(index, row) {
                axios.defaults.headers.token = this.token;
                axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
                axios({
                    method: 'post',
                    url: '/user/findRoleListByUserId',
                    data: JSON.stringify({
                        id: row.id
                    })
                }).then(response => {
                    if(typeof response.data.error !== 'undefined' || response.data.error != null){
                        this.dialogEditUser = false;
                        ELEMENT.Notification.error({
                            title: '为用户'+row.username+'分配角色失败!',
                            message: response.data.error,
                            position: 'top-right',
                            showClose: false,
                            offset: 110
                        });
                        return;
                    }
                    console.log(response.data);
                    for(let item of response.data.allRoleList){
                        this.transferData.push({
                            key: item.id,
                            label: item.description
                        });
                    }
                    for(let item of response.data.beRoleList){
                        this.transferValue.push(item.id);
                    }
                    this.id = row.id;
                    this.username = row.username;
                    this.allRoleList = response.data.allRoleList;
                    this.roleTitle = '为用户'+row.username+'分配角色';
                    this.dialogEditUser = true;
                }).catch(error => {
                    console.log(error);
                    ELEMENT.Message(error);
                });
            },
            assignRoles() {
                for(let item of this.allRoleList){
                    for(let i in this.transferValue){
                        if (this.transferValue[i] == item.id) {
                            this.roleList.push(item);
                        }
                    }
                }
                axios.defaults.headers.token = this.token;
                axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
                axios({
                    method: 'post',
                    url: '/user/updateUserRole',
                    data: JSON.stringify({
                        id: this.id,
                        username: this.username,
                        roleList: this.roleList
                    })
                }).then(response => {
                    if(typeof response.data.error !== 'undefined' || response.data.error != null){
                        this.dialogEditUser = false;
                        ELEMENT.Notification.error({
                            title: '为用户'+row.username+'分配角色失败!',
                            message: response.data.error,
                            position: 'top-right',
                            showClose: false,
                            offset: 110
                        });
                        this.id = null;
                        this.username = '';
                        this.allRoleList = [];
                        this.roleList = [];
                        this.transferData = [];
                        this.transferValue = [];
                        return;
                    }
                    if (response.data.removeUserRole >= 0 && response.data.addUserRole >= 0) {
                        this.dialogEditUser = false;
                        ELEMENT.Notification({
                            title: '更新成功',
                            message: '为用户'+this.username+',分配角色成功!',
                            type: 'success',
                            position: 'top-right',
                            showClose: false,
                            offset: 110
                        });
                        this.id = null;
                        this.username = '';
                        this.allRoleList = [];
                        this.roleList = [];
                        this.transferData = [];
                        this.transferValue = [];
                    }
                    console.log(response.data);
                }).catch(error => {
                    console.log(error);
                });

            },
            handleDeleteUser(index, row) {
                //this.ruleForm = Object.assign({}, row, index); //这句是关键!!!
                ELEMENT.MessageBox.confirm('此操作将永久删除用户'+row.id+', 是否继续?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    axios.defaults.headers.token = this.token;
                    axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
                    axios({
                        method: 'post',
                        url: '/user/removeUser',
                        data: JSON.stringify({
                            id: row.id
                        })
                    }).then(response => {
                        if(typeof response.data.error !== 'undefined' || response.data.error != null){
                            ELEMENT.Notification.error({
                                title: '用户'+row.username+',删除失败!',
                                message: response.data.error,
                                position: 'top-right',
                                showClose: false,
                                offset: 110
                            });
                            return;
                        }
                        if (response.data.removeUser >= 0 && response.data.removeUserRole >= 0) {
                            if(((this.userRowCount - 1) % 5 == 0) && ((this.userRowCount - 1) / 5 == (this.currentPage - 1))) {
                                this.currentPage = this.currentPage - 1;
                            }
                            this.queryUserListPage();
                            ELEMENT.Notification({
                                title: '删除成功',
                                message: '用户'+row.username+',删除成功!',
                                type: 'success',
                                position: 'top-right',
                                showClose: false,
                                offset: 110
                            });
                        }
                    }).catch(error => {
                        ELEMENT.Message({ type: 'info', message: error});
                    });
                }).catch(() => {
                    ELEMENT.Message({ type: 'info', message: '已取消删除'});
                });
            },
            handleClose() {
                // 用户设置
                this.dialogEditUser = false;
                this.dialogAddUser = false;
                this.id = null;
                this.username = '';
                this.password = '';
                this.password1 = '';
                this.reserve = '';
                this.allRoleList = [];
                this.roleList = [];
                this.transferData = [];
                this.transferValue = [];
                this.roleTitle = '';
                // 角色设置
                this.dialogEditRole = false;
                this.dialogAddRole = false;
                this.roleId = null;
                this.name = null;
                this.permissions = [];
                this.checkedPermissions = [];
                this.permissionList = [];
                this.permissionsTitle = '';
                ELEMENT.Message({
                    message: '取消操作,系统不会保留任何更改',
                    type:'warning'
                });
            },
            handleAddUser(){
                this.dialogAddUser = true;
                this.id = null;
                this.username = '';
                this.password = '';
                this.password1 = '';
                this.reserve = '';
            },
            insertUser() {
                axios.defaults.headers.token = this.token;
                axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
                axios({
                    method: 'post',
                    url: '/user/insertUser',
                    data: JSON.stringify({
                        username: this.username,
                        password: this.password,
                        reserve: this.reserve
                    })
                }).then(response => {
                    if(response.data.addUser > 0) {
                        this.dialogAddUser = false;
                        this.password = '';
                        this.password1 = '';
                        this.reserve = '';
                        this.queryUserList();
                        ELEMENT.Notification({
                            title: '添加成功',
                            message: '用户'+this.username+',添加成功!',
                            type: 'success',
                            position: 'top-right',
                            showClose: false,
                            offset: 110
                        });
                    }
                    if(typeof response.data.error !== 'undefined' || response.data.error != null){
                        this.dialogAddUser = false;
                        this.password = '';
                        this.password1 = '';
                        this.reserve = '';
                        this.queryUserList();
                        ELEMENT.Notification.error({
                            title: '用户'+this.username+',添加失败!',
                            message: response.data.error,
                            position: 'top-right',
                            showClose: false,
                            offset: 110
                        });
                        return;
                    }
                    console.log(response.data);
                }).catch(error => {
                    ELEMENT.Message({ type: 'info', message: error});
                });
            }
        },
        mounted() {
            console.log('组件Manager被挂载了');
        },
        created() {
            this.permissionsStr = this.$route.params.permissionsStr;
            this.token = this.$route.params.token;
            for(let key in this.permissionsFlag){
                for(let i in this.permissionsStr){
                    if(this.permissionsStr[i] == key){
                        this.permissionsFlag[key] = true;
                    }
                }
                console.log(key + '---' + this.permissionsFlag[key])
            }
        }
    };
    const router = new VueRouter({
        routes:[
            {
                path: '/',
                name: 'sign',
                component: Sign
            },
            {
                path: '/manager',
                name: 'manager',
                component: Manager
            }
        ]
    });
    new Vue({
        router,
        el: '#app',
        data: {},
        methods: {}
    })
</script>
<style>
    .el-pagination {
        display: flex;
        justify-content: flex-end;
        align-items: center;
        height: 60px;
    }
    .el-transfer {
        display: flex;
        justify-content: center;
        align-items: center;
    }
    .handle-area {
        display: flex;
        align-items: center;
        justify-content: space-between;
        height: 70px;
        flex-wrap: nowrap;
    }
    .demo-input {
        display: flex;
        align-items: center;
    }
    .demo-input span {
        white-space: nowrap;
    }
    .el-dialog__body {
        display: flex;
        flex-direction: column;
        justify-content: center;
        flex-wrap: nowrap;
        height: 280px;
    }
    .el-checkbox-group-dialog {
        height: 100%;
        display: flex;
        flex-direction: column;
        justify-content: center;
        margin: auto;
    }
    .el-checkbox {
        height: 30px;
        line-height: 30px;
    }
    .high70 {
        height: 70px;
    }
    .handle {
        position: absolute;
        width: 100%;
        height: 100%;
        top: 0;
        left: 0;
        margin: 0;
        background-image: url(banner.jpg);
        background-position: center;
        background-repeat: no-repeat;
        background-size: cover;
        overflow: hidden;
        display: flex;
        justify-content: center;
        align-items: center;
    }
    .handle-input {
        display: flex;
        flex-direction: column;
    }
</style>
</html>

具体看index.html 代码,如果没看懂,参考网址:
https://blog.csdn.net/laow1314/article/details/109323527
https://blog.csdn.net/qq_29722281/article/details/85016524

权限相关表

最基础的CRUD操作无法体现shiro的功能,需引入RBAC (Role-Based Access Control)思想,配置至少需要三张主表分别代表用户(user)、角色(role)、权限(permission),及两个附表分别是用户和角色(user_role),角色与权限(role_permission)表,表结构如下:
ER

对应的实体如下:
1、com/example/demo/entity/User.java

package com.example.demo.entity;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Data
@ToString
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class User {
    /**
     * 主键
     */
    private int id;
    /**
     * 用户名
     */
    private String username;
    /**
     * 密码
     */
    private String password;
    /**
     * 保留字段
     */
    private String reserve;

    /**
     * 保留字段1
     */
    private int reserve1;
    /**
     * 角色集合
     */
    private List<Role> roleList = new ArrayList<>();

    public User(String json) throws IOException {
        User user = new ObjectMapper().readValue(json,User.class);
        this.id = user.getId();
        this.username = user.getUsername();
        this.password = user.getPassword();
        this.reserve = user.getReserve();
        this.reserve1 = user.getReserve1();
        this.roleList = user.getRoleList();
    }
}

2、com/example/demo/entity/Role.java

package com.example.demo.entity;

import lombok.*;

import java.util.ArrayList;
import java.util.List;

@Data
@ToString
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Role {
    /**
     * 主键
     */
    private int id;
    /**
     * 角色名称
     */
    private String name;
    /**
     * 角色描述
     */
    private String description;
    /**
     * 权限集合
     */
    private List<Permission> permissionList=new ArrayList<>();

}

3、com/example/demo/entity/Permission.java

package com.example.demo.entity;

import lombok.*;

@Data
@ToString
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Permission {
    /**
     * 主键
     */
    private int id;
    /**
     * 权限名称
     */
    private String name;
    /**
     * 权限描述
     */
    private String description;

}

前后端分离项目中使用shiro的session鉴别用户身份

1、src/main/resources/static/index.html

<template id="sign">
    <div class="handle">
        <div class="handle-input">
            <div class="high70">
                <span>用户名称:</span>
                <el-input
                        v-model="username"
                        placeholder="请输入用户名称"
                        clearable></el-input>
            </div>
            <div class="high70">
                <span>密码:</span>
                <el-input
                        v-model="password"
                        placeholder="请输入密码"
                        clearable
                        show-password></el-input>
            </div>
            <el-button @click="login" plain>登录</el-button>
        </div>
    </div>
</template>
login() {
            axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
            axios({
                method: 'post',
                url: '/user/login',
                data: JSON.stringify({
                    username: this.username,
                    password: this.password
                })
            }).then(response => {
                if(typeof response.data.error !== 'undefined' || response.data.error != null){
                    this.username = '';
                    this.password = '';
                    ELEMENT.Notification.error({
                        title: '登录失败!',
                        message: response.data.error,
                        position: 'top-right',
                        showClose: false,
                        offset: 110
                    });
                    return;
                }
                this.permissionsStr = response.data.permissions;
                this.token = response.data.token;
                this.$router.push({
                    name: 'manager',
                    params: {
                        token: this.token,
                        permissionsStr: this.permissionsStr
                    }
                });
            }).catch(error => {
                console.log(error);
                ELEMENT.Message(error);
            });
        }

2、com/example/demo/controller/UserCtrl.java

   /**
     * 登录接口
     *
     * @param user user
     * @return resultMap
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public Map<String, Object> login(@RequestBody User user) {
        //拿到主体
        Subject subject = SecurityUtils.getSubject();
        try {
            UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(user.getUsername(), user.getPassword());
            subject.login(usernamePasswordToken);
            Object permissions = subject.getSession().getAttribute("permissions");
            subject.getSession().removeAttribute("permissions");
            return userService.resultMap("permissions", permissions, "token",  subject.getSession().getId(), "", "");
        }catch (Exception e){
            e.printStackTrace();
            return userService.resultMap("error", e.getMessage(), "",  "", "", "");
        }
    }

3、com/example/demo/config/UserRealm.java

    /**
     * 认证
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //从token中获取用户信息
        String uesrName = (String) authenticationToken.getPrincipal();
        User user = userService.findUserByName(uesrName);
        if (user == null) {
            return null;
        }
        //权限集合
        Set<String> stringPermissionSet = new HashSet<>();
        user.getRoleList().forEach(role -> {
            stringPermissionSet.addAll(role.getPermissionList().stream().map(Permission::getName).collect(Collectors.toList()));
        });
        SecurityUtils.getSubject().getSession().setAttribute("permissions", stringPermissionSet);
        //密码
        String pwd = user.getPassword();
        if (pwd == null || "".equals(pwd)) {
            return null;
        }
        return new SimpleAuthenticationInfo(uesrName, pwd, this.getClass().getName());
    }

4、com/example/demo/service/UserService.java

    public User findUserByName(String userName) {
        User user = userMapper.findUserByName(userName);
        //用户角色的集合
        List<Role> roleList = roleMapper.findRoleListByUserId(user.getId());
        user.setRoleList(roleList);
        return user;
    }

5、src/main/resources/mapper/UserMapper.xml

    <resultMap id="resultUser" type="com.example.demo.entity.User">
        <result property="id" column="id" />
		<result property="username" column="username" />
		<result property="password" column="password" />
    </resultMap>

    <select id="findUserByName" resultMap="resultUser" parameterType="String">
		select
			id,
			username,
		    password
		from user where
		    username = #{userName}
	</select>

6、src/main/resources/mapper/RoleMapper.xml

    <resultMap id="roleResult" type="com.example.demo.entity.Role">
        <result property="id" column="id" />
		<result property="name" column="name" />
        <result property="description" column="description" />
		<collection property="permissionList" column="id" select="com.example.demo.mapper.PermissionMapper.findByPermissionListByRoleId" />
    </resultMap>

	<resultMap id="roleResultNotPermission" type="com.example.demo.entity.Role">
		<result property="id" column="id" />
		<result property="name" column="name" />
		<result property="description" column="description" />
	</resultMap>

    <select id="findRoleListByUserId" resultMap="roleResult" parameterType="int">
		select
			r.id id,
			r.name name,
			r.description description
		from
			user_role ur
		left join role r on
			ur.role_id = r.id
		where
			ur.user_id = #{userId}
	</select>

7、src/main/resources/mapper/PermissionMapper.xml

    <resultMap id="permissionResult" type="com.example.demo.entity.Permission">
        <result property="id" column="id" />
		<result property="name" column="name" />
        <result property="description" column="description" />
    </resultMap>

    <select id="findByPermissionListByRoleId" resultMap="permissionResult" parameterType="int">
        select
            p.id id,
            p.name name,
            p.description description
        from
            role_permission rp
        left join permission p on
            rp.permission_id = p.id
        where
            rp.role_id = #{roleId}
	</select>

8、页面
login_fail

9、src/main/resources/static/index.html

queryPermissionList() {
                axios.defaults.headers.token = this.token;
                axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
                axios({
                    method: 'post',
                    url: '/user/findPermissionListByRoleId',
                    data: JSON.stringify({
                        id: 0
                    })
                }).then(response => {
                    if(typeof response.data.error !== 'undefined' || response.data.error != null){
                        ELEMENT.Notification.error({
                            title: '查询失败!',
                            message: response.data.error,
                            position: 'top-right',
                            showClose: false,
                            offset: 110
                        });
                        return;
                    }
                    this.permissionData = response.data.allPermissionList;
                }).catch(error => {
                    console.log(error);
                    ELEMENT.Message(error);
                });
            },

10、com/example/demo/config/UserSessionManager.java

package com.example.demo.config;

import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.apache.shiro.web.util.WebUtils;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.Serializable;

public class UserSessionManager extends DefaultWebSessionManager {
    public static final String AUTHORIZATION="token";

    public UserSessionManager() {
        super();
    }

    @Override
    protected Serializable getSessionId(ServletRequest request, ServletResponse response) {
        //获取sessionId
        String sessionId= WebUtils.toHttp(request).getHeader(AUTHORIZATION);
        if (sessionId!=null && sessionId!=""){
            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE,
                    ShiroHttpServletRequest.COOKIE_SESSION_ID_SOURCE);
            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, sessionId);
            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);
            return sessionId;
        }else {
            return super.getSessionId(request,response);
        }
    }

}

11、参考链接:
https://blog.csdn.net/qq_25046827/article/details/124540457
https://blog.csdn.net/palerock/article/details/73457415

前端控制按钮显隐,后端请求路径拦截配置

用户登陆成功后会返回用户具有的权限列表,根据权限列表控制前端控制按钮显隐及后端请求拦截路径,
总结如下:
permission

相关代码
com/example/demo/config/ShiroConfig.java

package com.example.demo.config;

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {
    @Bean
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
        System.out.println("ShiroConfig ShiroFilterFactoryBean 执行");
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //设置SecurityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //如果访问需要登录的某个接口,却没有登录,则调用此接口(如果不是前后端分离,则跳转页面)
        //shiroFilterFactoryBean.setLoginUrl("/index.html");
        //登录成功后,跳转的链接,若前后端分离,没必要设置这个
        //shiroFilterFactoryBean.setSuccessUrl("");
        //登录成功,未授权会调用此方法
        //shiroFilterFactoryBean.setUnauthorizedUrl("/user/*");
        //拦截路径,必须使用:LinkedHashMap,要不然拦截效果会时有时无,因为使用的是无序的Map
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        //key=正则表达式路径,value=org.apache.shiro.web.filter.mgt.DefaultFilter
        //退出过滤器
        //filterChainDefinitionMap.put("/logout", "logout");
        //匿名可以访问,游客模式
        filterChainDefinitionMap.put("/", "anon");
        filterChainDefinitionMap.put("/user/login", "anon");
        //登录用户才可以访问
        filterChainDefinitionMap.put("/user/**", "authc");
        //管理员角色才能访问
        //filterChainDefinitionMap.put("/user/**", "roles[admin]");
        //有权限才能访问
        filterChainDefinitionMap.put("/user/queryUserListPage", "perms[query_user, add_user, allot_roles, remove_user]");
        filterChainDefinitionMap.put("/user/insertUser", "perms[add_user]");
        filterChainDefinitionMap.put("/user/removeUser", "perms[remove_user]");
        filterChainDefinitionMap.put("/user/findRoleListByUserId", "perms[allot_roles, query_role, add_role, remove_role, allot_permission]");
        filterChainDefinitionMap.put("/user/updateUserRole", "perms[allot_roles]");
        filterChainDefinitionMap.put("/user/addRole", "perms[add_role]");
        filterChainDefinitionMap.put("/user/removeRole", "perms[remove_role]");
        filterChainDefinitionMap.put("/user/findPermissionListByRoleId", "perms[allot_permission]");
        filterChainDefinitionMap.put("/user/updateRolePermission", "perms[allot_permission]");
        //authc:url必须通过认证才可以访问
        //anon:url可以匿名访问
        //过滤链是顺序执行,从上而下,一般把/**,放到最下面
        filterChainDefinitionMap.put("/**", "authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //如果不是前后端分离,不用设置setSessionManager
        securityManager.setSessionManager(sessionManager());
        securityManager.setRealm(userRealm());
        return securityManager;
    }

    /**
     * 自定义realm
     *
     * @return
     */
    @Bean
    public UserRealm userRealm() {
        UserRealm userRealm = new UserRealm();
        //因为数据库密码存的是明文,所以无需使用双重md5校验
//        customRealm.setCredentialsMatcher(hashedCredentialsMatcher());
        return userRealm;
    }

    /**
     * 密码验证器,双重md5
     *
     * @return
     */
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher() {
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        //设置散列算法,使用md5算法
        hashedCredentialsMatcher.setHashAlgorithmName("md5");
        //散列次数,使用2次md5算法,相当于md5(md5(xxx))
        hashedCredentialsMatcher.setHashIterations(2);
        return hashedCredentialsMatcher;
    }

    /**
     * 自定义SessionManager
     *
     * @return
     */
    @Bean
    public SessionManager sessionManager() {
        UserSessionManager userSessionManager = new UserSessionManager();
        //超时时间,默认 30分钟,会话超时,单位毫秒
//        customSessionManager.setGlobalSessionTimeout(200000);
        return userSessionManager;
    }
}

待完成

1、密码加解密;
2、记住我;

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
课程简介:历经半个多月的时间,Debug亲自撸的 “企业员工角色权限管理平台” 终于完成了。正如字面意思,本课程讲解的是一个真正意义上的、企业级的项目实战,主要介绍了企业级应用系统中后端应用权限的管理,其中主要涵盖了六大核心业务模块、十几张数据库表。 其中的核心业务模块主要包括用户模块、部门模块、岗位模块、角色模块、菜单模块和系统日志模块;与此同时,Debug还亲自撸了额外的属模块,包括字典管理模块、商品分类模块以及考勤管理模块等等,主要是为了更好地巩固相应的技术栈以及企业应用系统业务模块的开发流程! 核心技术栈列表: 值得介绍的是,本课程在技术栈层面涵盖了前端和后端的大部分常用技术,包括Spring BootSpring MVC、Mybatis、Mybatis-Plus、Shiro(身份认证与资源授权跟会话等等)、Spring AOP、防止XSS攻击、防止SQL注入攻击、过滤器Filter、验证码Kaptcha、热部署插件Devtools、POI、Vue、LayUI、ElementUI、JQuery、HTML、Bootstrap、Freemarker、一键打包部署运行工具Wagon等等,如下图所示: 课程内容与收益: 总的来说,本课程是一门具有很强实践性质的“项目实战”课程,即“企业应用员工角色权限管理平台”,主要介绍了当前企业级应用系统中员工、部门、岗位、角色、权限、菜单以及其他实体模块的管理;其中,还重点讲解了如何基于Shiro的资源授权实现员工-角色-操作权限、员工-角色-数据权限的管理;在课程的最后,还介绍了如何实现一键打包上传部署运行项目等等。如下图所示为本权限管理平台的数据库设计图: 以下为项目整体的运行效果截图: 值得一提的是,在本课程中,Debug也向各位小伙伴介绍了如何在企业级应用系统业务模块的开发中,前端到后端再到数据库,最后再到服务器的上线部署运行等流程,如下图所示:

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值