管理系统权限设计借鉴

转自:http://blog.csdn.net/zwx19921215/article/details/44467099/

最近在做一个网站类型项目,主要负责后台,ui框架选型为jquery easy ui,项目架构为spring mvc + spring jdbc,简单易用好上手!搭建好框架后开始了第一个任务,设计并实现一套简单的权限管理功能。

一套最基本的权限管理包括用户、角色、资源。

数据库设计

我的设计如下:

用户:user

角色:role

用户-角色:user_role

资源:resource(包括上级菜单、子菜单、按钮等资源)

角色-资源:role_resource

标准的权限管理系统设计为以上5张表。

注:用户、用户-角色我就不做说明了,这两个是很简单的两块,用户的crud,以及为用户分配角色(多对多的关系)稍微琢磨一下就清楚了,下面都是针对为角色分配权限的实现

后台实现

展示层采用ztree树

role.jsp

[html] view plain copy

  1. <%@ page contentType="text/html;charset=UTF-8"%>
  2. <%@ include file="/views/back/include/taglib.jsp"%>
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  4. <html xmlns="http://www.w3.org/1999/xhtml">
  5. <head>
  6. <meta name="decorator" content="back" />
  7. <script type="text/javaScript">
  8. //打开菜单窗口
  9. function openMenuDialog(){
  10. var selected = $("#list").datagrid(‘getSelected‘);
  11. if (selected != null) {
  12. $("#id").val(selected.id);
  13. queryMenus(selected.id);
  14. $("#menuWindow").window("open");
  15. } else {
  16. $.messager.alert(‘提示‘, "未选择数据!");
  17. }
  18. }
  19. //角色-菜单信息入库
  20. function ajaxSubmit(rid,idstr){
  21. $.post("${ctx}/roleMenu/save.jhtml",{"roleId":rid,"ids":idstr},function(obj){
  22. $.messager.alert(‘提示‘,obj.msg);
  23. $("#menuWindow").window(‘close‘);
  24. },‘json‘);
  25. }
  26. </script>
  27. <!-- ztree -->
  28. <script type="text/javascript">
  29. var tree = "";
  30. var setting = {
  31. check : {
  32. chkboxType:{"Y":"ps","N":"s"},//勾选checkbox对于父子节点的关联关系,取消勾选时不关联父
  33. chkStyle:"checkbox",
  34. enable : true   //是否复选框
  35. },
  36. //数据
  37. data : {
  38. simpleData : {
  39. enable : true
  40. }
  41. }
  42. };
  43. //查询菜单信息
  44. function queryMenus(roleId){
  45. $.post(‘${ctx}/role/treedata.jhtml‘, {‘roleId‘:roleId}, function(zNodes) {
  46. for (var i = 0; i < zNodes.length; i++) {
  47. if (zNodes[i].isParent) {
  48. } else {
  49. //zNodes[i].icon = "${ctxStatic}/images/532.ico";//设置图标
  50. }
  51. }
  52. tree = $.fn.zTree.init($("#tree"), setting, zNodes);
  53. tree.expandAll(true);//全部展开
  54. //var nodes = treeObj.getNodes();
  55. }, ‘json‘);
  56. }
  57. //获取选中节点
  58. function onCheck(){
  59. var rid = $("#id").val();
  60. var treeObj=$.fn.zTree.getZTreeObj("tree");
  61. var nodes=treeObj.getCheckedNodes(true);
  62. var ids = new Array();
  63. for(var i=0;i<nodes.length;i++){
  64. //获取选中节点的值
  65. ids.push(nodes[i].id);
  66. // v+=nodes[i].id + ",";
  67. //alert(nodes[i].id);
  68. }
  69. ajaxSubmit(rid,ids);
  70. }
  71. </script>
  72. </head>
  73. <body>
  74. <!-- 数据表格 -->
  75. <table id="list" url=‘${ctx}/role/list/page.jhtml‘ method=‘post‘
  76. class="easyui-datagrid" style="width:100%;" fitcolumns="true"
  77. toolbar=‘#tb‘ pagination=‘true‘ rownumbers=‘true‘ singleSelect=‘true‘>
  78. <thead>
  79. <tr>
  80. <th field=‘name‘ sortable=‘true‘ width=‘100‘>角色名称</th>
  81. <th field=‘description‘ width=‘200‘ align=‘right‘>描述</th>
  82. <th field=‘createTimeFormat‘ width=‘150‘ align=‘center‘>创建时间</th>
  83. </tr>
  84. </thead>
  85. </table>
  86. <!-- 编辑栏  -->
  87. <div id="tb" style="padding:5px 5px;">
  88. <div>
  89. <p2p:permission module="role" code="add"><a href="#" class="easyui-linkbutton" iconCls="icon-add" onclick="openCreateDialog();">新增</a></p2p:permission>
  90. <p2p:permission module="role" code="edit"><a href="#" class="easyui-linkbutton" iconCls="icon-edit" onclick="openUpdateDialog();">编辑</a></p2p:permission>
  91. <p2p:permission module="role" code="delete"><a href="#" class="easyui-linkbutton" iconCls="icon-remove" onclick="del();">删除</a></p2p:permission>
  92. <p2p:permission module="role" code="authority"><a href="#" class="easyui-linkbutton" iconCls="icon-edit" onclick="openMenuDialog();">设置权限</a></p2p:permission>
  93. </div>
  94. <!-- 搜索项 -->
  95. <div style="margin-top:5px;padding-left:5px">
  96. 用户名:   <input id="query_name" class="easyui-textbox" type="text" style="width:110px" />
  97. 创建日期: <input id="query_startDate" class="easyui-datebox" style="width:110px">
  98. 至:     <input id="query_endDate" class="easyui-datebox" style="width:110px">
  99. <a onclick="reload();" href="#" class="easyui-linkbutton" iconCls="icon-search">查询</a>
  100. </div>
  101. </div>
  102. <!-- 权限窗口 -->
  103. <div id="menuWindow" class="easyui-window" title="配置权限" data-options="modal:true,iconCls:‘icon-save‘,footer:‘#menuWindowfooter‘" style="width:350px;height:420px;padding:10px">
  104. <div id="tree" class="ztree" style="padding: 10px 20px;"></div>
  105. </div>
  106. <div id="menuWindowfooter" style="padding:5px;text-align:right;">
  107. <a href="#" onclick="onCheck();" class="easyui-linkbutton" data-options="iconCls:‘icon-save‘">提交</a>
  108. </div>
  109. </body>
  110. </html>

 

