基于acegi1.0.5 新的权限模型实现行级细粒度权限控制

实现效果图如下:
acegi1.05的新的权限模型针对 hsqldb 数据库,移植到到sqlserver/mysql 需要修改如下文件:
org.acegisecurity.acls.jdbc.BasicLookupStrategy ;
org.acegisecurity.acls.jdbc.JdbcMutableAclService;

JdbcMutableAclService 是最主要的类,对acl和ace的操作都集中在该类;
BasicLookupStrategy 只有一个方法readAclsById 获得实例对象的acl。

要点:
1、搭建基础代码可以参考ss2中的acegi实现(完全拷贝),在roleManager中需要特别注意是,如果采用getHibernateTemplate().saveOrUpdate(o);对对象进行保存或者更新的话,在修改角色对于用户或者角色对应资源的保存角色前,应该将缓存中的role对于的用户和资源的authorities清除rolename,然后更新角色实例,保存角色到cache中。
2、采用ss1中对对象保护的方法,新建com.at21.pm.core.security.acl.domain.AclDomainAware标示接口或者需要实现public long getId()方法。
3、编辑applicationContext-acegi-acl.xml(可以拷贝acegi中contact例子中的文件)。
4、解析acl中几个表对象
ACL_SID:用以保存sid的实例 PrincipalSid 用户实例,GrantedAuthoritySid 角色实例。
ACL_OBJECT_IDENTITY:用户需要保存的实例。字段ENTRIES_INHERITING表示是否继承父级权限。
ACL_ENTRY:用户实例对应sid的权限(read/create/delete/admin) 字段MASK标示权限(具体标示参考org.acegisecurity.acls.domain.BasePermission类)字段GRANTING表示是是否授予某用户/角色该实例的某权限

介绍开发树形实例:
1、保存树形到数据库对应表时,保存该对象到acl模型中调用updateAcl()方法。

java 代码

 

  1. /**  
  2.      * @param clazz 需要保护的对象类  
  3.      * @param id 实例对象id  
  4.      * @param sid 角色名/用户名  
  5.      * @param permission 权限  
  6.      * @param granting 授予/拒绝  
  7.      * @param entriesInheriting 是否从父类继承权限  
  8.      * @param parentid 父类实例  
  9.      */  
  10. public void updateAcl(Class clazz,Serializable id,Sid sid,Permission permission,boolean granting,boolean entriesInheriting,Serializable parentid){   
  11.         MutableAcl acl;   
  12.         ObjectIdentity oid = new ObjectIdentityImpl(clazz,id);   
  13.         try {   
  14.             acl = (MutableAcl) mutableAclService.readAclById(oid);   
  15.         } catch (NotFoundException nfe) {   
  16.             acl = mutableAclService.createAcl(oid);   
  17.         }   
  18.            
  19.         if ( parentid != null){   
  20.             MutableAcl parentacl;   
  21.             ObjectIdentity parentoi = new ObjectIdentityImpl(clazz,parentid);   
  22.             try {   
  23.                 parentacl = (MutableAcl) mutableAclService.readAclById(parentoi);   
  24.             } catch (NotFoundException nfe) {   
  25.                 parentacl = mutableAclService.createAcl(parentoi);   
  26.             }   
  27.             acl.setParent(parentacl);   
  28.         }   
  29.            
  30.         AccessControlEntry sameAce = null;   
  31.         AccessControlEntry[] aces = acl.getEntries();   
  32.         if ( aces != null && aces.length >0 ){   
  33.             for (int i = 0; i < aces.length; i++) {   
  34.                 AccessControlEntry ace = aces[i];   
  35.                 if ( ace.getPermission().getMask() == permission.getMask() && sid.equals(ace.getSid())){   
  36.                     sameAce = ace;   
  37.                     break;   
  38.                 }   
  39.             }   
  40.         }   
  41.            
  42.         if ( sameAce != null){   
  43.             acl.deleteAce(sameAce.getId());   
  44.         }   
  45.            
  46.         acl.insertAce(null, permission, sid, granting);   
  47.         acl.setEntriesInheriting(entriesInheriting);   
  48.            
  49.         mutableAclService.updateAcl(acl);   
  50.     }  

如果是从后台直接保存树形(比如采用线程定时更新树形的话),没有web层的请求的话,需要用户后台登陆
保存前添加如下代码

java 代码
  1. Authentication authRequest = new UsernamePasswordAuthenticationToken(admin,admin,new GrantedAuthority[]{new GrantedAuthorityImpl(role_admin)});   
  2.         SecurityContextHolder.getContext().setAuthentication(authRequest);  
2、对某用户授予read的权限。
java 代码
  1. String nodeid = request.getParameter("nodeid");   
  2. String rolename = request.getParameter("rolename");   
  3. String mark = request.getParameter("mark");   
  4. String granted = request.getParameter("granted");   
  5.                
  6. Permission p = mutableAclService.buildFromMask(Integer.parseInt(mark));   
  7. updateAcl(Vssdoc.class, Long.parseLong(nodeid), new GrantedAuthoritySid(rolename), p, Boolean.parseBoolean(granted), truenull);  
3、完成了。

 

你可能感兴趣的:(spring,bean,jdbc,Security,Acegi)