Acegi安全系统介绍 (二)
 
2008-12-11 来源:网络
 

三 Acegi安全系统扩展

相信side对Acegi的扩展会给你耳目一新的感觉,提供完整的扩展功能,管理界面,中文注释和靠近企业的安全策略。side只对Acegi不符合企业应用需要的功能进行扩展,尽量不改动其余部分来实现全套权限管理功能,以求能更好地适应Acegi升级。

3.1 基于角色的权限控制(RBAC)

Acegi 自带的 sample 表设计很简单: users表{username,password,enabled} authorities表{username,authority},这样简单的设计无法适应复杂的权限需求,故SpringSide选用RBAC模型对权限控制数据库表进行扩展。 RBAC引入了ROLE的概念,使User(用户)和Permission(权限)分离,一个用户拥有多个角色,一个角色拥有有多个相应的权限,从而减少了权限管理的复杂度,可更灵活地支持安全策略。

同时,我们也引入了resource(资源)的概念,一个资源对应多个权限,资源分为ACL,URL,和FUNTION三种。注意,URL和FUNTION的权限命名需要以AUTH_开头才会有资格参加投票, 同样的ACL权限命名需要ACL_开头。

3.2 管理和使用EhCache

3.2.1 设立缓存

在SpringSide里的 Acegi 扩展使用 EhCache 就作为一种缓存解决方案,以缓存用户和资源的信息和相对应的权限信息。

首先需要一个在classpath的ehcache.xml 文件,用于配置EhCache。

 1 < ehcache >
 2 < defaultCache
 3              maxElementsInMemory ="10000"
 4             eternal ="false"
 5             overflowToDisk ="true"
 6             timeToIdleSeconds ="0"
 7             timeToLiveSeconds ="0"
 8             diskPersistent ="false"
 9            diskExpiryThreadIntervalSeconds = "120" />  
10      <!--  acegi cache -->
11      < cache  name ="userCache"
12            maxElementsInMemory ="10000"
13            eternal ="true"
14           overflowToDisk = "true" />
15      <!--  acegi cache -->    
16      < cache  name ="resourceCache"
17            maxElementsInMemory ="10000"
18            eternal ="true"
19            overflowToDisk ="true" />
20 </ ehcache >    
21

maxElementsInMemory设定了允许在Cache中存放的数据数目,eternal设定Cache是否会过期,overflowToDisk设定内存不足的时候缓存到硬盘,timeToIdleSeconds和timeToLiveSeconds设定缓存游离时间和生存时间,diskExpiryThreadIntervalSeconds设定缓存在硬盘上的生存时间,注意当eternal="true"时,timeToIdleSeconds,timeToLiveSeconds和diskExpiryThreadIntervalSeconds都是无效的.

<defaultCache>是除制定的Cache外其余所有Cache的设置,针对Acegi 的情况, 专门设置了userCache和resourceCache,都设为永不过期。在applicationContext-acegi-security.xml中相应的调用是


<bean id="userCacheBackend" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager" ref="cacheManager"/>
<property name="cacheName" value=" userCache"/>
</bean>
<bean id="userCache" class="org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache" autowire="byName">
<property name="cache" ref="userCacheBackend"/>
</bean>

<bean id="resourceCacheBackend" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager" ref="cacheManager"/>
<property name="cacheName" value=" resourceCache"/>
</bean>
<bean id="resourceCache" class="org.springside.modules.security.service.acegi.cache.ResourceCache" autowire="byName">
<property name="cache" ref="resourceCacheBackend"/>
</bean>

<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>

"cacheName" 就是设定在ehcache.xml 中相应Cache的名称 : userCache,resourceCache。

userCache使用的是Acegi 的EhCacheBasedUserCache(实现了UserCache接口)

1 public   interface  UserCache    {    
2      public  UserDetails getUserFromCache   (String username);    
3      public   void  putUserInCache   (UserDetails user);    
4      public   void  removeUserFromCache   (String username);
5 }

UserCache 就是通过EhCache对UserDetails 进行缓存管理

1 public   interface  UserDetails    extends  Serializable  {   
2      public   boolean  isAccountNonExpired();    
3      public   boolean  isAccountNonLocked();    
4      public  GrantedAuthority[] getAuthorities();    
5      public   boolean  isCredentialsNonExpired();    
6      public   boolean  isEnabled();    
7      public  String getPassword();    
8      public  String getUsername();
9 }

resourceCache是SpringSide的扩展类  

 1public class ResourceCache   {    
 2    public ResourceDetails getAuthorityFromCache   (String resString) {
 3           
 4    }    
 5    public void putAuthorityInCache  (ResourceDetails resourceDetails) {
 6          
 7    }    
 8    public void removeAuthorityFromCache   (String resString) {
 9         
10    }    
11    public List getUrlResStrings() {
12         
13    }    
14    public List getFunctions() {
15         
16    }
17}

而ResourceCache 是对ResourceDetails 类进行缓存管理

1 public   interface  ResourceDetails    extends  Serializable  {    
2      public  String getResString();    
3      public  String getResType();    
4      public  GrantedAuthority[] getAuthorities();
5 }

