文档章节

多公司权限模型

光石头
 光石头
发布于 2012/12/17 22:55
字数 1722
阅读 1118
收藏 27

此文转自我的个人博客:http://www.weicms.net/2012/12/17/quanxian.html

 

今天和一个网友争论了权限的问题,我感觉有必要分享下我的研究心得.

权限 无非是 角色 人员 资源 的配比关系

权限的操作无非是 增删改查,导入,导出 的操作,以及针对数据集的操作

业务结构无非是 公司,部门,用户

在rest时代,权限无非是 对一个URL是否有权限操作! 权限的本质就是URL的访问控制!

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

-- ----------------------------

-- Table structure for `users`

-- 都是常用的字段

-- ----------------------------

DROPTABLEIF EXISTS `users`;

CREATETABLE`users` (

  `id`varchar(40)NOTNULL,

  `name`varchar(50)DEFAULTNULL,

  `userCode`varchar(50)NOTNULL,

  `password`varchar(50)NOTNULL,

  `email`varchar(100)DEFAULTNULL,

  PRIMARYKEY(`id`)

) ENGINE=InnoDBDEFAULTCHARSET=utf8;

 

---角色表

---角色是继承关系

---level,roleCode为表示层级关系,部门表类似.主要用于快速查询,抛弃递归函数.

DROPTABLEIF EXISTS `role`;

CREATETABLE`role` (

  `id`varchar(50)NOTNULLDEFAULT'',

  `pid`varchar(50)NOTNULLDEFAULT'',--父角色ID

  `roleName`varchar(200)NOTNULL,

  `level`intNOTNULLDEFAULT0,--角色处的层级,根角色为1,它的子角色为2 孙角色为3

  `roleCode`varchar(200)NOTNULL,--根角色001 他的子角色为001001,001002...孙角色为001001001,001002001....依次类推.

  PRIMARYKEY(`id`)

) ENGINE=InnoDBDEFAULTCHARSET=utf8;

 

-- ----------------------------

-- Table structure for `model`

-- ----------------------------

DROPTABLEIF EXISTS `model`;

CREATETABLE`model` (

  `id`varchar(50)NOTNULL,

  `modelName`varchar(200)NOTNULL,

  PRIMARYKEY(`id`)

) ENGINE=InnoDBDEFAULTCHARSET=utf8;

 

----

-- ----------------------------

-- Table structure for `re_user_role`用户角色中间表

-- ----------------------------

DROPTABLEIF EXISTS `re_user_role`;

CREATETABLE`re_user_role` (

  `id`varchar(50)NOTNULL,

  `userId`varchar(50)NOTNULL,

  `roleId`varchar(50)NOTNULL,

  PRIMARYKEY(`id`)

) ENGINE=InnoDBDEFAULTCHARSET=utf8;

 

--角色资源中间表

DROPTABLEIF EXISTS `re_role_model`;

CREATETABLE`re_role_model` (

  `id`varchar(50)NOTNULL,

  `roleId`varchar(50)NOTNULL,

 -- `startDate` datetime,

 -- `endDate` datetime,--表示权限的生存周期,用于领导临时分配权限,这里简化暂不讨论

 -- allunit int,--主要用于判断是否级联下级部门,这里不讨论

  `pageurl`varchar(1000)NOTNULL,

  `bool`int(11)NOTNULLDEFAULT'1',--表示真假,0为假,1为真

  PRIMARYKEY(`id`)

) ENGINE=InnoDBDEFAULTCHARSET=utf8;

基本表结构如此,其他例如 unit 什么的这里就不写了

说下场景,借用网友的一张图片啊
154119_GsbS_724215
这里要重点说下 re_user_model 中间表的pageurl 和bool字段

pageurl是一个正则表达式,用于匹配用户访问的URL .    bool表示真假,前提是pagurl必须匹配.

pageurl 和model表也没有直接关系了,只是一个正则表达式而已.

如果pagurl匹配时, bool=0表示不可访问,bool=1表示可以访问此url.例如 角色superuser 能够访问除了/admin/开头之外的所有url.就可以在数据库插入两条数据

1

2

INSERTINTO`re_role_model`VALUES('b1156249-9a8c-4f71-99ca-f56864401c41','superuser','(.*)','1');

INSERTINTO`re_role_model`VALUES('fa1f2c33-b5b8-4134-ae50-53334de61fc3','superuser','.*/admin/.*','0');

