权限管理

1.权限管理体系

粗粒度权限控制:

使用拦截器从宏观上控制用户对资源的访问

细粒度权限控制:

 

将用户没有权限访问的资源隐藏起来

2.权限管理体系的目的

将应用程序的功能保护起来,让没有权限的用户不能访问。

3.权限管理体系模型:RBAC

Role Base Authority Controlle

①资源:整个权限管理体系要保护的具体功能。在Web项目中体现为一系列URL地址。由于同一个Web项目中Web应用虚拟路径是一样的,所以关注servletPath即可。
实体类名:Res
 
②权限[狭义]:在访问资源时,很多资源是彼此相互联系的,它们应该封装到一起统一分配。
更新调查权限:
/guest/survey/updateSurvey
/guest/survey/toEditUI/2
/guest/survey/showMyUncompleted【共有资源】
删除调查权限:
/guest/survey/removeSurvey/2
/guest/survey/showMyUncompleted【共有资源】
狭义的权限就是多个资源的封装。
实体类名:Auth
③角色:用户分类。用户往往数量很多,具体权限数量可能也会很多。直接把权限分配给用户会造成错综复杂的关联关系,不同用户具备的权限可能是杂乱无章的。而项目功能确定后用户分类通常的固定的,而且数量不会很多。所以应该将具体权限分配给角色,再将用户划分到不同角色下。
实体类名:Role
④用户:操作系统的人登录系统时使用的账号。
User
Admin
4.四个实体类之间关联关系
①Auth→Res:单向多对多[1]多对多(数据库表之间的关系)
一个Auth包含多个Res
  一个Res也可以被分配给多个不同Auth
  [2]单向(Java类之间的关系)
  有:auth.getResSet();
  无:res.getAuthSet();——从项目功能角度看不关心
②Role→Auth:单向多对多
③Admin→Role:单向多对多
④User→Role:单向多对多
5.多对多关联关系
结论:表示多对多关联关系必须要有中间表
中间表主键解决方案
①方案一:另外创建一个字段专门作为主键
②方案二:用当前的两个字段共同组成联合主键
[1]参与联合主键的字段本身可以有重复数据
[2]联合主键组成的值整体不能重复
6.权限的验证
①具体来说:当一个具体的用户真切的访问一个具体的资源时,判断这个用户能不能访问。
②验证方案:基于二进制位运算(bitwise)进行验证

i.给每一个资源设置一个权限码字段

资源名称 权限码 用户访问标识
/res01 0000 0001
/res02 0000 0010 √
/res03 0000 0100
……
/res07 0100 0000 √

ii.计算用户的权限码数值:把用户所有可以访问的权限码放在一起做或运算
0000 0010
0100 0000 |
--------------
0100 0010

iii.当用户访问/res01时验证是否有权限?把用户的权限码数值和资源的权限码数值放在一起做与运算
0100 0010
0000 0001 &
---------------
0000 0000
结果为零,表示不能访问

iv.当用户访问/res02时验证是否有权限?
0100 0010
0000 0010 &
--------------
0000 0010
结果非零,表示可以访问

 

③验证方案改进:在权限码基础上再附加权限位

1.初步方案的局限
byte类型:1字节,8位,最多表示7个资源
short类型:2字节,16位,最多表示15个资源
int类型:4字节,32位,最多表示31个资源
long类型:8字节,64位,最多表示63个资源

2.给资源在权限码之外再设置一个权限位

资源名称 权限码 权限位 用户访问标识
/res01 0000 0001 0
/res02 0000 0010 0 √
/res03 0000 0100 0
……
/res07 0100 0000 0 √
/res08 0000 0001 1
/res09 0000 0010 1 √
/res10 0000 0100 1
……
/res14 0100 0000 1
/res15 0000 0001 2
/res16 0000 0010 2

3.计算用户的权限码数组:按照各个权限位分别计算
①计算权限位0上面的权限码数值
0000 0010
0100 0000 |
------------
0100 0010
②计算权限位1上面的权限码数值
0000 0010
0000 0000 |
------------
0000 0010
③计算权限位2上面的权限码数值
0000 0000
※注意:就算某个权限位上面没有任何资源可以访问也要用0占据这一位,不能没有任何一个权限位

④结果需要存入用户对象中
0:66
1:2
2:0

数组:[66,2,0]各个权限位值正好是这个数组的下标

4.验证方式
①访问/res09
[1]根据/res09从数据库中查询对应的数据
资源名 资源权限码 资源权限位
/res09 0000 0010 1
[2]以资源权限位为下标,从用户的权限码数组中取值
[66,2,0]→下标1→2
[3]用2和资源权限码做与运算
0000 0010
0000 0010 &
------------
0000 0010
[4]结果非零,可以访问
②访问/res16
[1]根据/res16从数据库中查询对应的数据
资源名 资源权限码 资源权限位
/res16 0000 0010 2
[2]以资源权限位为下标,从用户的权限码数组中取值
[66,2,0]→下标2→0
[3]用0和资源权限码做与运算
0000 0000
0000 0010 &
------------
0000 0000
[4]结果为零,不能访问

 

7.manager_res表
①主键:res_id
②servlet_path
③public_status
true:公共资源
false:受保护资源
④权限码:res_code
⑤权限位:res_pos
 
8.manager_auth表
①主键:auth_id
②权限名:auth_name
 
9.manager_role表
①主键:role_id
②角色名:role_name
 
10.实体类
Res
Auth:额外增加resSet属性
Role:额外增加authSet属性
11.建立数据
①Res
[1]用拦截器动态生成具体的Res数据
[2]以列表形式显示所有Res
[3]以Ajax方式切换Res的publicStatus状态
[4]批量删除
②Auth
[1]通过表单创建
[2]以列表形式显示所有Auth
[3]以Ajax方式修改Auth名称
[4]批量删除
③Role
[1]通过表单创建
[2]以列表形式显示所有Role
[3]以Ajax方式修改Role名称
[4]批量删除
④Admin
[1]通过表单创建
[2]以列表形式显示所有Admin
⑤给Auth分配Res
⑥给Role分配Auth
⑦给Admin分配Role
 
 
posted @ 2017-10-20 12:23  lamsey16  阅读(229)  评论(0编辑  收藏  举报