GrantedAuthority 就是权限信息,在Acegi 的 sample 里GrantedAuthority 的信息如ROLE_USER, ROLE_SUPERVISOR, ACL_CONTACT_DELETE, ACL_CONTACT_ADMIN等等,网上也有很多例子把角色作为GrantedAuthority ,但事实上看看ACL 就知道, Acegi本身根本就没有角色这个概念,GrantedAuthority 包含的信息应该是权限,对于非ACL的权限用 AUTH_ 开头更为合理, 如SpringSide里的 AUTH_ADMIN_LOGIN, AUTH_BOOK_MANAGE 等等。

3.2.2 管理缓存

使用AcegiCacheManager对userCache和resourceCache进行统一缓存管理。当在后台对用户信息进行修改或赋权的时候, 在更新数据库同时就会调用acegiCacheManager相应方法, 从数据库中读取数据并替换cache中相应部分,使cache与数据库同步

 1 public   class  AcegiCacheManager  extends  BaseService  {
 2      private  ResourceCache resourceCache   ;
 3      private  UserCache userCache   ;    
 4
 5      /**      * 修改User时更改userCache        */
 6      public   void  modifyUserInCache   (User user, String orgUsername)  {
 7             
 8     }
   
 9      /**      * 修改Resource时更改resourceCache        */     
10      public   void  modifyResourceInCache   (Resource resource, String orgResourcename)  {
11             
12     }
    
13      /**      *   修改权限时同时修改userCache和resourceCache      */     
14      public   void  modifyPermiInCache   (Permission permi, String orgPerminame)  {
15           
16     }
    
17      /**      * User授予角色时更改userCache      */     
18      public   void  authRoleInCache   (User user)  {
19             
20     }
    
21      /**      * Role授予权限时更改userCache和resourceCache        */     
22      public   void  authPermissionInCache   (Role role)  {
23           
24     }
    
25      /**      * Permissioni授予资源时更改resourceCache        */     
26      public   void  authResourceInCache   (Permission permi)  {
27           
28     }
    
29      /**      *   初始化userCache      */     
30      public   void  initUserCache   ()  {
31           
32     }
    
33      /**      *   初始化resourceCache      */     
34      public   void  initResourceCache   ()  { }     
35      /**      *  获取所有的url资源      */     
36      public  List getUrlResStrings   ()  {
37           
38     }
    
39      /**      * 获取所有的Funtion资源        */     
40      public  List getFunctions   ()  {
41           
42     }
    
43      /**      * 根据资源串获取资源        */     
44      public  ResourceDetails getAuthorityFromCache   (String resString)  {
45           
46     }
 
47     
48     
49
50 }

51

3.3 资源权限定义扩展

Acegi给出的sample里,资源权限对照关系是配置在xml中的,试想一下如果你的企业安全应用有500个用户,100个角色权限的时候,维护这个xml将是个繁重无比的工作,如何动态更改用户权限更是个头痛的问题

 1     < bean  id ="contactManagerSecurity"  class ="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor" >       
 2         < property  name ="authenticationManager" >
 3             < ref  bean ="authenticationManager" />
 4         </ property >       
 5         < property  name ="accessDecisionManager" >
 6             < ref  local ="businessAccessDecisionManager" />
 7         </ property >       
 8         < property  name ="afterInvocationManager" >
 9             < ref  local ="afterInvocationManager" />
10         </ property >       
11         < property  name ="objectDefinitionSource" >          
12             < value >            
13                sample.contact.ContactManager.create=ROLE_USER            
14                sample.contact.ContactManager.getAllRecipients=ROLE_USER            
15                sample.contact.ContactManager.getAll=ROLE_USER,AFTER_ACL_COLLECTION_READ            
16                sample.contact.ContactManager.getById=ROLE_USER,AFTER_ACL_READ            
17                sample.contact.ContactManager.delete=ACL_CONTACT_DELETE            
18                sample.contact.ContactManager.deletePermission=ACL_CONTACT_ADMIN            
19                sample.contact.ContactManager.addPermission=ACL_CONTACT_ADMIN         
20             </ value >       
21         </ property >    
22    </ bean >
 
 1    < bean  id ="filterInvocationInterceptor"  class ="org.acegisecurity.intercept.web.FilterSecurityInterceptor" >       
 2        < property  name ="authenticationManager" >
 3            < ref  bean ="authenticationManager" />
 4        </ property >       
 5        < property  name ="accessDecisionManager" >
 6            < ref  local ="httpRequestAccessDecisionManager" />
 7        </ property >       
 8        < property  name ="objectDefinitionSource" >          
 9            < value >        
10               CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON       
11               PATTERN_TYPE_APACHE_ANT       
12               /index.jsp=ROLE_ANONYMOUS,ROLE_USER       
13               /hello.htm=ROLE_ANONYMOUS,ROLE_USER       
14               /logoff.jsp=ROLE_ANONYMOUS,ROLE_USER       
15               /switchuser.jsp=ROLE_SUPERVISOR       
16               /j_acegi_switch_user=ROLE_SUPERVISOR      
17               /acegilogin.jsp*=ROLE_ANONYMOUS,ROLE_USER      
18               /**=ROLE_USER         
19            </ value >       
20        </ property >    
21    </ bean >
22

火龙果软件/UML软件工程组织致力于提高您的软件工程实践能力,我们不断地吸取业界的宝贵经验,向您提供经过数百家企业验证的有效的工程技术实践经验,同时关注最新的理论进展,帮助您“领跑您所在行业的软件世界”。
资源网站: UML软件工程组织