根据 bool字段正序查询

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

String model_sql="SELECT re.* FROM re_role_model as re,re_user_role as rerole 

where

re.roleId=rerole.roleId and rerole.userId=:userId order by re.bool asc";

 

//对比url是否匹配

booleanflag=false;

for(Re_Role_Model m:models){

String pageurl=m.getPageurl();

Integer bool=m.getBool();

Pattern pattern = Pattern.compile(pageurl);

Matcher matcher = pattern.matcher(requestURL);//请求的url是否具有权限

booleanf=matcher.matches();

if(f&&(bool==0)){//如果没有权限,跳出.

flag=false;

break;

}

 

if(f&&(bool==1)){

flag=true;

break;

}

}

returnflag;

这是整个控制的核心 访问的url是根据正则匹配的!!  通过rest 将数据权限转变成对URL的访问控制

系统依赖rest实现权限的控制

约定url如下 : /{model}/{operation}/{公司ID}/ 为标准开头

操作约定为 save/delete/update/get/import/export

我认为 公司拥有单独的组织结构,可以认为是根,所以单独列出.当然也可以根据业务需要去掉{公司ID}

例如 /user/update/abc/unit789/123  (/user/update/{公司ID}/{部门ID}/{userID})意义为 修改 abc公司下部门为unit789 id为123的员工信息

所有的角色都是从根角色派生而来(可以根据业务实际需要决定是否角色继承),根角色为 admin(超级管理员) 其他的角色都是依次派生 就和主管分配权限是一致的. 例如 superuser 派生自admin

1

2

insert into role values('admin','','超级管理员','1','001')

insert into role values('superuser','admin','超级用户','2','001001')

主管操作是一样的,这个其实用户前台操作比较复杂,后台理顺关系还是比较简单的.每个用户都可以从自己的权限范围内分给其他用户(其实也是角色,只是后台默认生成了)

关于re_role_model 中的 allunit 主要是用来判断是否包含子部门

例如 admin给 superuser分配了.*/user/get/gs123/unitabc/.*  (/user/get/{公司ID}/{部门ID}) 用来判断 superuser是否能够查询 unitabc下的所有子部门 如果unitabc下的部门较少 可以用多条记录代替 例如

..*/user/get/gs123/unitabc1/.*   .*/user/get/gs123/unitabc2/.*  如果子部门较多 可以启用 allunit 字段,根据实际情况自行判断吧

 

pageurl正则表达式,反转获得实际权限数据 可 以扩展实现数据库正则函数,在sql中直接对比.

示例

select u.* from unit as u ,re_role_model as re where regfun('/update/'+u.id+'/',re.pageurl,re.bool) and re.roleid='admin'

关于大家关心的sql注入我这里说下

1.会有过滤器过滤非法的url字符

2.如果你伪造了url 可以通过我的权限过滤器,但是却无法找到controller,404.例如 我的controller 接收路径为 /usr/update/abc  你给我发送了 /user/update/abc/d/c   controller无法相应此请求.

3.regfun这个函数的参数不是从前台获取的,而是根据业务逻辑后台拼装的!

----------------------------------------------------权限系统的思想基本介绍完毕了.--------------------------------

来个实例

添加管理员  admin_add  有全局添加权限  .*/save/.*  bool 为1.

当然也可以具体到某个公司,某个部门,某个人.也就是数据集权限

因为 有 bool 字段做判断. 可以很容易做出交叉权限,例如上例的superuser 除了/admin/其他的都有权限访问.

save/delete/update/get/import/export 其实代表了操作 可以根据需要添加角色的权限.角色是继承的,所以用户可以再自己的权限范围内 自由分配给其他用户.

当然有些也是可以系统定义的 例如

.*/user/delete/admin.* bool 为0 roleid为 *   任何角色都没有权限删除超级管理员的权限. 这些都是系统后台定义的.

最小权限.例如 普通用户 abc只有访问自己信息的权限

pageurl为:  */user/update/abc.*  (当然,这里可以使用二次解析的通配符,暂不讨论)

如果用户abc向非法修改 用户f的信息 那么访问的url是  */user/update/f.*     数据库没有匹配的url,没有权限访问

 

© 著作权归作者所有

共有 人打赏支持
光石头

光石头

粉丝 317
博文 92
码字总数 17546
作品 2
郑州
程序员
加载中

评论(25)

y
ylmotol7

引用来自“屁屁果”的评论

引用来自“哈库纳”的评论

