SpringSecurity ACL持久化: Hibernate implementation of Spring Security ACL
来源:互联网 发布:高中数学软件手机 编辑:程序博客网 时间:2024/05/26 05:52
本文重点描述如何基于hibernate在micrite中实现SS(Spring Security) ACL,相关软件版本为 spring-security-2.0.5.RELEASE和micrite-0.11。实现的过程中,借鉴了下面三个例子:
- contacts 联系人管理(重点参考)
SS 的官方例子,控制不同用户对联系人的查看、修改、删除、管理权限。 - dms 文档管理系统
SS 的官方例子,和contract相比,功能相对简单,主要是体现了ACL继承的概念,例如文档的ACL权限可继承自所在目录的权限。 - springstart 职员、客户的帐户管理(重点参考)
denksoft 提供的基于postgresql的例子,有详细的说明文档。
它们都采用SS默认的JDBC对ACL数据做持久化,而micrite持久层采用hibernate,如要实现ACL,需要重新实现SS默认的ACL数据持久化接口,否则一个系统里就会有两种持久化方式(就像springstart一样),这有点难以接受。
SS的开发组曾对这个问题做过讨论,似乎短期内都没有修改的计划,所以,只能自己动手了。
建表
实现ACL需要建下面4张表:acl_sid
acl_class
acl_object_identity
acl_entry
表结构的说明请参考 Schema Documentation 和 ER Diagram(基于derby)。
micrite使用velocity模板生成多种数据库脚本,保存在安装包的如下目录。path: ./dbscripts
创建实体类
除了为上面的4张表建立相应的实体类之外,再建一个抽象类AbstractSecureObject,目的是如果有多个受ACL保护的对象,不用在applicationContext-security.xml
文件里一一配置,只需配置一个AbstractSecureObject,让其他受保护的实体类继承它。
AbstractSecureObject 只需要一个ID属性,让ACL可以获得受保护对象实例的ID值。
package org.gaixie.micrite.beans
增加DAO
为每个ACL实体类增加相应的DAO接口,及实现类。
package org.gaixie.micrite.security.dao
IAclSidDAO.java
IAclClassDAO.java
IAclObjectIdentityDAO.java
IAclEntryDAO.java
package org.gaixie.micrite.security.dao.hibernate
AclSidDAOImpl.java
AclClassDAOImpl.java
AclObjectIdentityDAOImpl.java
AclEntryDAOImpl.java
方法的说明请参见 micrite API文档。
实现ACL数据持久化接口
我们需要实现两个ACL负责数据持久化的接口:
- AclService 负责ACL实例的读取。
- MutableAclService 负责创建和存储ACL实例。
首先,先创建一个我们自己的接口 ISecurityAclService,目的是当新增一个受保护的对象实例时,统一调用此接口实现权限信息的持久化,同时让它继承SS的MutableAclService接口,所有下面会提到。
接下来,创建两个Acl的数据持久化接口的实现类:
package org.gaixie.micrite.security.service.impl
AclServiceImpl.java
MutableAclServiceImpl.java
- AclServiceImpl
重点是重新实现AclService接口的一个方法public Map readAclsById(ObjectIdentity[] objects, Sid[] sids);
SS中此方法默认实现,是通过调用一个名为BasicLookupStrategy的类来完成ACL实例信息的读取,这里我们直接通过调用相关的DAO,来实现此功能。省去BasicLookupStrategy类的原因是SS基于JDBC获取数据,除了需要一些ANSI SQL之外,还要将得到的ResultSet结果集转换为相应的ACL实例,而我们采用Hibernate,直接通过DAO取出来就是对象实例,代码要比默认的实现简单很多。(总算体现出Hibernate的好处了!!!) - MutableAclServiceImpl
此类所有方法都需要基于hibernate重写,由于它实现的是自定义的ISecurityAclService接口,所以要比SS默认的JDBC多实现两个方法:public void addPermission(AbstractSecureObject securedObject
, Permission permission, Class clazz);
public void addPermission(AbstractSecureObject securedObject
, Sid recipient, Permission permission, Class clazz);
如果你了解上面ACL4个实体类的含义,并且熟悉Hibernate,会很容易理解这两个实现类,可以对照SS默认的JDBC实现。
当前micrite还没有实现AclCache接口,它可以大幅提升获取Acl实例的性能。
修改相关的xml配置文件
最后修改两个配置文件。
- applicationContext-security.xml
此配置文件相比没有ACL之前,主要是增加了afterInvocationManager的相关内容,用来处理在被拦截方法执行后,对返回的结果集进行ACL过滤。 - applicationContext-security-bean.xml
此配置文件唯一需要注意的是 securityMutableAclService ,它实际对应着SS配置文件中的aclService,他们都是ACL数据持久化接口MutableAclService的实现类,由于我们采用Spring自动装载的方式,所以不需要构造参数。它在applicationContext-security.xml
文件中被频繁引用。
增加一个角色AFTER_ACL_COLLECTION_READ
,以后所有需要进行ACL结果集过滤的方法都绑定到此角色。
到目前为止,我们已经完成了所有的ACL修改。
测试ACL
下面的步骤将实现:不同的用户只能看到自己拥有在的角色。管理员组(ROLE_ADMIN)可以看到所有的角色。
- 选择一个要进行ACL保护的实体类Role,让Role继承AbstractSecureObject
- 添加要拦截的方法并绑定到角色
AFTER_ACL_COLLECTION_READ
,通过界面或者SQL命令都可以。注意拦截的方法至少有一个是返回Role对象结果集,如List(Role)
或Set(Role)
等。可参见: - 修改RoleServiceImpl类中的
add(..), delete(..)
方法,在增加或删除Role之后,也增加或删除相应的ACL对象。通过调用ISecurityAclServicede的方法可以很简单的实现。 - 编译、运行修改后的代码,用admin登录系统,增加几个Role和User,然后用不同的User登录,看看结果是否正确。
参考文档
[1] http://code.google.com/p/micrite/wiki/Permissions
[2] http://en.wikipedia.org/wiki/Access_Control_List
- SpringSecurity ACL持久化: Hibernate implementation of Spring Security ACL
- spring security之ACL
- Spring Security中的ACL
- acegi/springsecurity acl 简介
- Spring Security手册更新cas, basic, acl
- ACL
- ACL
- ACL
- ACL
- ACL
- ACL
- ACL
- ACL
- ACL
- ACL
- ACL
- acl
- ACL
- 初窥中间件
- flash位图技术研究篇(7):像素粒子(2)
- 第一个项目进行时 -- 分享遇到的问题
- java学习之JNI 学习三 取得JAVA属性/设定JAVA属性值
- MFC类图
- SpringSecurity ACL持久化: Hibernate implementation of Spring Security ACL
- Linux 使用技巧33条
- easerver6.3的debug
- Win7下安装VS2008和SQL Server 2008
- 网络编程基础
- struts2中 # % $ 的区别和用法
- microsoft 安全风险管理指南
- C#几种进制之间的互转方法
- Netty