RBAC基于角色的权限管理--设计篇1.0_小祝特烦恼的博客-程序员宝宝

技术标签: Java  权限设计  rbac  

RBAC基于角色的权限管理–设计篇1.0

RBAC是什么

基于角色的权限管理。简单来说就是一个用户可以拥有若干个角色,一个角色可以拥有若干个权限。这样就形成了“用户-角色-权限”的模型。

基础表设计

  • 数据库采用MySql
  • 这里表设计只采用最基础的字段
  • 忽略字段长度,如采用此设计,请自行修改
  • 忽略外键建设,如采用此设计,请自行建立

用户表

CREATE TABLE `t_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `create_user` datetime DEFAULT NULL COMMENT '创建人',
  `login_time` datetime DEFAULT NULL COMMENT '登录时间',
  `name` varchar(255) DEFAULT NULL COMMENT '用户名称',
  `password` varchar(255) DEFAULT NULL COMMENT '登录密码',
  `remark` varchar(255) DEFAULT NULL COMMENT '备注',
  `status` int(11) DEFAULT NULL COMMENT '用户状态',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  `update_user` datetime DEFAULT NULL COMMENT '更新人员',
  `username` varchar(255) DEFAULT NULL COMMENT '登录名称',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

角色表

CREATE TABLE `t_role` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '角色id',
  `role_name` varchar(255) DEFAULT NULL COMMENT '角色名称',
  `remark` varchar(255) DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

权限表

CREATE TABLE `t_permission` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '权限ID',
  `permission_code` varchar(255) DEFAULT NULL COMMENT '权限编码',
  `permission_name` varchar(255) DEFAULT NULL COMMENT '权限名称',
  `pid` int(11) DEFAULT NULL COMMENT '父类权限ID(依赖权限)',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

用户角色关系表

CREATE TABLE `t_user_role` (
  `user_id` int(11) NOT NULL COMMENT '用户id',
  `role_id` int(11) NOT NULL COMMENT '角色id',
  PRIMARY KEY (`user_id`,`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

角色权限关系表