引用来自“屁屁果”的评论

引用来自“哈库纳”的评论

引用来自“屁屁果”的评论

引用来自“屁屁果”的评论

引用来自“王瑞平”的评论

理解浅了,遇到数据权限就崩溃了
比如销售人员分配销售电话,每个人只能操作自己分配到的数据
当一个销售离职了,数据收回再分配或者直接转交****
复杂的问题预先没有计划到时很多系统做到结束时发现失败的跟本原因
再考虑你的系统里有几百个各级管理员情况下怎么办
只考虑这一步也太简单

url可以非常复杂,然后加密成短url,例如新浪微博

每个数据都是一条url,然后销售人员拥有这些url的权限

数据权限中 查看权限如何实现。 就是说不让列表中出现不想看到的数据。

资源是定义到业务表上,还是另起一个资源管理表。 感觉数据权限这块还是没有办法全面控制,建议数据权限彻底分离出去。

数据权限的确很难和业务剥离......例如不想让让用户查看某条特殊的数据,资源匹配表里加入一条url,列表的情况 需要使用正则表达式 排除这样的数据,实现也是比较复杂......

我觉得数据权限最好的方式还是干脆放弃不做,交由业务系统实现时进行考虑。这样设计就简单了很多。

嗯,这篇文章只是写出了我的实现思想和理论,并没有用到生成环境,实际的生产环境数据权限是有业务自行实现的
嗯,自由
哈库纳
哈库纳

引用来自“屁屁果”的评论

引用来自“哈库纳”的评论

引用来自“屁屁果”的评论

引用来自“哈库纳”的评论

引用来自“屁屁果”的评论

引用来自“屁屁果”的评论

引用来自“王瑞平”的评论

理解浅了,遇到数据权限就崩溃了
比如销售人员分配销售电话,每个人只能操作自己分配到的数据
当一个销售离职了,数据收回再分配或者直接转交****
复杂的问题预先没有计划到时很多系统做到结束时发现失败的跟本原因
再考虑你的系统里有几百个各级管理员情况下怎么办
只考虑这一步也太简单

url可以非常复杂,然后加密成短url,例如新浪微博

每个数据都是一条url,然后销售人员拥有这些url的权限

数据权限中 查看权限如何实现。 就是说不让列表中出现不想看到的数据。

资源是定义到业务表上,还是另起一个资源管理表。 感觉数据权限这块还是没有办法全面控制,建议数据权限彻底分离出去。

数据权限的确很难和业务剥离......例如不想让让用户查看某条特殊的数据,资源匹配表里加入一条url,列表的情况 需要使用正则表达式 排除这样的数据,实现也是比较复杂......

我觉得数据权限最好的方式还是干脆放弃不做,交由业务系统实现时进行考虑。这样设计就简单了很多。

嗯,这篇文章只是写出了我的实现思想和理论,并没有用到生成环境,实际的生产环境数据权限是有业务自行实现的

我看了一下文章,感觉上其实就是 RBAC 3个级别中 级别比较高级别的一个实现,挺不错的。
光石头
光石头

引用来自“哈库纳”的评论

引用来自“屁屁果”的评论

引用来自“哈库纳”的评论

引用来自“屁屁果”的评论

引用来自“屁屁果”的评论

引用来自“王瑞平”的评论

理解浅了,遇到数据权限就崩溃了
比如销售人员分配销售电话,每个人只能操作自己分配到的数据
当一个销售离职了,数据收回再分配或者直接转交****
复杂的问题预先没有计划到时很多系统做到结束时发现失败的跟本原因
再考虑你的系统里有几百个各级管理员情况下怎么办
只考虑这一步也太简单

url可以非常复杂,然后加密成短url,例如新浪微博

每个数据都是一条url,然后销售人员拥有这些url的权限

数据权限中 查看权限如何实现。 就是说不让列表中出现不想看到的数据。

资源是定义到业务表上,还是另起一个资源管理表。 感觉数据权限这块还是没有办法全面控制,建议数据权限彻底分离出去。

数据权限的确很难和业务剥离......例如不想让让用户查看某条特殊的数据,资源匹配表里加入一条url,列表的情况 需要使用正则表达式 排除这样的数据,实现也是比较复杂......

我觉得数据权限最好的方式还是干脆放弃不做,交由业务系统实现时进行考虑。这样设计就简单了很多。

