SpringSecurity ACL持久化: Hibernate implementation of Spring Security ACL
2010-04-07 23:55
721 查看
本文重点描述如何基于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的开发组曾对这个问题做过讨论,似乎短期内都没有修改的计划,所以,只能自己动手了。
表结构的说明请参考 Schema
Documentation
和 ER
Diagram
(基于derby)。
micrite使用velocity
模板
生成多种数据库脚本,保存在安装包的如下目录。
,
目的是如果有多个受ACL保护的对象,不用在
文件里一一配
置,只需配置一个AbstractSecureObject,让其他受保护的实体类继承它。
AbstractSecureObject 只需要一个ID属性,让ACL可以获得受保护对象实例的ID值。
方法的说明请参见 micrite
API文档
。
AclService
负责ACL实例的读取。
MutableAclService
负责创建和存储ACL实例。
首先,先创建一个我们自己的接口 ISecurityAclService
,
目的是当新增一个受保护的对象实例时,统一调用此接口实现权限信息的持久化,同时让它继承SS的MutableAclService接口,所有下面会提
到。
接下来,创建两个Acl的数据持久化接口的实现类:
AclServiceImpl
重点是重新实现AclService接口的一个方法
SS中此方法默认实现,是通过调用一个名为BasicLookupStrategy
的
类来完成ACL实例信息的读取,这里我们直接通过调用相关的DAO,来实现此功能。省去BasicLookupStrategy类的原因是SS基于
JDBC获取数据,除了需要一些ANSI
SQL之外,还要将得到的ResultSet结果集转换为相应的ACL实例,而我们采用Hibernate,直接通过DAO取出来就是对象实例,代码要比
默认的实现简单很多。(总算体现出Hibernate的好处了!!!)
MutableAclServiceImpl
此类所有方法都需要基于hibernate重写,由于它实现的是自定义的ISecurityAclService接口,所以要比SS默认的JDBC多实现
两个方法:
如果你了解上面ACL4个实体类的含义,并且熟悉Hibernate,会很容易理解这两个实现类,可以对照SS默认的JDBC实现。
当前micrite还没有实现AclCache接口,它可以大幅提升获取Acl实例的性能。
applicationContext-security.xml
此配置文件相比没有ACL之前,主要是增加了afterInvocationManager的相关内容,用来处理在被拦截方法执行后,对返回的结果集进行
ACL过滤。
applicationContext-security-bean.xml
此配置文件唯一需要注意的是 securityMutableAclService
,它实际对应着SS配置文件中的aclService,他们都是ACL数据持久化接口MutableAclService的实现类,由于我们采用
Spring自动装载的方式,所以不需要构造参数。它在
文件
中被频繁引用。
增加一个角色
,以后所有需要进行ACL结果集过滤的方法都绑定到此
角色。
到目前为止,我们已经完成了所有的ACL修改。
选择一个要进行ACL保护的实体类Role
,
让Role继承AbstractSecureObject
添加要拦截的方法并绑定到角色
,通过界面或者SQL命令都可以。
注意拦截的方法至少有一个是返回Role对象结果集,如
或
等。
可参见:
修改RoleServiceImpl
类
中的
方法,在增加或删除Role之后,也增加或删除相应的ACL对象。通过调用
ISecurityAclServicede的方法可以很简单的实现。
编译、运行修改后的代码,用admin登录系统,增加几个Role和User,然后用不同的User登录,看看结果是否正确。
[2] http://en.wikipedia.org/wiki/Access_Control_List
中
实现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
相关文章推荐
- 深入学习SSH框架(Spring MVC +Spring FrameWork +Hibernate +Spring Security)《一:Servlet原理》
- Spring Security ACL使用Oracle数据库的配置与数据库脚本
- 深入学习SSH框架(Spring MVC +Spring FrameWork +Hibernate +Spring Security)《四:Spring Framework配置篇》
- 基于Spring MVC+Hibernate+Spring Security+Mysql 的B/S应用系统平台设计与实现
- Spring Security ACL使用Oracle数据库的配置与数据库脚本
- spring+hibernate整合时tomcat启动的一个错误(严重: Exception sending context initialized event to listener instance of class org.springframewo
- Spring JDBCTemplate VS Hibernate in terms of performance
- acegi/springsecurity acl 简介
- Spring Security + Hibernate XML Example
- 在使用hibernate 和spring 构架的框架中如果出现Initialization of bean failed; nested exception is java.lang.NoSuchMethodError: org.objectweb.asm
- Improving the Security and User Experience of your Google Sign In Implementation
- 使用spring-security3.1 + spring mvc + Hibernate 控制系统权限
- springmvc+hibernate+security整合笔记
- Performance Tuning of Spring/Hibernate Applications---reference
- Spring,hibernate,struts2(SSH)项目在tomcat中多次reload时出现OutOfMemoryError:PermGen Space
- How to use JDBC-Authentication of Spring Boot/Spring Security with Flyway
- 【spring-security】 Property or field 'ROLE_USER' cannot be found on object of type 'org.springframewo
- [Spring实战系列] - No.12 Java配置 SpringMVC + Spring Security + Hibernate 多用户登录
- REST标准,支持多终端。resteasy + spring + spring security + spring aop + hibernate + c# + jquery mobile
- spring-security3.1 + spring mvc + Hibernate 控制系统权限