action层
RoleAction.java

[java] view plain copy

  1. @RequestMapping(value = "/treedata.jhtml")
  2. @ResponseBody
  3. public String treedata(HttpServletRequest request, Model model) {
  4. DynamicParams params = new DynamicParams(request);
  5. List<Map<String, Object>> mapList = Lists.newArrayList();
  6. params.put("allMenu", "allMenu");
  7. List<Menu> list = authManager.findMenuList(params);
  8. List<RoleMenu> roleMenus = authManager.findRoleMenuList(params);
  9. for (int i = 0; i < list.size(); i++) {
  10. Menu e = list.get(i);
  11. Map<String, Object> map = Maps.newHashMap();
  12. map.put("id", e.getId());
  13. map.put("pId", e.getParentId() != null ? e.getParentId() : 0);
  14. map.put("name", e.getName());
  15. for (RoleMenu roleMenu : roleMenus) {
  16. if (roleMenu.getMenuId() == e.getId()) {
  17. map.put("checked", true);
  18. }
  19. }
  20. mapList.add(map);
  21. }
  22. return toJson(mapList);
  23. }

service层

AuthManager.java

[java] view plain copy

  1. // 菜单管理
  2. public List<Menu> findMenuList(DynamicParams params) {
  3. List<Menu> menus = new ArrayList<Menu>();
  4. if ("allMenu".equals(params.getString("allMenu"))) {
  5. menus = menuDao.findList(params);
  6. } else {
  7. // 通过用户查询角色
  8. List<UserRole> userRoles = userRoleDao.findList(params);
  9. // 通过角色查询菜单
  10. List<RoleMenu> roleMenus = new ArrayList<RoleMenu>();
  11. if (userRoles != null && userRoles.size() > 0) {
  12. for (UserRole userRole : userRoles) {
  13. params = new DynamicParams();
  14. if (userRole != null) {
  15. if (userRole.getRoleId().equals(params.getString("rid"))) {
  16. break;
  17. }
  18. params.put("roleId", userRole.getRoleId().toString());
  19. List<RoleMenu> rms = roleMenuDao.findList(params);
  20. for (RoleMenu roleMenu : rms) {
  21. roleMenus.add(roleMenu);
  22. }
  23. }
  24. }
  25. }
  26. // 查询菜单信息
  27. for (RoleMenu roleMenu : roleMenus) {
  28. if (roleMenu != null) {
  29. Menu menu = menuDao.find(roleMenu.getMenuId());
  30. if (menu != null) {
  31. menus.add(menu);
  32. }
  33. }
  34. }
  35. menus = removeDuplicate(menus);
  36. Collections.sort(menus);
  37. }
  38. return menus;
  39. }

