东莞网站建设公司,寻找客户资源的网站,门户网站什么意思,郑州网络公司哪个最好shiro、springboot、vue、elementUI CDN模式前后端分离的权限管理demo 附源码
源码下载地址
https://github.com/Aizhuxueliang/springboot_shiro.git
前提你电脑的安装好这些工具#xff1a;jdk8、idea、maven、git、mysql#xff1b;
shiro的主要概念
Shiro是一个强大…shiro、springboot、vue、elementUI CDN模式前后端分离的权限管理demo 附源码
源码下载地址
https://github.com/Aizhuxueliang/springboot_shiro.git
前提你电脑的安装好这些工具jdk8、idea、maven、git、mysql
shiro的主要概念
Shiro是一个强大的简单易用的Java安全框架主要用来更便捷的认证、授权、加密、会话管理、与Web集成、缓存等Shiro使用起来小而简单spring中有spring security ,是一个权限框架它和spring依赖过于紧密没有shiro使用简单shiro不依赖于spring,shiro不仅可以实现web应用的权限管理还可以实现c/s系统分布式系统权限管理
在应用程序角度来观察如何使用Shiro完成工作 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 官方APIhttps://element.eleme.cn/#/zh-CN/component/installation cdn方式引入vue-router官方APIhttps://router.vuejs.org/zh/guide/#html
DEMO的整体流程设计
技术层面了解完就该设计业务流程了如图
demo整体结构
如图
主要功能页面
1、登录
2、用户查询
3、分配角色
4、删除角色
5、新建用户
6、分配权限
7、新建角色
主要代码
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 {Autowiredprivate UserService userService;/*** 登录接口** param user user* return resultMap*/RequestMapping(value /login, method RequestMethod.POST)public MapString, 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 MapString, 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 MapString, 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 MapString, 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 MapString, 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 MapString, 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 MapString, 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 MapString, 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 MapString, 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 MapString, 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 {Autowiredprivate UserMapper userMapper;Autowiredprivate RoleMapper roleMapper;Autowiredprivate PermissionMapper permissionMapper;public User findUserByName(String userName) {User user userMapper.findUserByName(userName);//用户角色的集合ListRole roleList roleMapper.findRoleListByUserId(user.getId());user.setRoleList(roleList);return user;}public MapString, Object findRoleListByUserId(int userId){//用戶具有的角色集合ListRole beRoleList roleMapper.findRoleListByUserIdNotPermission(userId);//用戶没有的角色集合ListRole notRoleList roleMapper.findNotRoleListByUserIdNotPermission(userId);//所有角色集合Collection? allRoleList CollectionUtils.union(beRoleList, notRoleList);return this.resultMap(beRoleList, beRoleList, notRoleList, notRoleList, allRoleList, allRoleList);}Transactional(rollbackFor {Exception.class})public MapString, 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 MapString, Object findPermissionListByRoleId(int roleId){//角色具有的权限集合ListPermission bePermissionList permissionMapper.findByPermissionListByRoleId(roleId);//角色没有的权限集合ListPermission notPermissionList permissionMapper.findNotPermissionListByRoleId(roleId);//所有权限集合Collection? allPermissionList CollectionUtils.union(bePermissionList, notPermissionList);return this.resultMap(bePermissionList, bePermissionList, notPermissionList, notPermissionList, allPermissionList, allPermissionList);}Transactional(rollbackFor {Exception.class})public MapString, 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 MapString, 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 MapString, Object queryUserListPage(User user){//当前页页码int pageNow user.getReserve1() 1 ? 1 : user.getReserve1();//当前页第一行索引user.setReserve1(5*(pageNow - 1));ListUser userListPage userMapper.queryUserListPage(user);int userRowCount userMapper.getUserRowCount(user);return this.resultMap(userListPage, userListPage, userRowCount, userRowCount, , );}public MapString, Object addRole(Role role){int addRole roleMapper.addRole(role);return this.resultMap(addRole, addRole, , , , );}Transactional(rollbackFor {Exception.class})public MapString, Object removeUser(User user){int removeUser userMapper.removeUserByUserId(user.getId());int removeUserRole userMapper.removeUserRoleByUserId(user.getId());return this.resultMap(removeUser, removeUser, removeUserRole, removeUserRole, , );}public MapString, Object insertUser(User user) {int addUser userMapper.insertUser(user);return this.resultMap(addUser, addUser, , , , );}public MapString, Object resultMap(String str1, Object obj1, String str2, Object obj2, String str3, Object obj3){MapString, 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
headmeta charsetUTF-8!-- import CSS --link relstylesheet hrefhttps://unpkg.com/element-ui/lib/theme-chalk/index.css
/head
body
div idapprouter-view/router-view
/div
template idsigndiv classhandlediv classhandle-inputdiv classhigh70span用户名称:/spanel-inputv-modelusernameplaceholder请输入用户名称clearable/el-input/divdiv classhigh70span密码:/spanel-inputv-modelpasswordplaceholder请输入密码clearableshow-password/el-input/divel-button clicklogin plain登录/el-button/div/div
/template
template idmanagerel-tabs :tab-positiontabPositionel-tab-pane label用户设置 v-ifpermissionsFlag.query_user || permissionsFlag.add_user || permissionsFlag.allot_roles || permissionsFlag.remove_userel-row typeflex justifycenterel-col :span18div classhandle-areadiv classdemo-input v-showpermissionsFlag.query_user || permissionsFlag.add_user || permissionsFlag.allot_roles || permissionsFlag.remove_userspan用户ID:/spanel-inputv-modelidplaceholder请输入用户IDtypenumbersizemediumclearable/el-inputspan用户名称:/spanel-inputv-modelusernameplaceholder请输入用户名称sizemediumclearable/el-inputel-button:plaintrueclickqueryUserListiconel-icon-searchsizemedium查询用户/el-button/divel-buttonv-showpermissionsFlag.add_user:plaintrueclickhandleAddUsericonel-icon-usersizemedium新建用户/el-button/divel-table:datatableDataborderhighlight-current-rowel-table-columnpropidlabel用户ID/el-table-columnel-table-columnpropusernamelabel用户名称/el-table-columnel-table-columnlabel操作template slot-scopescopeel-buttonv-showpermissionsFlag.allot_rolestypetexticonel-icon-set-upclickhandleEditUser(scope.$index, scope.row)分配角色/el-buttonel-buttonv-showpermissionsFlag.remove_usertypetexticonel-icon-remove-outlineclickhandleDeleteUser(scope.$index, scope.row)删除用户/el-button/template/el-table-column/el-tableel-paginationlayouttotal, prev, pager, next, jumper:totaluserRowCount:page-size5:current-page.synccurrentPagecurrent-changequeryUserListPage:hide-on-single-pagehidePageFlagbackground/el-pagination/el-col/el-rowel-dialog :titleroleTitle :visible.syncdialogEditUser :before-closehandleCloseel-transferv-modeltransferValue:datatransferData:titles[待分配角色, 已分配角色]/el-transferspan slotfooter classdialog-footerel-button clickhandleClose取 消/el-buttonel-button typeprimary clickassignRoles确 定/el-button/span/el-dialogel-dialog title新建用户 :visible.syncdialogAddUser :before-closehandleClosediv classhigh70span用户名称:/spanel-inputv-modelusernameplaceholder请输入用户名称sizemediumclearable/el-input/divdiv classhigh70span密码:/spanel-inputv-modelpasswordplaceholder请输入密码sizemediumclearableshow-password/el-input/divdiv classhigh70span再次输入密码:/spanel-inputv-modelpassword1placeholder请再次输入密码sizemediumshow-password/el-input/divdiv classhigh70span备注:/spanel-inputv-modelreserveplaceholder请输入用户备注sizemedium/el-input/divspan slotfooter classdialog-footerel-button clickhandleClose取 消/el-buttonel-button typeprimary clickinsertUser确 定/el-button/span/el-dialog/el-tab-paneel-tab-pane label角色设置 v-ifpermissionsFlag.allot_roles || permissionsFlag.query_role || permissionsFlag.add_role || permissionsFlag.remove_role || permissionsFlag.allot_permissionel-row typeflex justifycenterel-col :span18div classhandle-areael-buttonv-showpermissionsFlag.allot_roles || permissionsFlag.query_role || permissionsFlag.add_role || permissionsFlag.remove_role || permissionsFlag.allot_permission:plaintrueclickqueryRoleListiconel-icon-searchsizemedium角色查询/el-buttonel-buttonv-showpermissionsFlag.add_role:plaintrueclickhandleAddRoleiconel-icon-circle-plus-outlinesizemedium新建角色/el-button/divel-table:dataroleDataborderhighlight-current-rowel-table-columnpropidlabel角色ID/el-table-columnel-table-columnpropnamelabel角色名称/el-table-columnel-table-columnpropdescriptionlabel角色描述/el-table-columnel-table-columnlabel操作template slot-scopescopeel-buttonv-showpermissionsFlag.allot_permissiontypetexticonel-icon-s-operationclickhandleEditRole(scope.$index, scope.row)分配权限/el-buttonel-buttonv-showpermissionsFlag.remove_roletypetexticonel-icon-remove-outlineclickhandleDeleteRole(scope.$index, scope.row)删除角色/el-button/template/el-table-column/el-table/el-col/el-rowel-dialog :titlepermissionsTitle :visible.syncdialogEditRole :before-closehandleCloseel-checkbox-group v-modelcheckedPermissions classel-checkbox-group-dialogel-checkbox v-forpermission in permissions :labelpermission.name :keypermission.name{{permission.description}}/el-checkbox/el-checkbox-groupspan slotfooter classdialog-footerel-button clickhandleClose取 消/el-buttonel-button typeprimary clickassignPermissions确 定/el-button/span/el-dialogel-dialog title新建角色 :visible.syncdialogAddRole :before-closehandleClosediv classhigh70span角色名称:/spanel-inputv-modelnameplaceholder请输入角色名称sizemedium/el-input/divdiv classhigh70span角色描述:/spanel-inputv-modeldescriptionplaceholder请输入角色描述sizemedium/el-input/divspan slotfooter classdialog-footerel-button clickhandleClose取 消/el-buttonel-button typeprimary clickinsertRole确 定/el-button/span/el-dialog/el-tab-paneel-tab-pane label权限列表 v-ifpermissionsFlag.allot_permissionel-row typeflex justifycenterel-col :span18div classhandle-areael-buttonv-showpermissionsFlag.allot_permission:plaintrueclickqueryPermissionListiconel-icon-searchsizemedium权限查询/el-button/divel-table:datapermissionDataborderhighlight-current-rowel-table-columnpropidlabel权限ID/el-table-columnel-table-columnpropnamelabel权限名称/el-table-columnel-table-columnpropdescriptionlabel权限描述/el-table-column/el-table/el-col/el-row/el-tab-pane/el-tabs
/template
/body
!-- import Vue before Element --
script srchttps://unpkg.com/vue2/dist/vue.js/script
!-- import JavaScript --
script srchttps://unpkg.com/element-ui/lib/index.js/script
!-- import Axios --
script srchttps://unpkg.com/axios/dist/axios.min.js/script
!-- import Router --
script srchttps://cdn.staticfile.org/vue-router/2.7.0/vue-router.min.js/script
scriptconst Sign {props: [todo],template: #sign,data() {return {username: ,password: ,permissionsStr: [],token: }},methods: {login() {axios.defaults.headers.post[Content-Type] application/json;charsetUTF-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;charsetUTF-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;charsetUTF-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;charsetUTF-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;charsetUTF-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;charsetUTF-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;charsetUTF-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;charsetUTF-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;charsetUTF-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;charsetUTF-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;charsetUTF-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;charsetUTF-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;charsetUTF-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)表表结构如下
对应的实体如下 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 ListRole 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 ListPermission permissionListnew 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 idsigndiv classhandlediv classhandle-inputdiv classhigh70span用户名称:/spanel-inputv-modelusernameplaceholder请输入用户名称clearable/el-input/divdiv classhigh70span密码:/spanel-inputv-modelpasswordplaceholder请输入密码clearableshow-password/el-input/divel-button clicklogin plain登录/el-button/div/div
/templatelogin() {axios.defaults.headers.post[Content-Type] application/json;charsetUTF-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 MapString, 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*/Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {//从token中获取用户信息String uesrName (String) authenticationToken.getPrincipal();User user userService.findUserByName(uesrName);if (user null) {return null;}//权限集合SetString 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);//用户角色的集合ListRole roleList roleMapper.findRoleListByUserId(user.getId());user.setRoleList(roleList);return user;}5、src/main/resources/mapper/UserMapper.xml resultMap idresultUser typecom.example.demo.entity.Userresult propertyid columnid /result propertyusername columnusername /result propertypassword columnpassword //resultMapselect idfindUserByName resultMapresultUser parameterTypeStringselectid,username,passwordfrom user whereusername #{userName}/select6、src/main/resources/mapper/RoleMapper.xml resultMap idroleResult typecom.example.demo.entity.Roleresult propertyid columnid /result propertyname columnname /result propertydescription columndescription /collection propertypermissionList columnid selectcom.example.demo.mapper.PermissionMapper.findByPermissionListByRoleId //resultMapresultMap idroleResultNotPermission typecom.example.demo.entity.Roleresult propertyid columnid /result propertyname columnname /result propertydescription columndescription //resultMapselect idfindRoleListByUserId resultMaproleResult parameterTypeintselectr.id id,r.name name,r.description descriptionfromuser_role urleft join role r onur.role_id r.idwhereur.user_id #{userId}/select7、src/main/resources/mapper/PermissionMapper.xml resultMap idpermissionResult typecom.example.demo.entity.Permissionresult propertyid columnid /result propertyname columnname /result propertydescription columndescription //resultMapselect idfindByPermissionListByRoleId resultMappermissionResult parameterTypeintselectp.id id,p.name name,p.description descriptionfromrole_permission rpleft join permission p onrp.permission_id p.idwhererp.role_id #{roleId}/select8、页面
9、src/main/resources/static/index.html
queryPermissionList() {axios.defaults.headers.token this.token;axios.defaults.headers.post[Content-Type] application/json;charsetUTF-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 AUTHORIZATIONtoken;public UserSessionManager() {super();}Overrideprotected Serializable getSessionId(ServletRequest request, ServletResponse response) {//获取sessionIdString 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
前端控制按钮显隐后端请求路径拦截配置
用户登陆成功后会返回用户具有的权限列表根据权限列表控制前端控制按钮显隐及后端请求拦截路径 总结如下
相关代码 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 {Beanpublic ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {System.out.println(ShiroConfig ShiroFilterFactoryBean 执行);ShiroFilterFactoryBean shiroFilterFactoryBean new ShiroFilterFactoryBean();//设置SecurityManagershiroFilterFactoryBean.setSecurityManager(securityManager);//如果访问需要登录的某个接口却没有登录则调用此接口(如果不是前后端分离则跳转页面)//shiroFilterFactoryBean.setLoginUrl(/index.html);//登录成功后跳转的链接若前后端分离没必要设置这个//shiroFilterFactoryBean.setSuccessUrl();//登录成功未授权会调用此方法//shiroFilterFactoryBean.setUnauthorizedUrl(/user/*);//拦截路径必须使用:LinkedHashMap要不然拦截效果会时有时无因为使用的是无序的MapMapString, String filterChainDefinitionMap new LinkedHashMap();//key正则表达式路径valueorg.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]);//authcurl必须通过认证才可以访问//anonurl可以匿名访问//过滤链是顺序执行从上而下一般把/**放到最下面filterChainDefinitionMap.put(/**, authc);shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);return shiroFilterFactoryBean;}Beanpublic SecurityManager securityManager() {DefaultWebSecurityManager securityManager new DefaultWebSecurityManager();//如果不是前后端分离不用设置setSessionManagersecurityManager.setSessionManager(sessionManager());securityManager.setRealm(userRealm());return securityManager;}/*** 自定义realm** return*/Beanpublic UserRealm userRealm() {UserRealm userRealm new UserRealm();//因为数据库密码存的是明文所以无需使用双重md5校验
// customRealm.setCredentialsMatcher(hashedCredentialsMatcher());return userRealm;}/*** 密码验证器双重md5** return*/Beanpublic HashedCredentialsMatcher hashedCredentialsMatcher() {HashedCredentialsMatcher hashedCredentialsMatcher new HashedCredentialsMatcher();//设置散列算法使用md5算法hashedCredentialsMatcher.setHashAlgorithmName(md5);//散列次数使用2次md5算法相当于md5(md5(xxx))hashedCredentialsMatcher.setHashIterations(2);return hashedCredentialsMatcher;}/*** 自定义SessionManager** return*/Beanpublic SessionManager sessionManager() {UserSessionManager userSessionManager new UserSessionManager();//超时时间默认 30分钟会话超时单位毫秒
// customSessionManager.setGlobalSessionTimeout(200000);return userSessionManager;}
}
待完成
1、密码加解密 2、记住我