嗯,这篇文章只是写出了我的实现思想和理论,并没有用到生成环境,实际的生产环境数据权限是有业务自行实现的
哈库纳
哈库纳

引用来自“屁屁果”的评论

引用来自“哈库纳”的评论

引用来自“屁屁果”的评论

引用来自“屁屁果”的评论

引用来自“王瑞平”的评论

理解浅了,遇到数据权限就崩溃了
比如销售人员分配销售电话,每个人只能操作自己分配到的数据
当一个销售离职了,数据收回再分配或者直接转交****
复杂的问题预先没有计划到时很多系统做到结束时发现失败的跟本原因
再考虑你的系统里有几百个各级管理员情况下怎么办
只考虑这一步也太简单

url可以非常复杂,然后加密成短url,例如新浪微博

每个数据都是一条url,然后销售人员拥有这些url的权限

数据权限中 查看权限如何实现。 就是说不让列表中出现不想看到的数据。

资源是定义到业务表上,还是另起一个资源管理表。 感觉数据权限这块还是没有办法全面控制,建议数据权限彻底分离出去。

数据权限的确很难和业务剥离......例如不想让让用户查看某条特殊的数据,资源匹配表里加入一条url,列表的情况 需要使用正则表达式 排除这样的数据,实现也是比较复杂......

我觉得数据权限最好的方式还是干脆放弃不做,交由业务系统实现时进行考虑。这样设计就简单了很多。
光石头
光石头

引用来自“哈库纳”的评论

引用来自“屁屁果”的评论

引用来自“屁屁果”的评论

引用来自“王瑞平”的评论

理解浅了,遇到数据权限就崩溃了
比如销售人员分配销售电话,每个人只能操作自己分配到的数据
当一个销售离职了,数据收回再分配或者直接转交****
复杂的问题预先没有计划到时很多系统做到结束时发现失败的跟本原因
再考虑你的系统里有几百个各级管理员情况下怎么办
只考虑这一步也太简单

url可以非常复杂,然后加密成短url,例如新浪微博

每个数据都是一条url,然后销售人员拥有这些url的权限

数据权限中 查看权限如何实现。 就是说不让列表中出现不想看到的数据。

资源是定义到业务表上,还是另起一个资源管理表。 感觉数据权限这块还是没有办法全面控制,建议数据权限彻底分离出去。

数据权限的确很难和业务剥离......例如不想让让用户查看某条特殊的数据,资源匹配表里加入一条url,列表的情况 需要使用正则表达式 排除这样的数据,实现也是比较复杂......
哈库纳
哈库纳

引用来自“屁屁果”的评论

引用来自“屁屁果”的评论

引用来自“王瑞平”的评论

理解浅了,遇到数据权限就崩溃了
比如销售人员分配销售电话,每个人只能操作自己分配到的数据
当一个销售离职了,数据收回再分配或者直接转交****
复杂的问题预先没有计划到时很多系统做到结束时发现失败的跟本原因
再考虑你的系统里有几百个各级管理员情况下怎么办
只考虑这一步也太简单

url可以非常复杂,然后加密成短url,例如新浪微博

每个数据都是一条url,然后销售人员拥有这些url的权限

数据权限中 查看权限如何实现。 就是说不让列表中出现不想看到的数据。

资源是定义到业务表上,还是另起一个资源管理表。 感觉数据权限这块还是没有办法全面控制,建议数据权限彻底分离出去。
哈库纳
哈库纳

引用来自“屁屁果”的评论

引用来自“pengcheng_1024”的评论

看来还是我的能力太差啊!!还是没搞明白!!需要好好学习!!看来我的机会来的有点早!!

有一条一定要记住,不要使用递归函数,使用两个辅助字段 level 和 unitcode !我们上一代的权限体系就是参考了用友华为的系统,切记!!!! @宏哥 说mysql无法实现这样的权限控制,我简直无语了.......

嗯,使用 递归函数 容易引发死循环,level unitcode 这种设计推荐。
光石头
光石头

引用来自“屁屁果”的评论

引用来自“王瑞平”的评论

理解浅了,遇到数据权限就崩溃了
比如销售人员分配销售电话,每个人只能操作自己分配到的数据
当一个销售离职了,数据收回再分配或者直接转交****
复杂的问题预先没有计划到时很多系统做到结束时发现失败的跟本原因
再考虑你的系统里有几百个各级管理员情况下怎么办
只考虑这一步也太简单

url可以非常复杂,然后加密成短url,例如新浪微博