[java] view plain copy

  1. /**
  2. * 去除菜单中重复项
  3. *
  4. * @param list
  5. * @return
  6. */
  7. private List<Menu> removeDuplicate(List<Menu> list) {
  8. List<Menu> result = new ArrayList<Menu>();
  9. Set<Long> menuIds = new HashSet<Long>();
  10. for (int i = 0; i < list.size(); i++) {
  11. Menu m = list.get(i);
  12. if (m != null && menuIds.add(m.getId())) {
  13. result.add(m);
  14. }
  15. }
  16. return result;
  17. }

[java] view plain copy

  1. public List<RoleMenu> findRoleMenuList(DynamicParams params) {
  2. List<RoleMenu> roleMenus = roleMenuDao.findList(params);
  3. return roleMenus;
  4. }

Dao层

menuDao

[java] view plain copy

  1. @Override
  2. protected void createQuery(DynamicParams params, StringBuffer sql, List<Object> args) {
  3. sql.append("select s.* from sys_menu s where 1=1 ");
  4. String parentId = params.getString("parentId");
  5. if (StringUtils.isNotBlank(parentId)) {
  6. sql.append(" and parent_id = ? ");
  7. args.add(parentId);
  8. }
  9. String sort = params.getString("sort");
  10. String order = params.getString("order");
  11. if (StringUtils.isNotBlank(sort)) {
  12. sql.append(" order by ").append(hump2underline(sort));
  13. if (StringUtils.isNotBlank(order)) {
  14. sql.append(" " + order);
  15. } else {
  16. sql.append(" desc ");
  17. }
  18. } else {
  19. sql.append("order by sort asc,id desc ");
  20. }
  21. }

userRoleDao

[java] view plain copy

  1. @Override
  2. protected void createQuery(DynamicParams params, StringBuffer sql, List<Object> args) {
  3. sql.append("select s.* from sys_user_role s where 1=1 ");
  4. Long adminId = params.getLong("adminId");
  5. if (adminId != null) {
  6. sql.append(" and s.user_id = ?");
  7. args.add(adminId);
  8. }
  9. }

roleMenuDao

[java] view plain copy

  1. @Override
  2. protected void createQuery(DynamicParams params, StringBuffer sql, List<Object> args) {
  3. sql.append("select s.* from ").append("sys_role_menu").append(" s where 1=1 ");
  4. Long adminId = params.getLong("roleId");
  5. if (adminId != null) {
  6. sql.append(" and s.role_id = ?");
  7. args.add(adminId);
  8. }
  9. }

在WEB-INF目录下建立文件夹tlds 建立自定义标签文件shiros.tld,我们通过自定义标签实现页面按钮的控制。

 

[html] view plain copy

  1. <span style="color:#333333;"><?xml version="1.0" encoding="UTF-8" ?>
  2. <taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
  4. version="2.0">
  5. <description>p2p permission taglib</description>
  6. <display-name>permission taglib</display-name>
  7. <tlib-version>1.0</tlib-version>
  8. <short-name>p2p_back</short-name>
  9. <uri>http://vanfon.p2p.cn/</uri>
  10. <tag>
  11. <description>权限校验标签,有权限就显示标签体的内容,否则不显示</description>
  12. <name>permission</name>
  13. <tag-class>com.vanfon.p2p.back.tag.PermissionTag</tag-class>
  14. <body-content>JSP</body-content>
  15. <attribute>
  16. <description></description>
  17. <name>module</name>
  18. <required>true</required>
  19. <rtexprvalue>false</rtexprvalue>
  20. </attribute>
  21. <attribute>
  22. <description></description>
  23. <name>code</name>
  24. <required>true</required>
  25. <rtexprvalue>false</rtexprvalue>
  26. </attribute>
  27. </tag>
  28. </taglib></span>

 

