J2EE-RBAC权限管理
前不久在http://blog.chinaunix.net/u1/52224/showart_410119.html讲述了业务系统的权限管理模型,并在http://blog.chinaunix.net/u1/52224/showart_412714.html实现了模型中的SSO单点登陆,这次讲述的是权限管理、权限验证的实现,并附带一个用户管理的Demo,用户管理的Demo很粗糙,基本上只是一个演示。
RBAC是基于角色的权限管理,RBAC参考(http://csrc.nist.gov/rbac/ ),有用户、角色、资源和权限四种主体,他们简化的关系如下:
资源和操作成对组成一种权限规则,角色关联到多个规则表示该角色拥有这些权限规则指定的权限,用户关联到多个角色表示用户拥有这些角色的权限。
上面的模型是Core RBAC,也就是RBAC的最基础的模型,更高级的模型提供了更多的管理功能,像角色继承和约束等,这里没有实现角色的继承和约束,著名的开源权限管理系统ACEGI(http://www.acegisecurity.org/ )已经做了实现,下面讲一下基于Core RABC三个扩充。
用户关联权限规则
在Core RBAC里面,用户通常不直接与权限规则关联,所有授权过程都是角色关联权限规则,然后用户关联到角色来实现,比如删除数据库这样一个过程,删除是操作,数据库是资源,(删除, 数据库)组成权限规则,如果要对用户bsmith授权允许删除数据库,那么可以将用户bsmith关联到已经拥有该权限的角色,如果没有合适的角色,那么必须新建一个角色比如叫admin,然后将(删除, 数据库)这个权限规则关联到admin,然后将bsmith关联到admin,而不能直接将(删除, 数据库)关联到bsmith。
将用户关联扩充到直接关联权限规则后,可以方便个别用户的特殊授权。也可以避免大量的特殊授权带来的角色零散性,也就是当上面的情况较多时,如果不能对用户直接关联权限规则,那么每次建立的角色数可能超过系统角色数,容易混淆。
权限规则集合
(操作, 资源)组成的权限规则理论上包含所有的系统权限规则,比如对数据库表T,有一个查询操作SELECT,那么权限规则就是(SELECT, T),如果还有一个数据库表T1,有一个查询操作SELECT,那么权限规则就是(SELECT, T1),资源和操作都是有限的,所以权限规则集合也是有限并且可以列举的,也就是可以一个一个的把这些权限规则记录下来,分配权限时只要找到这些权限规则,然后关联到相应的角色和用户就可以了。
不过实际情况往往比预想的复杂,第一种情况是虽然权限规则有限并且可以列举,但是数据可能很大,需要很大的存储空间,并且过多的记录会影响权限验证的查询速度。
第二个问题是对于像论坛文章这样的内容动态变化的系统,如果要对某个用户授予所有的权限,那么当论坛文章时,需要管理员手动关联这些增加的权限规则到该用户。当然,也可以采用在论坛文章业务逻辑处自动关联权限规则给用户,但是这样一方面没有达到权限系统和业务逻辑分开的目的,无法实现权限系统的重用,另一方面也需要设置一个标志来给哪些用户授权,难以统一化。
要解决这两个问题,一方面要使权限规则集合尽量小,另一方面要使这个集合能自动适应资源的动态变化。通配符是一个很好的解决方式,通过对资源和操作增加通配符,让资源和操作本身变成资源集合和操作集合,如对于数据库表T_USER, T_GROUP,可以用T_*来表示,*表示匹配所有字符串,那么(SELECT, T_*)就表示对所有以T_开头的数据库表的SELECT操作,这样以前的权限规则就变成了权限规则集合,如果(SELECT, T_*)被授权给用户,以后数据库表增加时,只要数据库表名称以T_开头,该用户都有权进行SELECT操作。这样权限管理就变成授权用户允许对某些资源进行某些操作,权限规则不再表示单个操作和单个资源的关联,而是一组操作和一组资源进行笛卡尔积的集合,即(操作, 资源) = 操作集×资源集。
关系数据库使用%表示匹配所有字符串,_表示匹配单个字符,使用like关键字进行匹配判断,所以可以方面的实现权限验证,如权限数据表为T_PRIVILEGE,验证用户U是否具有对T_USER进行SELECT的权限的SQL为:
select * from T_PRIVILEGE where USER_ID=’U’ and RESOURCE_NAME like ‘T_USER’ and OPERATION_NAME like ‘SELECT’;
如果有记录返回,表示有权访问,根据不同数据库提供商可以加上限制返回1条记录的判断提高权限验证效率。
匹配规则也可以使用正则表达式,但是正则表达式通常验证比较慢,不适合做实时权限验证,但是正则表达式可以实现更加复杂的匹配规则,所以如果对实时性要求不高,可以预先缓存规则,提高验证效率。
禁止的权限规则集
如果权限规则不是一个集合,因为只有与用户或角色关联的权限规则才允许访问,所以用户的权限是一个闭合区域,不想用户拥有某些权限时,只要不进行关联授权即可。如果权限规则使用通配符变成一个集合,那么用户的权限将变成一个开放区域,比如上面的论坛文章列表,假设论坛文章按照“版面/作者/文章标题”作为资源命名,那么将(阅览, 版面/作者/*)授权给某用户时,该用户允许阅览该版面下该作者的所有文章,假设现在有一种管理需求要求某用户可以阅览某版面下某作者除某几种文章标题外的所有文章,这样单纯的允许授权难以实现这个管理需求。
法律有许可和禁止的区别,那么权限管理也应该有许可和禁止两种授权,上面的不允许访问某几种文章标题的文章就是一种禁止规则,如果将这种禁止规则合并到允许规则中,就可以解决上面的问题。这就相当于画了一个大圈表示可以访问的区域,但是大圈里面的某些小圈是不可以访问的区域。这又带来一个问题,假设允许的和禁止的规则重叠,以谁为准?这个没有一个准则,不过基于安全性考虑,应该采用禁止优先,只要是禁止的集合,就算有允许的集合重叠,也不允许访问。
提高权限验证效率
使用关系数据库存储权限数据时,权限数据表更新和查询的操作频繁度通常小于1:9,也就是这是一个典型的OLAP系统,以查询为主,所以可以采用OLAP的优化策略进行优化,但是大多数优化策略都不具备实时性,如果兼顾实时性和效率要求,可以单独创建一个内存数据库,这个内存数据库只存放用户、资源、操作关联关系,也就是(用户, 操作, 资源)集合,如果用户通过角色关联到权限规则,那么将这些用户到权限规则的间接传递关系转变成直接传递关系保存。这个内存数据库就相当于权限数据的缓存,可以保证很高的查询效率,并且该内存数据库与权限管理保持同步,可以保证实时性。
安装和配置
附件是权限管理和权限验证的实现,也有用户管理的演示,不过用户管理很粗糙,实际使用需要做进一步开发,之所以没有开发相对完善的用户管理,是因为现在已有的系统通常都有完善的用户管理。
下面简单讲解安装配置,只在Tomcat5523+MySQL5037+jre1.5.0_12下测试过。
1. 下载rbac+profile.rar,解压,得到一系列文件,文件用途如下:
profile.admin.src.v1.jar 用户管理源代码
rbac.admin.src.v2.jar 权限管理源代码
rbac.auth.src.v2.jar 权限验证源代码
profile.v1.MySQL5.sql 用户管理用户数据表
profile.war 用户管理WEB系统
rbac.v2.MySQL5.sql 权限管理数据表
rbac.war 权限管理WEB系统
2. 创建数据库profile,使用UTF-8导入profile.v1.MySQL5.sql到profile,使用下面SQL创建用户root/1:
Insert into T_PROFILE(USER_ID, USER_NAME, USER_PASSWORD) values(‘1’, ‘root’, sha1(‘1’));
如果创建过先前SSO单点登陆的用户数据表,可以跳过这步,使用先前的数据表。
3. 创建数据库rbac,使用UTF-8导入rbac.v2.MySQL5.sql到rbac。
4. 拷贝profile.war和rbac.war到Tomcat5523/webapps/,会自动生成profile和rbac目录。
5. 参考http://blog.chinaunix.net/u1/52224/showart_412714.html配置单点登陆,因为权限管理和用户管理需要依赖单点登陆。
6. 下载相关依赖Java库:
下载cglib最新版本http://cglib.sourceforge.net/,拷贝asm.jar和cglib-2.1.3.jar到Tomcat/shared/lib。
下载c3p0最新版本http://sourceforge.net/projects/c3p0,拷贝c3p0-0.9.1.1.jar到Tomcat/shared/lib。
下载mysql-connector最新版本http://sourceforge.net/projects/mmmysql/,拷贝mysql-connector-java-5.0.4-bin.jar到Tomcat/shared/lib。
下载dwr最新版本http://getahead.org/dwr,拷贝dwr2.0.1.jar到Tomcat/shared/lib。
7. 打开profile/ WEB-INF/classes/的rbac_auth.properties、sso_agent.properties、profile_admin.properties。
# 修改为合适配置
# rbac_auth.properties
rbac.auth.db.ds.c3p0.url=jdbc:mysql://localhost/rbac
rbac.auth.db.ds.c3p0.user=root
rbac.auth.db.ds.c3p0.password=1
# sso_agent.properties
sso.passport.login=http://bsmith-cn:8080/sso/passport/login.srv
sso.passport.logout=http://bsmith-cn:8080/sso/passport/logout.srv
# profile_admin.properties
profile.admin.db.ds.c3p0.url=jdbc:mysql://localhost/profile
profile.admin.db.ds.c3p0.user=root
profile.admin.db.ds.c3p0.password=1
8. 打开rbac/WEB-INF/classes/下的rbac_admin.properties、rbac_auth.properties、sso_agent.properties。
# 修改为合适配置
# rbac_auth.properties
rbac.auth.db.ds.c3p0.url=jdbc:mysql://localhost/rbac
rbac.auth.db.ds.c3p0.user=root
rbac.auth.db.ds.c3p0.password=1
# sso_agent.properties
sso.passport.login=http://bsmith-cn:8080/sso/passport/login.srv
sso.passport.logout=http://bsmith-cn:8080/sso/passport/logout.srv
# rbac_admin.properties
rbac.admin.profile.explorer=http://bsmith-cn:8080/profile/admin/explorer.jsp?
rbac.admin.profile.profile=http://bsmith-cn:8080/profile/admin/profile.jsp?
rbac.admin.db.rbac.ds.c3p0.url=jdbc:mysql://localhost/rbac
rbac.admin.db.rbac.ds.c3p0.user=root
rbac.admin.db.rbac.ds.c3p0.password=1
9. 重启Tomcat使设置生效。
使用简介
浏览http://yourhost:yourport/rbac/admin/userList.jsp进入用户列表,可以管理用户。
浏览http://yourhost:yourport/rbac/admin/roleList.jsp进入角色列表,可以管理角色。
浏览http://yourhost:yourport/rbac/admin/operationList.jsp进入操作列表,可以管理操作。
浏览http://yourhost:yourport/rbac/admin/resourceList.jsp进入资源列表,可以管理资源。
默认用户ID为1的用户可以进行所有操作(%, %)。
验证权限
rbac.auth.src.v2.jar中包含了权限验证的源代码,rbac_auth.properties是配置文件,可以配置权限管理数据库的路径。
org.bsmith.rbac.auth. Authorization 实现权限验证,详细参考org.bsmith.rbac.auth. Authorization.java。
文件: rbac+profile.rar
大小: 876KB
下载: 下载
http://blogold.chinaunix.net/u1/52224/showart_415123.html
前不久在http://blog.chinaunix.net/u1/52224/showart_410119.html讲述了业务系统的权限管理模型,并在http://blog.chinaunix.net/u1/52224/showart_412714.html实现了模型中的SSO单点登陆,这次讲述的是权限管理、权限验证的实现,并附带一个用户管理的Demo,用户管理的Demo很粗糙,基本上只是一个演示。
RBAC是基于角色的权限管理,RBAC参考(http://csrc.nist.gov/rbac/ ),有用户、角色、资源和权限四种主体,他们简化的关系如下:
资源和操作成对组成一种权限规则,角色关联到多个规则表示该角色拥有这些权限规则指定的权限,用户关联到多个角色表示用户拥有这些角色的权限。
上面的模型是Core RBAC,也就是RBAC的最基础的模型,更高级的模型提供了更多的管理功能,像角色继承和约束等,这里没有实现角色的继承和约束,著名的开源权限管理系统ACEGI(http://www.acegisecurity.org/ )已经做了实现,下面讲一下基于Core RABC三个扩充。
用户关联权限规则
在Core RBAC里面,用户通常不直接与权限规则关联,所有授权过程都是角色关联权限规则,然后用户关联到角色来实现,比如删除数据库这样一个过程,删除是操作,数据库是资源,(删除, 数据库)组成权限规则,如果要对用户bsmith授权允许删除数据库,那么可以将用户bsmith关联到已经拥有该权限的角色,如果没有合适的角色,那么必须新建一个角色比如叫admin,然后将(删除, 数据库)这个权限规则关联到admin,然后将bsmith关联到admin,而不能直接将(删除, 数据库)关联到bsmith。
将用户关联扩充到直接关联权限规则后,可以方便个别用户的特殊授权。也可以避免大量的特殊授权带来的角色零散性,也就是当上面的情况较多时,如果不能对用户直接关联权限规则,那么每次建立的角色数可能超过系统角色数,容易混淆。
权限规则集合
(操作, 资源)组成的权限规则理论上包含所有的系统权限规则,比如对数据库表T,有一个查询操作SELECT,那么权限规则就是(SELECT, T),如果还有一个数据库表T1,有一个查询操作SELECT,那么权限规则就是(SELECT, T1),资源和操作都是有限的,所以权限规则集合也是有限并且可以列举的,也就是可以一个一个的把这些权限规则记录下来,分配权限时只要找到这些权限规则,然后关联到相应的角色和用户就可以了。
不过实际情况往往比预想的复杂,第一种情况是虽然权限规则有限并且可以列举,但是数据可能很大,需要很大的存储空间,并且过多的记录会影响权限验证的查询速度。
第二个问题是对于像论坛文章这样的内容动态变化的系统,如果要对某个用户授予所有的权限,那么当论坛文章时,需要管理员手动关联这些增加的权限规则到该用户。当然,也可以采用在论坛文章业务逻辑处自动关联权限规则给用户,但是这样一方面没有达到权限系统和业务逻辑分开的目的,无法实现权限系统的重用,另一方面也需要设置一个标志来给哪些用户授权,难以统一化。
要解决这两个问题,一方面要使权限规则集合尽量小,另一方面要使这个集合能自动适应资源的动态变化。通配符是一个很好的解决方式,通过对资源和操作增加通配符,让资源和操作本身变成资源集合和操作集合,如对于数据库表T_USER, T_GROUP,可以用T_*来表示,*表示匹配所有字符串,那么(SELECT, T_*)就表示对所有以T_开头的数据库表的SELECT操作,这样以前的权限规则就变成了权限规则集合,如果(SELECT, T_*)被授权给用户,以后数据库表增加时,只要数据库表名称以T_开头,该用户都有权进行SELECT操作。这样权限管理就变成授权用户允许对某些资源进行某些操作,权限规则不再表示单个操作和单个资源的关联,而是一组操作和一组资源进行笛卡尔积的集合,即(操作, 资源) = 操作集×资源集。
关系数据库使用%表示匹配所有字符串,_表示匹配单个字符,使用like关键字进行匹配判断,所以可以方面的实现权限验证,如权限数据表为T_PRIVILEGE,验证用户U是否具有对T_USER进行SELECT的权限的SQL为:
select * from T_PRIVILEGE where USER_ID=’U’ and RESOURCE_NAME like ‘T_USER’ and OPERATION_NAME like ‘SELECT’;
如果有记录返回,表示有权访问,根据不同数据库提供商可以加上限制返回1条记录的判断提高权限验证效率。
匹配规则也可以使用正则表达式,但是正则表达式通常验证比较慢,不适合做实时权限验证,但是正则表达式可以实现更加复杂的匹配规则,所以如果对实时性要求不高,可以预先缓存规则,提高验证效率。
禁止的权限规则集
如果权限规则不是一个集合,因为只有与用户或角色关联的权限规则才允许访问,所以用户的权限是一个闭合区域,不想用户拥有某些权限时,只要不进行关联授权即可。如果权限规则使用通配符变成一个集合,那么用户的权限将变成一个开放区域,比如上面的论坛文章列表,假设论坛文章按照“版面/作者/文章标题”作为资源命名,那么将(阅览, 版面/作者/*)授权给某用户时,该用户允许阅览该版面下该作者的所有文章,假设现在有一种管理需求要求某用户可以阅览某版面下某作者除某几种文章标题外的所有文章,这样单纯的允许授权难以实现这个管理需求。
法律有许可和禁止的区别,那么权限管理也应该有许可和禁止两种授权,上面的不允许访问某几种文章标题的文章就是一种禁止规则,如果将这种禁止规则合并到允许规则中,就可以解决上面的问题。这就相当于画了一个大圈表示可以访问的区域,但是大圈里面的某些小圈是不可以访问的区域。这又带来一个问题,假设允许的和禁止的规则重叠,以谁为准?这个没有一个准则,不过基于安全性考虑,应该采用禁止优先,只要是禁止的集合,就算有允许的集合重叠,也不允许访问。
提高权限验证效率
使用关系数据库存储权限数据时,权限数据表更新和查询的操作频繁度通常小于1:9,也就是这是一个典型的OLAP系统,以查询为主,所以可以采用OLAP的优化策略进行优化,但是大多数优化策略都不具备实时性,如果兼顾实时性和效率要求,可以单独创建一个内存数据库,这个内存数据库只存放用户、资源、操作关联关系,也就是(用户, 操作, 资源)集合,如果用户通过角色关联到权限规则,那么将这些用户到权限规则的间接传递关系转变成直接传递关系保存。这个内存数据库就相当于权限数据的缓存,可以保证很高的查询效率,并且该内存数据库与权限管理保持同步,可以保证实时性。
安装和配置
附件是权限管理和权限验证的实现,也有用户管理的演示,不过用户管理很粗糙,实际使用需要做进一步开发,之所以没有开发相对完善的用户管理,是因为现在已有的系统通常都有完善的用户管理。
下面简单讲解安装配置,只在Tomcat5523+MySQL5037+jre1.5.0_12下测试过。
1. 下载rbac+profile.rar,解压,得到一系列文件,文件用途如下:
profile.admin.src.v1.jar 用户管理源代码
rbac.admin.src.v2.jar 权限管理源代码
rbac.auth.src.v2.jar 权限验证源代码
profile.v1.MySQL5.sql 用户管理用户数据表
profile.war 用户管理WEB系统
rbac.v2.MySQL5.sql 权限管理数据表
rbac.war 权限管理WEB系统
2. 创建数据库profile,使用UTF-8导入profile.v1.MySQL5.sql到profile,使用下面SQL创建用户root/1:
Insert into T_PROFILE(USER_ID, USER_NAME, USER_PASSWORD) values(‘1’, ‘root’, sha1(‘1’));
如果创建过先前SSO单点登陆的用户数据表,可以跳过这步,使用先前的数据表。
3. 创建数据库rbac,使用UTF-8导入rbac.v2.MySQL5.sql到rbac。
4. 拷贝profile.war和rbac.war到Tomcat5523/webapps/,会自动生成profile和rbac目录。
5. 参考http://blog.chinaunix.net/u1/52224/showart_412714.html配置单点登陆,因为权限管理和用户管理需要依赖单点登陆。
6. 下载相关依赖Java库:
下载cglib最新版本http://cglib.sourceforge.net/,拷贝asm.jar和cglib-2.1.3.jar到Tomcat/shared/lib。
下载c3p0最新版本http://sourceforge.net/projects/c3p0,拷贝c3p0-0.9.1.1.jar到Tomcat/shared/lib。
下载mysql-connector最新版本http://sourceforge.net/projects/mmmysql/,拷贝mysql-connector-java-5.0.4-bin.jar到Tomcat/shared/lib。
下载dwr最新版本http://getahead.org/dwr,拷贝dwr2.0.1.jar到Tomcat/shared/lib。
7. 打开profile/ WEB-INF/classes/的rbac_auth.properties、sso_agent.properties、profile_admin.properties。
# 修改为合适配置
# rbac_auth.properties
rbac.auth.db.ds.c3p0.url=jdbc:mysql://localhost/rbac
rbac.auth.db.ds.c3p0.user=root
rbac.auth.db.ds.c3p0.password=1
# sso_agent.properties
sso.passport.login=http://bsmith-cn:8080/sso/passport/login.srv
sso.passport.logout=http://bsmith-cn:8080/sso/passport/logout.srv
# profile_admin.properties
profile.admin.db.ds.c3p0.url=jdbc:mysql://localhost/profile
profile.admin.db.ds.c3p0.user=root
profile.admin.db.ds.c3p0.password=1
8. 打开rbac/WEB-INF/classes/下的rbac_admin.properties、rbac_auth.properties、sso_agent.properties。
# 修改为合适配置
# rbac_auth.properties
rbac.auth.db.ds.c3p0.url=jdbc:mysql://localhost/rbac
rbac.auth.db.ds.c3p0.user=root
rbac.auth.db.ds.c3p0.password=1
# sso_agent.properties
sso.passport.login=http://bsmith-cn:8080/sso/passport/login.srv
sso.passport.logout=http://bsmith-cn:8080/sso/passport/logout.srv
# rbac_admin.properties
rbac.admin.profile.explorer=http://bsmith-cn:8080/profile/admin/explorer.jsp?
rbac.admin.profile.profile=http://bsmith-cn:8080/profile/admin/profile.jsp?
rbac.admin.db.rbac.ds.c3p0.url=jdbc:mysql://localhost/rbac
rbac.admin.db.rbac.ds.c3p0.user=root
rbac.admin.db.rbac.ds.c3p0.password=1
9. 重启Tomcat使设置生效。
使用简介
浏览http://yourhost:yourport/rbac/admin/userList.jsp进入用户列表,可以管理用户。
浏览http://yourhost:yourport/rbac/admin/roleList.jsp进入角色列表,可以管理角色。
浏览http://yourhost:yourport/rbac/admin/operationList.jsp进入操作列表,可以管理操作。
浏览http://yourhost:yourport/rbac/admin/resourceList.jsp进入资源列表,可以管理资源。
默认用户ID为1的用户可以进行所有操作(%, %)。
验证权限
rbac.auth.src.v2.jar中包含了权限验证的源代码,rbac_auth.properties是配置文件,可以配置权限管理数据库的路径。
org.bsmith.rbac.auth. Authorization 实现权限验证,详细参考org.bsmith.rbac.auth. Authorization.java。
文件: rbac+profile.rar
大小: 876KB
下载: 下载
http://blogold.chinaunix.net/u1/52224/showart_415123.html