四 Acegi ACL使用 
		4.1 基本概念
		      在google中搜索'acl'会找到很多相关的介绍,而且涉及的范围也特别广泛。ACL是(Access Control List)的缩写,顾名思义,ACL是‘访问控制列表’的意思。通俗点说,ACL保存了所有用户或角色对资源的访问权限。最典型的ACL实现是流行操作系统(window, unix)的文件访问控制系统,精确定义了某个用户或角色对某个特定文件的读、写、执行等权限,更通俗的例子是可以定义某个管理员只能管一部分的订单,而另一个管理员只能管另一部分的。
		4.2 Acegi ACL配置
		Acegi好早就实现了ACL(好像是0.5),但是使用起来确实有点麻烦,所以用的不是太广泛。这里简单的说明一下使用方法,希望有更多的朋友来试试。
首先要理解Acegi里面Voter的概念,ACL正是在一个Voter上扩展起来的。现来看一下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指的是这个Voter对哪些SecurityConfig起作用,我们可以把ACL_READ配置在想要拦截的Method上。比方说我们要拦截readOrder这个方法,以实现ACL控制,可以这样配置。
 orderManager.readOrder=ACL_READ
- 
						
								
										processDomainObjectClass指出哪些DomainObject是要进行ACL校验的。
								
						
				
- 
						
								
										aclManager是一个比较重要的概念,主要负责在权限列表中根据用户和DomainObject取得acl列表。
								
						
				
- 
						
								requirePermission指出要进行这个操作必须具备的acl权限,比方说read操作就必须有ADMINISTRATION或READ两个权限。
						
				
				
						其实整个过程看下来比较清晰,下面来看一下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的一贯风格,Provider可以提供多种取得ACL访问列表的途径,默认的是用basicAclProvider在数据库中取得。既然提到了数据库,那我们就来看一下Acegi默认提供的ACL在数据库里的保存表结构:
		
				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表存放了所有受保护的domainObject的信息。其中object_identity字段保存了domainObject的class和id,默认的保存格式是:domainClass:domainObjectId。 
- acl_permission 就是ACL权限列表了,recipient 是用户或角色信息,mask表示了这个用户或角色对这个domainObject的访问权限。注意这些信息的保存格式都是可以根据自己的需要改变的。
这样读取和删除的时候Acegi就能很好的完成拦截工作,但是读取一个List的时候,如何才能把该用户不能操作的domainObject剔除掉呢?这就需要afterInvocationManager来完成这个工作。下面来看下配置:
		
				    
				<!--
				 ============== "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会在拦截的方法执行结束的时候执行。主要的作用就是在返回的List中挨个检查domainObject的操作权限,然后根据requirePermission来剔除不符合的domainObject。
		
		4.3 使用RuleEngine设置的ACL规则
		在SpringSide里使用了RuleEngine来设置ACL规则,具体规则见
bookstore-sample\resources\rules\drl
		
				
		
大盘预测
 
国富论
	posted on 2007-09-12 14:46 
华梦行 阅读(300) 
评论(0)  编辑  收藏