每个数据都是一条url,然后销售人员拥有这些url的权限
光石头
光石头

引用来自“王瑞平”的评论

理解浅了,遇到数据权限就崩溃了
比如销售人员分配销售电话,每个人只能操作自己分配到的数据
当一个销售离职了,数据收回再分配或者直接转交****
复杂的问题预先没有计划到时很多系统做到结束时发现失败的跟本原因
再考虑你的系统里有几百个各级管理员情况下怎么办
只考虑这一步也太简单

url可以非常复杂,然后加密成短url,例如新浪微博
王瑞平
王瑞平
理解浅了,遇到数据权限就崩溃了
比如销售人员分配销售电话,每个人只能操作自己分配到的数据
当一个销售离职了,数据收回再分配或者直接转交****
复杂的问题预先没有计划到时很多系统做到结束时发现失败的跟本原因
再考虑你的系统里有几百个各级管理员情况下怎么办
只考虑这一步也太简单
漫谈业务系统从0到1的设计

摘要:互联网公司常常将产品方向分为两类,C端和B端,C端主要是面向客户和消费者的系统,B端的范围则相对模糊,给供应商或商家使用的系统,给内部业务人员使用的系统,都统称为B端系统。C端和...

goYangKun
2017/12/14
0
0
易贝内容管理系统--EBCMS

易贝内容管理系统EBCMS采用流行的PHP+MySQL架构设计,MVC设计模式,完全开源。 EBCMS是基于ThinkPHP开发的一套内容管理系统。我们的宗旨是给客户提供一套持久更新、功能全面、操作便捷的供大...

EBCMS
2016/02/02
3.9K
0
【权限管理】角色访问控制(RBAC)模式及其思想

本文为转载学习 原文链接:http://hi.baidu.com/boyyf/item/2bc5c8320f7ce4c22e8ec2ca Role作为一个用户(User)与权限(Privilege)的代理层,解耦了权限和用户的关系,所有的授权应该给予R...

heroShane
2014/01/26
0
0
基于ASP.NET+C#实现的superflow工作流平台架构设计

SuperFlow工作流平台纯B/S架构, 采用VS2005(08/10)+C#+ASP.NET进行开发实现,由SuperFlow控制台及SuperFlow协同办公平台组成。现在的大型信息化系统,尤其是基于GIS的综合电 子政务应用系统,...

成都领君科技
2013/02/26
0
0
Jira和Confluence的权限管理

(关于Jira和Confluence的基本介绍请参看文章团队协作,集成工具推荐) 背景:已经使用Jira和Confluence管理了一个产品团队的任务和资源,现在又想加入另外一个产品团队的任务和资源,首要问题是...

yaocoder
2014/08/30
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

深夜胡思乱想

魔兽世界 最近魔兽世界出了新版本, 周末两天升到了满级,比之前的版本体验好很多,做任务不用抢怪了,不用组队打怪也是共享拾取的。技能简化了很多,哪个亮按哪个。 运维 服务器 产品 之间的...

Firxiao
9分钟前
0
0
MySQL 8 在 Windows 下安装及使用

MySQL 8 带来了全新的体验,比如支持 NoSQL、JSON 等,拥有比 MySQL 5.7 两倍以上的性能提升。本文讲解如何在 Windows 下安装 MySQL 8,以及基本的 MySQL 用法。 下载 下载地址 https://dev....

waylau
43分钟前
0
0
微信第三方平台 access_token is invalid or not latest

微信第三方开发平台code换session_key说的特别容易,但是我一使用就带来无穷无尽的烦恼,搞了一整天也无济于事. 现在记录一下解决问题的过程,方便后来人参考. 我遇到的这个问题搜索了整个网络也...

自由的开源
今天
0
0
openJDK之sun.misc.Unsafe类CAS底层实现

注:这篇文章参考了https://www.cnblogs.com/snowater/p/8303698.html 1.sun.misc.Unsafe中CAS方法 在sun.misc.Unsafe中CAS方法如下: compareAndSwapObject(java.lang.Object arg0, long a......

汉斯-冯-拉特
今天
2
0
设计模式之五 责任链模式(Chain of Responsibility)

一. 场景 相信我们都有过这样的经历; 我们去职能部门办理一个事情,先去了A部门,到了地方被告知这件事情由B部门处理; 当我们到了B部门的时候,又被告知这件事情已经移交给了C部门处理; ...

JackieRiver
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部