自定义标签类

[java] view plain copy

  1. package com.vanfon.p2p.back.tag;
  2. import java.util.List;
  3. import javax.servlet.http.HttpServletRequest;
  4. import javax.servlet.jsp.JspException;
  5. import javax.servlet.jsp.tagext.TagSupport;
  6. import com.vanfon.p2p.entity.system.Admin;
  7. import com.vanfon.p2p.entity.system.Menu;
  8. import com.vanfon.p2p.manager.system.AuthManager;
  9. import com.vanfon.p2p.utils.DynamicParams;
  10. import com.vanfon.p2p.utils.SpringContextHolder;
  11. /**
  12. * 权限控制标签
  13. *
  14. * @author zhangwx
  15. * @date 2015-2-5
  16. */
  17. public class PermissionTag extends TagSupport {
  18. /**
  19. *
  20. */
  21. private static final long serialVersionUID = 4592227792811389132L;
  22. private String module;// 属性名必须与JSP自定义标签的属性名一样
  23. private String code;
  24. public String getModule() {
  25. return module;
  26. }
  27. public void setModule(String module) {
  28. this.module = module;
  29. }
  30. public String getCode() {
  31. return code;
  32. }
  33. public void setCode(String code) {
  34. this.code = code;
  35. }
  36. @Override
  37. public int doStartTag() throws JspException {
  38. boolean result = false;
  39. HttpServletRequest request = (HttpServletRequest) this.pageContext.getRequest();// 通过成员变量获取HttpServletRequest对象
  40. Admin admin = (Admin) request.getSession().getAttribute("admin");// 获取登录到系统的用户
  41. if (admin != null) {
  42. if ("1".equals(String.valueOf(admin.getIfsuper()))) {// 超级管理员
  43. result = true;
  44. } else {
  45. DynamicParams params = new DynamicParams();
  46. params.put("id", String.valueOf(admin.getId()));
  47. params.put("module", this.module);
  48. params.put("code", this.code);
  49. AuthManager authManager = SpringContextHolder.getBean(AuthManager.class);
  50. List<Menu> userRoleAuths = authManager.findUserRoleAuthList(params);
  51. if (userRoleAuths != null && userRoleAuths.size() > 0) {
  52. result = true;
  53. }
  54. }
  55. }
  56. return result ? EVAL_BODY_INCLUDE : SKIP_BODY;
  57. }
  58. }

以上就是该权限管理中权限树(为角色分配权限)的大体实现。

 


时间: 2024-10-09 21:12:15

管理系统权限设计借鉴的相关文章

通用的管理系统权限设计

原文:通用的管理系统权限设计 在以前的工作中,我常常会遇到一些系统管理权限的问题,常常是一种系统一种管理方式,很浪费时间和精力,后来我根据Windows的文件权限管理方式想了一种相似流程的控制方式,具体流程如下: 将系统的功能页面加入到模块中,并加入权限限制造,权限可以灵活设置,加入多种权限,对于用户可单独设置权限,也可以给角色设置权限,配置流程和Windows权里的方式差不多,系统代码正在编写中,完成之后将开源贡献给大家,下面是表结构及关系 关系图 原文地址:https://www.cnblo

[转]完整的权限管理系统,设计概要

很多人都知道以角色为基础的权限管理设计(RBAC),但是大部分人似懂非懂,不知道完整的权限管理系统都包括哪些内容.  在此以权限管理的使用场景来说明一下完整的权限管理内容.     一是鉴权管理,即权限判断逻辑.     1. 最基本的权限管理就是菜单管理,用户没有权限的功能模块在菜单节点上是不显示的.(很多人以为这就是权限管理!)      示例:普通业务人员登录系统后,是看不到[用户管理]菜单的.         2. 功能权限管理,B/S系统的功能体现为URL,所以功能权限管理主要是针对U

基于Bootstrap框架的临床数据管理系统的设计与开发

    基于Bootstrap框架的临床数据管理系统的设计与开发     2018年11月10日 目  录 第一章绪论... 6 1.1 选题背景及其意义... 6 1.2国内外研究现状... 7 1.2.1 临床大数据管理系统发展现状... 7 1.2.2医疗电子表单管理发展现状... 8 1.3研究目标... 9 1.4 研究内容... 10 1.5论文整体结构... 10 第二章相关技术研究... 12 2.1 AngularJS技术简述... 12 2.2 RESTful API +sw

