posts - 193,  comments - 520,  trackbacks - 0

数据权限分为两种,一种是数据范围权限,一种是具体到每一条数据的权限。前一种可以通过动态构建SQL解决;后一种
似乎必须通过ACL不可。于是就想对Acegi ACL做一个通用的扩展。以通讯录为例
先看一个总的配置
  <bean id="contactManagerSecurityInterceptor" class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
      <property name="authenticationManager"><ref bean="authenticationManager"/></property>
      <property name="accessDecisionManager"><ref local="aclDecisionManager"/></property>
      <property name="afterInvocationManager"><ref local="afterInvocationManager"/></property>
      <property name="objectDefinitionSource">
         <value>
            com.ronghao.acltest.services.ContactService.saveContact=AFTER_ACL_CREAT
            com.ronghao.acltest.services.ContactService.getAllContacts=AFTER_ACL_COLLECTION_READ
            com.ronghao.acltest.services.ContactService.getContact=AFTER_ACL_READ
         </value>
      </property>
   </bean>
扩展一、当你增加一条记录的同时向ACL表里插入权限信息 这个SS已经做到了这一点
  ss有一个接口标示哪些doamin需要acl保护 AclDomainAware
  这里再扩展一个基类 ,目的很简单当读出数据时附加上权限信息
  public  class BasicAclDomain implements AclDomainAware {

    private int mask; //权限

    public int getMask() {
        return mask;
    }

    public void setMask(int mask) {
        this.mask = mask;
    }
  }
  
  public class Contact extends BasicAclDomain
扩展二、读取列表时进行数据的过滤,原来的acegi在ACL的集合后处理会造成分页产生虎牙子
     这里采用前拦截,在acl表里增加一个className字段,里面放上PO的类名,这样可以缩小
     数据查询范围.实际在读取集合时,是先到acl表里完成分页,然后获得对Contact的real id list
     然后拦截实际DAO方法,动态改变SQL成select * from real_data where id in ( {real id list} )的形式,这样就OK了,
     分页实际是对acl表里相应记录的'分页'.比如说取第10条到20条,实际是取acl表里相应记录的第10条到20条来动态改变SQL
     这个可以写一个专门被用来拦截的类 SecurityDAO 方法findByPageACL(query, page),ContactServiceImpl中getAllContacts
     方法强制调用该方法
扩展三、后拦截。这里AFTER_ACL_COLLECTION_READ和AFTER_ACL_READ的目的就很简单了,因为他们不再进行数据过 滤, 他们只是把用户对每条记录的mask取最大权限就OK,然后往PO里setMask。这样PO带了权限信息到页面上就非常好处理了。比如button的显示等等
扩展四、封装AclService,对单条记录的ACL权限管理。比如增加权限、修改权限、删除权限。这个acegi的最新1.0.3已经开始加入。
具体在实现中感觉acl的vote完全是鸡肋,全部不用。另外在扩展二中如果用户数据要实现数据库排序就比较困难。所以就有了还未实现的构想:
一、PO创建向ACL表里插入权限信息时可以配置不同的策略:比如通讯录创建一条新信息只能创建者可以看并管理,而你往请假表里插一条新信息后,不仅你了,你的上司也可以同时看到。(这个还是比较easy)
二、用户数据要实现数据库排序。需要在ACL_OBJECT_IDENTITY里增加几个额外的字段,把po相应的排序字段同步更新到ACL表中。什么?不好做?写配置文件啊!再对PO的update进行后拦截。
想法就这样。实现??



http://www.blogjava.net/ronghao 荣浩原创,转载请注明出处:)
posted on 2006-12-14 10:20 ronghao 阅读(4264) 评论(6)  编辑  收藏 所属分类: 权限相关

FeedBack:
# re: 对Acegi ACL扩展的构想
2006-12-15 10:29 | 差沙
写的不错,有几个疑问
为什么ACL的Voter是鸡肋呢,ACL完全是再一个Voter上发展起来的。

你说的构想一,其实自己写一个ACL规则就能实现,总体来说ACL这边还是加上脚本引擎(当然要考虑性能问题)是最灵活的解决方案。

还有你说的SQL层实现ACL拦截,前一阵子好像有人在做。  回复  更多评论
  
# re: 对Acegi ACL扩展的构想
2006-12-16 11:55 | ronghao
纯粹是个人看法,觉得ACL似乎并不需要acegi的前拦截,于是VOTE就作用不太大,另外是把mask给附加到PO的属性里,这样就更加觉得不需要了.
关于构想一,我们可以针对不同的需求配置不同的AFTER_ACL_CREAT
比如:AFTER_CONTACT_ACL_CREATE
AFTER_MESSAGE_ACL_CREATE
SQL层实现ACL拦截我已经有了一个粗糙的实现,就是有限制:即getAll时SQL必须是select * from table 后面不能带条件,原因也很简单:ACL表里没有业务字段.所以这也是我着重考虑的问题:)  回复  更多评论
  
# re: 对Acegi ACL扩展的构想
2008-01-04 15:13 | 企业精英社区
文中提到的ss是指什么呢?  回复  更多评论
  
# re: 对Acegi ACL扩展的构想
2008-01-17 15:17 | ronghao
springside  回复  更多评论
  
# re: 对Acegi ACL扩展的构想
2008-03-20 17:40 | zhx

因为是刚接触,所以我想问下,是不是每个领域对象的实例在acl表里都要体现。如果要保护的领域对象多了的话 那么acl表里的数据量是不是会很大?  回复  更多评论
  
# re: 对Acegi ACL扩展的构想
2008-04-07 18:19 | ronghao
@zhx
是的,所以需要权衡。  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航:
 
<2006年12月>
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

关注工作流和企业业务流程改进。现就职于ThoughtWorks。新浪微博:http://weibo.com/ronghao100

常用链接

留言簿(38)

随笔分类

随笔档案

文章分类

文章档案

常去的网站

搜索

  •  

最新评论

阅读排行榜

评论排行榜