权限管理
粗粒度权限控制:
使用拦截器从宏观上控制用户对资源的访问
细粒度权限控制:
将用户没有权限访问的资源隐藏起来
将应用程序的功能保护起来,让没有权限的用户不能访问。
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【共有资源】狭义的权限就是多个资源的封装。
③角色:用户分类。用户往往数量很多,具体权限数量可能也会很多。直接把权限分配给用户会造成错综复杂的关联关系,不同用户具备的权限可能是杂乱无章的。而项目功能确定后用户分类通常的固定的,而且数量不会很多。所以应该将具体权限分配给角色,再将用户划分到不同角色下。
④用户:操作系统的人登录系统时使用的账号。
中间表主键解决方案
①方案一:另外创建一个字段专门作为主键②方案二:用当前的两个字段共同组成联合主键
①具体来说:当一个具体的用户真切的访问一个具体的资源时,判断这个用户能不能访问。②验证方案:基于二进制位运算(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]结果为零,不能访问
①主键:res_id②servlet_path③public_status
true:公共资源false:受保护资源④权限码:res_code⑤权限位:res_pos
①主键:auth_id②权限名:auth_name
①主键:role_id②角色名:role_name
ResAuth:额外增加resSet属性Role:额外增加authSet属性
①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