图书管理系统------软件设计图纸

图书管理系统------软件设计图纸 一.图书馆管理系统总体功能概述 图书馆管理系统功能图: 1.系统登录模块 : 本模块的功能点包括: (1) 判断用户名和密码是否相符: (2) 根据用户的权限类型,登录到系统的制定界面操作使用. 2.图书管理模块: 在本模块中图书馆工作人员可以对图书进行管理操作. 本模块的功能点包括: (1) 新书入库,将新进图书按其类型将图书的基本信息录入系统数据库: (2) 图书出库,某一部分图书会随着时间的增长及知识的更新而变得不再有收藏的价值,或者图书被损坏,这些图

WisDom.Net 框架设计(五) 权限设计

WisDom.Net --权限设计 1.需求分析     基本在所有的管理系统中都离不开权限管理.可以这么说,权限管理是管理系统的核心所在. 权限管理说白一些就是每个人能够做什么,不能够做什么.可以说是一套规则.下面就说一下,在wisdom.net中的权限     1. 控制用户修改和删除数据.即 用户编辑和删除自己创建的数据,但是只能编辑和删除比自己权限小的人创建的数据     2. 模块的控制. 用户只能访问自己被授权访问的模块,不能访问其他模块     3. 用户被赋予不同的角色,各个角色

java用户角色权限设计

实现业务系统中的用户权限管理 B/S系统中的权限比C/S中的更显的重要,C/S系统因为具有特殊的客户端,所以访问用户的权限检测可以通过客户端实现或通过客户端+服务器检测实现,而B/S中,浏览器是每一台计算机都已具备的,如果不建立一个完整的权限检测,那么一个"非法用户"很可能就能通过浏览器轻易访问到B/S系统中的所有功能.因此B/S业务系统都需要有一个或多个权限系统来实现访问权限检测,让经过授权的用户可以正常合法的使用已授权功能,而对那些未经授权的"非法用户"将会将他

ASP.NET 系列:RBAC权限设计

权限系统的组成通常包括RBAC模型.权限验证.权限管理以及界面访问控制.现有的一些权限系统分析通常存在以下问题: (1)没有权限的设计思路 认为所有系统都可以使用一套基于Table设计的权限系统.事实上设计权限系统的重点是判断角色的稳定性和找出最小授权需求.角色的稳定性决定了系统是通过角色判断权限还是需要引入RBAC方式,最小授权需求防止我们过度设计导致超出授权需求的权限粒度. (2)没有独立的RBAC模型的概念 直接使用实体类表示RBAC模型,导致本身本应该只有几行代码且可以在项目级别复用的R

基于ASP.NET的高校辅导员工作管理系统的设计与实现--论文随笔(四)

一.基本信息 标题:基于ASP.NET的高校辅导员工作管理系统的设计与实现 时间:2017 出版源:南通理工学院 关键词:ASP.NET; SQL Server; 高校; 管理系统; 辅导员; 二.研究背景 问题定义:高校学生数量越来越多,学生信息也越来越庞大,在辅导员的日常工作中,所使用的传统的电子表格和纸质文档容易丢失造成学校多部门间缺乏资源共享机制,同时管理不变,数据易丢失.为了提高辅导员队伍整体工作效率已经成为高校学生工作中有待解决的难题. 难点:引用ajax技术减轻服务器的负担, 相关

文献综述十三:超市商品管理系统的设计与实现

一.基本信息 标题:超市商品管理系统的设计与实现 时间:2016 出版源:古林大学 文件分类:对商品管理系统的研究 二.研究背景 采用计算机和通讯技术来对超市的商品进行科学规范的管理和经营,用来满足超市日常所需,节约人力物力. 三.具体内容 论文的内容分为6个部分.分别是绪论.超市商品管理系统的开发方法和工具.系统分析.系统概要设计.系统详 细设计以及系统测试. 绪论:论述了超市商品管理系统的开发背景.开发意义以及国内外发展现状. 超市商品管理系统的开发方法和工具:采用 C#编程语言作为前端开发