Acegi好早就實(shí)現(xiàn)了ACL(好像是0.5),但是使用起來確實(shí)有點(diǎn)麻煩,所以用的不是太廣泛。這里簡單的說明一下使用方法,希望有更多的朋友來試試。
首先要理解Acegi里面Voter的概念,ACL正是在一個(gè)Voter上擴(kuò)展起來的。現(xiàn)來看一下AclVoter的配置。
????<bean?id="aclBeanReadVoter"?class="org.acegisecurity.vote.BasicAclEntryVoter">
????????<property?name="processConfigAttribute">
????????????<value>ACL_READ</value>
????????</property>
????????<property?name="processDomainObjectClass">
????????????<value>org.springside.modules.security.acl.domain.AclDomainAware</value>
????????</property>
????????<property?name="aclManager">
????????????<ref?local="aclManager"/>
????????</property>
????????<property?name="requirePermission">
????????????<list>
????????????????<ref?local="org.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/>
????????????????<ref?local="org.acegisecurity.acl.basic.SimpleAclEntry.READ"/>
????????????</list>
????????</property>
????</bean>- ACL_READ指的是這個(gè)Voter對哪些SecurityConfig起作用,我們可以把ACL_READ配置在想要攔截的Method上。比方說我們要攔截readOrder這個(gè)方法,以實(shí)現(xiàn)ACL控制,可以這樣配置。
orderManager.readOrder=ACL_READ - processDomainObjectClass指出哪些DomainObject是要進(jìn)行ACL校驗(yàn)的。
- aclManager是一個(gè)比較重要的概念,主要負(fù)責(zé)在權(quán)限列表中根據(jù)用戶和DomainObject取得acl列表。
- requirePermission指出要進(jìn)行這個(gè)操作必須具備的acl權(quán)限,比方說read操作就必須有ADMINISTRATION或READ兩個(gè)權(quán)限。
其實(shí)整個(gè)過程看下來比較清晰,下面來看一下AclManager如何配置。
????<!--?=========?ACCESS?CONTROL?LIST?LOOKUP?MANAGER?DEFINITIONS?=========?-->

????<bean?id="aclManager"?class="org.acegisecurity.acl.AclProviderManager">
????????<property?name="providers">
????????????<list>
????????????????<ref?local="basicAclProvider"/>
????????????</list>
????????</property>
????</bean>

????<bean?id="basicAclProvider"?class="org.acegisecurity.acl.basic.BasicAclProvider">
????????<property?name="basicAclDao">
????????????<ref?local="basicAclExtendedDao"/>
????????</property>
????</bean>

????<bean?id="basicAclExtendedDao"?class="org.acegisecurity.acl.basic.jdbc.JdbcExtendedDaoImpl">
????????<property?name="dataSource">
????????????<ref?bean="dataSource"/>
????????</property>
????</bean>很明顯ACLManager繼承了Acegi的一貫風(fēng)格,Provider可以提供多種取得ACL訪問列表的途徑,默認(rèn)的是用
basicAclProvider在數(shù)據(jù)庫中取得。既然提到了數(shù)據(jù)庫,那我們就來看一下Acegi默認(rèn)提供的ACL在數(shù)據(jù)庫里的保存表結(jié)構(gòu):
CREATE?TABLE?acl_object_identity?(
id?IDENTITY?NOT?NULL,
object_identity?VARCHAR_IGNORECASE(250)?NOT?NULL,
parent_object?INTEGER,
acl_class?VARCHAR_IGNORECASE(250)?NOT?NULL,
CONSTRAINT?unique_object_identity?UNIQUE(object_identity),
FOREIGN?KEY?(parent_object)?REFERENCES?acl_object_identity(id)
);
CREATE?TABLE?acl_permission?(
id?IDENTITY?NOT?NULL,
acl_object_identity?INTEGER?NOT?NULL,
recipient?VARCHAR_IGNORECASE(100)?NOT?NULL,
mask?INTEGER?NOT?NULL,
CONSTRAINT?unique_recipient?UNIQUE(acl_object_identity,?recipient),
FOREIGN?KEY?(acl_object_identity)?REFERENCES?acl_object_identity(id)
);- acl_object_identity表存放了所有受保護(hù)的domainObject的信息。其中object_identity字段保存了domainObject的class和id,默認(rèn)的保存格式是:domainClass:domainObjectId。
- acl_permission?就是ACL權(quán)限列表了,recipient?是用戶或角色信息,mask表示了這個(gè)用戶或角色對這個(gè)domainObject的訪問權(quán)限。注意這些信息的保存格式都是可以根據(jù)自己的需要改變的。
這樣讀取和刪除的時(shí)候Acegi就能很好的完成攔截工作,但是讀取一個(gè)List的時(shí)候,如何才能把該用戶不能操作的domainObject剔除掉呢?這就需要afterInvocationManager來完成這個(gè)工作。下面來看下配置:
????<!--?==============?"AFTER?INTERCEPTION"?AUTHORIZATION?DEFINITIONS?===========?-->

????<bean?id="afterInvocationManager"?class="org.acegisecurity.afterinvocation.AfterInvocationProviderManager">
????????<property?name="providers">
????????????<list>
????????????????<ref?local="afterAclCollectionRead"/>
????????????</list>
????????</property>
????</bean>
????<!--?Processes?AFTER_ACL_COLLECTION_READ?configuration?settings?-->
????<bean?id="afterAclCollectionRead"?class="org.acegisecurity.afterinvocation.BasicAclEntryAfterInvocationCollectionFilteringProvider">
????????<property?name="aclManager">
????????????<ref?local="aclManager"/>
????????</property>
????????<property?name="requirePermission">
????????????<list>
????????????????<ref?local="org.acegisecurity.acl.basic.SimpleAclEntry.ADMINISTRATION"/>
????????????????<ref?local="org.acegisecurity.acl.basic.SimpleAclEntry.READ"/>
????????????</list>
????????</property>
????</bean> afterAclCollectionRead會(huì)在攔截的方法執(zhí)行結(jié)束的時(shí)候執(zhí)行。主要的作用就是在返回的List中挨個(gè)檢查domainObject的操作權(quán)限,然后根據(jù)requirePermission來剔除不符合的domainObject。
posted on 2006-06-17 00:20
差沙 閱讀(2276)
評論(4) 編輯 收藏 所屬分類:
avaj