CREATE TABLE `t_role_permission` (
  `role_id` int(11) NOT NULL COMMENT '角色id',
  `permission_id` int(11) NOT NULL COMMENT '权限id',
  PRIMARY KEY (`role_id`,`permission_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

权限控制

控制菜单

场景

管理员和普通会员。如管理员可以看到所有菜单,普通会员只能看到一部分菜单(或可以看到,但点击时弹出没有权限操作的提示。由于个人喜好和个人体验度偏差的原因,此文章中不采取这种方式)。

问题来了,如何控制角色的菜单权限?let‘s go!!!

表设计

CREATE TABLE `t_menu` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `menu_name` varchar(255) DEFAULT NULL COMMENT '菜单名称',
  `permission_code` varchar(255) DEFAULT NULL COMMENT '权限编码(菜单编码)',
  `pid` int(11) DEFAULT NULL COMMENT '父菜单id',
  `url` varchar(255) DEFAULT NULL COMMENT '菜单url跳转链接',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

简要业务流程图

菜单控制-简要业务流程图

详细业务流程图

菜单控制-详细业务流程图

控制按钮

场景

拥有了菜单权限,依旧不能满足某些场景的需要。例如多个角色在同时拥有A菜单的情况下,角色1可以有查询,创建的权限,角色2则拥有查询,创建,修改,删除的权限。即角色1只能看到查询,创建的按钮,角色2可以看到查询,创建,修改,删除的按钮。这个时候,我们应该如何处理呢?

实现

  • 按钮权限定义:在菜单权限下定义下级权限查询,创建,修改,删除,例如Aquery,Aadd,Aupdate,Adelete。
  • 这里结合shiro使用(不会使用的小伙伴请留言,后期补上解决方式):在A菜单跳转的页面中使用则可以达到控制按钮的效果。例如

        <shiro:hasPermission name="Aadd">
            <button>新建<button>
        </shiro:hasPermission> 

详细业务流程图(结合shiro)

按钮控制-详细业务流程图

代码示例(思想很重要)

检查用户是否有菜单权限
/**
 * 检查用户是否有菜单权限
 * 
 * @param menus
 *            所有菜单
 * @param subject
 *            shiro用户信息
 * @return 用户已分配的菜单集合
 */
private List<Menu> check(List<Menu> menus, Subject subject) {
    List<Menu> res = new ArrayList<Menu>();
    for (Menu m1 : menus) {
        if (StringUtils.isEmpty(m1.getPermissionCode())) {
            continue;
        }
        // 这里会触发鉴权操作
        if (subject.isPermitted(m1.getPermissionCode())) {
            res.add(m1);
        }
    }
    return res;
}
自定义realm-鉴权操作
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    // 查询当前用户所有权限
    List<Permission> infos = userService.findMyPermitions();
    // 权限集合(这里我习惯把权限编码放进去)
    Set<String> permissions = new HashSet<String>();
    // 角色集合(这里放角色ID)
    Set<String> roles = new HashSet<String>();
    if (infos != null && infos.size() > 0) {
        for (Permission info : infos) {
            permissions.add(info.getPermissionCode());
            roles.add(info.getRoleId());
        }
    }
    SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
    authorizationInfo.setStringPermissions(permissions);
    authorizationInfo.setRoles(roles);
    return authorizationInfo;
}

数据权限

场景

有些业务可能会是这样。一个列表(或表格),要求普通用户只能看到自己创建的列表信息,业务部门经理只能看到本部门的所有列表信息。这种权限如何控制?

实现

看留言反应,下回见。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_22857293/article/details/78951532

智能推荐

C++和C#进程间通过命名管道来通信_beattwo的博客-程序员宝宝

C++和C#进程之间通过命名管道通信(上) “命名管道”是一种简单的进程间通信(IPC)机制。命名管道可在同一台计算机的不同进程之间,或在跨越一个网络的不同计算机的不同进程之间,支持可靠的、单向或双向的数据通信。用命名管道来设计应用程序实际非常简单,并不需要事先深入掌握基层网络传送协议(如TCP/IP或IPX)的知识。因为命名管道利用了微软网络提供者(MSNP)重定向器,通过一个网...

0353-如何使用curl命令调用CM的API动态配置Yarn资源池_Hadoop_SC的博客-程序员宝宝

温馨提示:如果使用电脑查看图片不清晰,可以使用手机打开文章单击文中的图片放大查看高清原图。Fayson的github:https://github.com/fayson/cdhproject提示:代码块部分可以左右滑动查看噢1.文档编写目的在使用CDH集群大数据平台过程中,用户会有需求在自己的统一管理平台上通过API接口能够动态的设置Yarn资源池,Cloudera Manager...

Android 和 Linux 关系_柚咖的博客-程序员宝宝_linux和安卓的关系

  Android 和 Linux 关系密切,Android 采用 Linux 作为内核,对 Linux 内核做了一定修改,使其适应移动设备上的应用。Android 开始时是作为 Linux 的一个分支,后来由于无法并入 Linux 的开发树,被 Linux 内核组从开发树中删除。Android 继承于 Linux  Android 是基于 Linux 2.6 的内核基础上运行的,提供的核心系统服务包括安全、内存管理、进程管理、网络组和驱动模型等内容。但是,严格来说,Android 不算是 Linux

ACL2020有关可解释性的文章_Kenny_SI的博客-程序员宝宝

DTCA: Decision Tree-based Co-Attention Networks for Explainable Claim Verification摘要:Recently, many methods discover effective evidence from reliable sources by appropriate neural networks for explainable claim verification, which has been widely recogni

django 字段DateTimeField用法 200315_whalecode的博客-程序员宝宝_datetimefield

时间的三个字段DateTimeField迁移后的类型使用例子now函数返回的是utc的时间utc时间与我们相差八个小时使用本地的时间设置中的时间配置结果小结,把别的时间转换成本地时间localtime(日期时间)auto_now_add参数创建时间适用auto_now参数更新时间适用总结DateTimeField的用法记录信息发布...

随便推点

LeetCode常见题型——图_贫道绝缘子的博客-程序员宝宝_leetcode 图

图是树的升级版。图通常分为有向(directed)或无向(undirected),有循环(cyclic)或无循环(acyclic),所有节点相连(connected)或不相连(disconnected)。

编程寓言:两位新手正讨论常用快捷键,路边乞丐直接说出答案!_普通网友的博客-程序员宝宝

两位大一新生刚刚开始学习C语言,并畅想着以后要成为一名优秀的C语言程序员,可谓是志向远大!这时,同伴突然向他询问了一个问题,问他编程里边这么多快捷键,我们学习C语言最常用的快捷键是哪一个,这个同伴苦思冥想了半天,奈何自己刚刚接触学习的C语言,还没弄清楚自己最常用的快捷键。一边走一边想,还是没有得到答案,可是没想到,路边的一个乞丐,却突然给出了答案······以上...

Oracle - 2.0 - 【学习笔记】for ocp 12c、体系结构、网络_LawssssCat的博客-程序员宝宝

测试package cn.edut.tarena.demo1;import java.math.BigDecimal;public class Test7_BigDEcimal { public static void main(String[] args) { // 接受用户数输入的两个浮点数 double f1 = 10.5 ; double f2 = 3.1; ...

关于《ERP原理》的读书笔记和思考(二)_ERP原理初探_猫撵耗子的博客-程序员宝宝

ERP定义支持混合方式的制作环境(1)生产方式的混合    离散型和流程型制造的混合。单件生产、面向库存生产、面向订单装备。(2)经营方式的混合    跨国的混合经营(3)生产、分销和服务等业务的混合提供据测能力支持ERP的能动性。ERP系统的一般构成1、主生产计划主生产计划员利用ERP系统提供一个模拟环境,ERP系统利用模拟数据库计算处相应

浏览器本地存储 sessionStorage和localStorage_ALKEN ABBY的博客-程序员宝宝_浏览器的sessionstorage

一. sessionStorage和localStorage的Api是一样的,都是四种// 保存一个数据setItem(key,value)// 读取一个数据getItem(key)// 删除一个数据removeItem(key)// 清空所有数据clear()// 注意:4个方法里面的key和value都是字符串类型的二. 下面是具体例子:localStorage使用:&lt;!DOCTYPE html&gt;&lt;html lang="en"&gt;&lt;head&g

推荐文章

热门文章

相关标签