JavaWeb-权限管理
来源:互联网 发布:网络信息安全重大事件 编辑:程序博客网 时间:2024/05/21 10:55
最近看公司的代码,对权限管理颇有兴趣,恰好今天有空,就记录了以下,如果有错误,还望指正
正统表结构:
从图上可以看出,表结构主要有User Role Function 三个表,分别对应用户、角色、功能,通过这三张表完成权限的控制和实现。
User 与 Role 是多对多关系,使用第三方UserRole表来维护
Role 与 Function 同样也是多对多的关系,多个角色对应多个功能(每个模块都有对应的id,功能即模块,即menu),使用第三方表RoleFunction来维护
大概思路:
用户登陆时加载菜单,根据用户查询用户角色,根据用户角色查询用户功能,将查询到一个menu code,然后返回这些menu code
在控制层在根据menu code 获取并加载菜单
但是无法对每个menu 中的按钮权限进行控制(比如添加、删除、审核)
解决办法:在Role和Function的第三方表中插入一列:menu_btn,代表该该角色下的功能拥有什么样的按钮权限
然后查询时,封装一个拥有menu_btn的实体类menu,用来记录权限,如果没有任何button,则不显示任何菜单
项目做法:
表结构:
T_SYS_USER 用户表
T_SYS_ROLE 角色表
T_SYS_USER_ROLE 用户角色关系表
T_SYS_MENU 功能表
T_SYS_ROLE_PRIVILEGE 按钮权限
[关于权限按钮列表]:
系统有固化的权限按钮,新增,修改,删除,查看,审核..
名称对应:ADD_BTN,MOD_BTN,DEL_BTN,VIEW_BTN,AUDIT_BTN…应:ADD_BTN,MOD_BTN,DEL_BTN,VIEW_BTN,AUDIT_BTN…
多个用户对应多个角色 , 使用第三方表T_SYS_USER_ROLE维护
权限管理中的授权问题:
一个用户可以对应多个角色,A角色的操作权限和B角色的操作权限有冲突,那该以谁的为准?
下面有几种解决方案:
- 合并权限,将A角色的权限和B角色的权限合并 √
- 在视图上给用户选择,让用户可以切换角色,操作麻烦 ×
- 如果角色之间有授权冲突,则不允许授权 ×
- 允许用户对冲突角色进行授予,让用户在授予权限时,设置角色的优先级,当角色冲突时,以优先级高的角色为准 √
公司代码分析:
// 定义一个map,用来保存菜单权限 Map<String, MenuPrivilege> ret = new HashMap<String, MenuPrivilege>(); // 查询出权限并添加,使用sql直接查询menu,不查role,即不实例化role,即可避免这个问题,但是btns又拥有这个问题,待解决 List<SysRolePrivilege> priviletList = sysRolePrivilegeDao.findByUserRolePrivilege(userId); for (SysRolePrivilege rp : priviletList) { ret.put(rp.getMenuCode(), new MenuPrivilege(rp.getMenuCode(), rp.getMenuBtn())); // 相同的menu code会直接被map的唯一性覆盖 } return ret;
问题解决,思路大概是按照解决方案一
新问题: btns问题
A role 对应 A menu - btn_add, btn_query
B role 对应 A menu - btn_add, btn_delete
如果Arole和Brole都赋给User1那么权限以谁的为准?
// todo 貌似是公司代码bug,待考证
代码展示:
项目的权限管理是根据当前用户的类型,决定要显示的菜单 从而实现权限管理的功能
当加载menu时,会在控制层根据当前登陆用户获取菜单:
/* 功能菜单数据获取 */ @RequestMapping("tree") @ResponseBody public Object menuTree(HttpServletRequest request, HttpSession session) { ... // 从数据库中获取菜单数据 List<SysMenu> list = menuService.menusOfUser(session); List<Map<String, String>> ret = new ArrayList<Map<String, String>>(); for (SysMenu po : list) { Map<String, String> map = new HashMap<String, String>(); map.put("id", po.getMenuCode()); map.put("pid", po.getMenuPcode()); map.put("name", po.getMenuName()); if (po.isLeafYn()) { // 如果为叶子节点 map.put("url", "menu/jump/" + po.getMenuCode()); // 点击链接 } else { map.put("url", po.getMenuUrl()); } ret.add(map); } return ret; // 这里在mvc配置文件中配置了json转换器,spring mvc会自动帮你将集合转换为json字符串,发送给jsp,使用js进行菜单的显示 }
List<SysMenu> list = menuService.menusOfUser(session);
menusOfUser方法:
@Service("menuService") public class MenuService { public List<SysMenu> menusOfUser(HttpSession session) { SessionUser sessionUser = (SessionUser) session.getAttribute(SessionUser.SESSION_USER_KEY); Assert.notNull(sessionUser, "user information in session cannot be null"); // 超级管理员 if (SysUser.USER_TYPE_MASTER == sessionUser.getUserType()) { return menuList; } // 其他普通用户 Map<String, MenuPrivilege> menus = sessionUser.getPrivilege(); // 如果没有权限菜单,返回空 if (menus == null || menus.size() == 0) { return new ArrayList<SysMenu>(); } List<SysMenu> result = new ArrayList<SysMenu>(); for (SysMenu sysMenu : menuList) { if (menus.containsKey(sysMenu.getMenuCode())) { result.add(sysMenu); } } return result; } }
- JavaWeb-权限管理
- JavaWEB采用Filter的权限管理
- javaweb开发中的权限管理的方法
- javaweb 项目的系统权限管理
- javaweb+SSH实现简单的权限管理系统
- JAVAWEB开发之权限管理(一)——权限管理详解(权限管理原理以及方案)、不使用权限框架的原始授权方式详解
- 权限设计javaweb
- javaweb 项目的系统权限管理,怎么设计?shiro简单了解
- JAVAWEB开发之权限管理(三)——shiro与企业项目整合开发(基于Spring)
- 权限管理
- 权限管理
- 权限管理
- 权限管理
- 权限管理
- 权限管理
- 权限管理
- 权限管理
- 权限管理
- FFmpeg命令详解
- csu1804 拓扑排序+dp
- 【漏洞分析】Discuz X3.3补丁安全分析
- Mysql编码问题总结
- HDU2490 Parade 单调队列优化DP
- JavaWeb-权限管理
- 最短路专题
- C++之单例模式代码实现
- [ ArcGIS for Server 10.1 系列 ]
- 转载的psql基础知识
- 1002:一元二次方程
- redis3.0.0配置文件详解
- opencl 返回值
- 学习 R 语言词云wordcloud--笔记