數(shù)據(jù)權(quán)限分為兩種,一種是數(shù)據(jù)范圍權(quán)限,一種是具體到每一條數(shù)據(jù)的權(quán)限。前一種可以通過動(dòng)態(tài)構(gòu)建SQL解決;后一種
似乎必須通過ACL不可。于是就想對Acegi ACL做一個(gè)通用的擴(kuò)展。以通訊錄為例
先看一個(gè)總的配置
? <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>
擴(kuò)展一、當(dāng)你增加一條記錄的同時(shí)向ACL表里插入權(quán)限信息 這個(gè)SS已經(jīng)做到了這一點(diǎn)
??ss有一個(gè)接口標(biāo)示哪些doamin需要acl保護(hù) AclDomainAware
??這里再擴(kuò)展一個(gè)基類 ,目的很簡單當(dāng)讀出數(shù)據(jù)時(shí)附加上權(quán)限信息
??public? class BasicAclDomain implements AclDomainAware {
??? private int mask; //權(quán)限
??? public int getMask() {
??????? return mask;
??? }
??? public void setMask(int mask) {
??????? this.mask = mask;
??? }
??}
??
??public class Contact extends BasicAclDomain
擴(kuò)展二、讀取列表時(shí)進(jìn)行數(shù)據(jù)的過濾,原來的acegi在ACL的集合后處理會(huì)造成分頁產(chǎn)生虎牙子
???? 這里采用前攔截,在acl表里增加一個(gè)className字段,里面放上PO的類名,這樣可以縮小
???? 數(shù)據(jù)查詢范圍.實(shí)際在讀取集合時(shí),是先到acl表里完成分頁,然后獲得對Contact的real id list
???? 然后攔截實(shí)際DAO方法,動(dòng)態(tài)改變SQL成select * from real_data where id in ( {real id list} )的形式,這樣就OK了,
???? 分頁實(shí)際是對acl表里相應(yīng)記錄的'分頁'.比如說取第10條到20條,實(shí)際是取acl表里相應(yīng)記錄的第10條到20條來動(dòng)態(tài)改變SQL
???? 這個(gè)可以寫一個(gè)專門被用來攔截的類 SecurityDAO 方法findByPageACL(query, page),ContactServiceImpl中g(shù)etAllContacts
???? 方法強(qiáng)制調(diào)用該方法
擴(kuò)展三、后攔截。這里AFTER_ACL_COLLECTION_READ和AFTER_ACL_READ的目的就很簡單了,因?yàn)樗麄儾辉龠M(jìn)行數(shù)據(jù)過 濾,?他們只是把用戶對每條記錄的mask取最大權(quán)限就OK,然后往PO里setMask。這樣PO帶了權(quán)限信息到頁面上就非常好處理了。比如button的顯示等等
擴(kuò)展四、封裝AclService,對單條記錄的ACL權(quán)限管理。比如增加權(quán)限、修改權(quán)限、刪除權(quán)限。這個(gè)acegi的最新1.0.3已經(jīng)開始加入。
具體在實(shí)現(xiàn)中感覺acl的vote完全是雞肋,全部不用。另外在擴(kuò)展二中如果用戶數(shù)據(jù)要實(shí)現(xiàn)數(shù)據(jù)庫排序就比較困難。所以就有了還未實(shí)現(xiàn)的構(gòu)想:
一、PO創(chuàng)建向ACL表里插入權(quán)限信息時(shí)可以配置不同的策略:比如通訊錄創(chuàng)建一條新信息只能創(chuàng)建者可以看并管理,而你往請假表里插一條新信息后,不僅你了,你的上司也可以同時(shí)看到。(這個(gè)還是比較easy)
二、用戶數(shù)據(jù)要實(shí)現(xiàn)數(shù)據(jù)庫排序。需要在ACL_OBJECT_IDENTITY里增加幾個(gè)額外的字段,把po相應(yīng)的排序字段同步更新到ACL表中。什么?不好做?寫配置文件啊!再對PO的update進(jìn)行后攔截。
想法就這樣。實(shí)現(xiàn)??
http://www.tkk7.com/ronghao 榮浩原創(chuàng),轉(zhuǎn)載請注明出處:)
posted on 2006-12-14 10:20
ronghao 閱讀(4278)
評論(6) 編輯 收藏 所屬分類:
權(quán)限相關(guān)