<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    szhswl
    宋針還的個(gè)人空間
    轉(zhuǎn)自:http://www.cublog.cn/u/11905/showart_162625.html

    最近在做項(xiàng)目遇到了權(quán)限管理,用戶要求可以自己建立不同的角色對(duì)系統(tǒng)的資源進(jìn)行控制, 不同的用戶有不同的角色,又恰恰框架中用到了struts+spring+hibernate,要求在web層調(diào)用 業(yè)務(wù)邏輯層 時(shí)不考慮權(quán)限,web層可以控制用戶的顯示界面,邏輯層處理用戶權(quán)限問(wèn)題。
    想來(lái)想去好像只有spring 的aop 可以做到,在調(diào)用到 接口 中的方法時(shí),首先檢查用戶的權(quán)限,如果檢查通過(guò)則繼續(xù)執(zhí)行,否則拋出異常。但是新的問(wèn)題又出現(xiàn)了,如何在邏輯層上來(lái)得到當(dāng)前用戶的id,以致用戶的 角色,總不能每次都要從web中傳來(lái)一個(gè) httprequest,或者 session 這類的吧。在網(wǎng)上看了很多資料,發(fā)現(xiàn)了acegi,恰好解決了以上的難題,具體的實(shí)現(xiàn)原理這里就不多說(shuō)了,網(wǎng)上有很多相關(guān)資料。
    說(shuō)正題,首先來(lái)看看acegi 的官方 example ,我下載的是acegi-security-1.0.0-RC1,解壓縮后可以看到acegi-security-sample-contacts-filter.war,打開(kāi)配置文件有這樣幾句
     1   <bean id="contactManagerSecurity" class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor"> 
     2       <property name="authenticationManager"><ref bean="authenticationManager"/></property> 
     3       <property name="accessDecisionManager"><ref local="businessAccessDecisionManager"/></property> 
     4       <property name="afterInvocationManager"><ref local="afterInvocationManager"/></property> 
     5       <property name="objectDefinitionSource"> 
     6          <value> 
     7             sample.contact.ContactManager.create=ROLE_USER 
     8             sample.contact.ContactManager.getAllRecipients=ROLE_USER 
     9             sample.contact.ContactManager.getAll=ROLE_USER,AFTER_ACL_COLLECTION_READ 
    10             sample.contact.ContactManager.getById=ROLE_USER,AFTER_ACL_READ 
    11             sample.contact.ContactManager.delete=ACL_CONTACT_DELETE 
    12             sample.contact.ContactManager.deletePermission=ACL_CONTACT_ADMIN 
    13             sample.contact.ContactManager.addPermission=ACL_CONTACT_ADMIN 
    14          </value> 
    15       </property> 
    16    </bean> 
    17 

    可以看到它是通過(guò)讀配置文件來(lái)判斷執(zhí)行某個(gè)方法所需要的角色的,再看這幾句
    <bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor"> 
          
    <property name="authenticationManager"><ref bean="authenticationManager"/></property> 
          
    <property name="accessDecisionManager"><ref local="httpRequestAccessDecisionManager"/></property> 
          
    <property name="objectDefinitionSource"> 
             
    <value> 
                                CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON 
                                PATTERN_TYPE_APACHE_ANT 
                                /index.jsp=ROLE_ANONYMOUS,ROLE_USER 
                                /hello.htm=ROLE_ANONYMOUS,ROLE_USER 
                                /logoff.jsp=ROLE_ANONYMOUS,ROLE_USER 
                                /switchuser.jsp=ROLE_SUPERVISOR 
                                /j_acegi_switch_user=ROLE_SUPERVISOR 
                                /acegilogin.jsp*=ROLE_ANONYMOUS,ROLE_USER 
                                    /**=ROLE_USER 
             
    </value> 
          
    </property> 
       
    </bean> 
    同樣是將頁(yè)面的訪問(wèn)權(quán)限寫(xiě)死在配置文件中,再來(lái)看看它的tag是如何處理的
    <auth:authorize ifAnyGranted="ROLE_DELETE"> 
              
    <href="">刪除</a> 
    </auth:authorize> 
    可見(jiàn)它是要求我們對(duì)鏈接或者其他資源的保護(hù)時(shí)提供 用戶角色,可是既然角色是用戶自己添加的我們又如何來(lái)寫(xiě)死在這里呢?
    還有就是它對(duì)用戶驗(yàn)證默認(rèn)使用的是jdbc,即 JdbcDaoImpl
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
                    
    <property name="dataSource"><ref local="dataSource"/></property> 
            
    </bean> 
    而我們希望基于Hibernate的Dao來(lái)實(shí)現(xiàn)。
    可見(jiàn)僅僅使用現(xiàn)有的acegi 是 無(wú)法滿足我們項(xiàng)目開(kāi)發(fā)的需求的。
    解決方法:

    1: 開(kāi)發(fā)基于數(shù)據(jù)庫(kù)的保護(hù)資源。

    看過(guò)acegi的源代碼就會(huì)知道,對(duì)保護(hù)資源的定義是通過(guò)實(shí)現(xiàn)ObjectDefinitionSource這個(gè)接口來(lái)實(shí)現(xiàn)的,而且acegi為我們提供了默認(rèn)實(shí)現(xiàn)的抽象類
    public abstract class AbstractMethodDefinitionSource 
        
    implements MethodDefinitionSource 
        
    //~ Static fields/initializers ============================================= 

        
    private static final Log logger = LogFactory.getLog(AbstractMethodDefinitionSource.class); 

        
    //~ Methods ================================================================ 

        
    public ConfigAttributeDefinition getAttributes(Object object) 
            
    throws IllegalArgumentException 
            Assert.notNull(object, 
    "Object cannot be null"); 

            
    if (object instanceof MethodInvocation) 
                
    return this.lookupAttributes(((MethodInvocation) object).getMethod()); 
            }
     

            
    if (object instanceof JoinPoint) 
                JoinPoint jp 
    = (JoinPoint) object; 
                Class targetClazz 
    = jp.getTarget().getClass(); 
                String targetMethodName 
    = jp.getStaticPart().getSignature().getName(); 
                Class[] types 
    = ((CodeSignature) jp.getStaticPart().getSignature()) 
                        .getParameterTypes(); 

                
    if (logger.isDebugEnabled()) 
                    logger.debug(
    "Target Class: " + targetClazz); 
                    logger.debug(
    "Target Method Name: " + targetMethodName); 

                    
    for (int i = 0; i < types.length; i++
                        
    if (logger.isDebugEnabled()) 
                            logger.debug(
    "Target Method Arg #" + i + "" 
                                    
    + types[i]); 
                        }
     
                    }
     
                }
     

                
    try 
                    
    return this.lookupAttributes(targetClazz.getMethod(targetMethodName, types)); 
                }
     catch (NoSuchMethodException nsme) 
                    
    throw new IllegalArgumentException("Could not obtain target method from JoinPoint: " + jp); 
                }
     
            }
     

            
    throw new IllegalArgumentException("Object must be a MethodInvocation or JoinPoint"); 
        }
     

        
    public boolean supports(Class clazz) 
            
    return (MethodInvocation.class.isAssignableFrom(clazz) 
            
    || JoinPoint.class.isAssignableFrom(clazz)); 
        }
     


        
    protected abstract ConfigAttributeDefinition lookupAttributes(Method method); 
    }
     

    我們要做的就是實(shí)現(xiàn)它的
    protected abstract ConfigAttributeDefinition lookupAttributes(Method method);方法,
    以下是我的實(shí)現(xiàn)方法,大致思路是這樣,通過(guò)由抽象類傳來(lái)的Method 對(duì)象得到
    調(diào)用這個(gè)方法的 包名,類名,方法名 也就是secureObjectName, 查詢數(shù)據(jù)庫(kù)并將結(jié)果映射為Function 也就是secureObject ,由于Function 與 Role 的多對(duì)多關(guān)系 可以得到 Function所對(duì)應(yīng)的 Roles ,在將role 包裝成GrantedAuthority (也就是acegi中的角色)。其中由于頻繁的對(duì)數(shù)據(jù)庫(kù)的查詢 所以使用Ehcache 來(lái)作為緩存。
      1 package sample.auth; 
      2 
      3 import java.lang.reflect.Method; 
      4 import java.util.ArrayList; 
      5 import java.util.Arrays; 
      6 import java.util.Collection; 
      7 import java.util.Iterator; 
      8 import java.util.List; 
      9 import java.util.Set; 
     10 
     11 import org.acegisecurity.ConfigAttributeDefinition; 
     12 import org.acegisecurity.ConfigAttributeEditor; 
     13 import org.acegisecurity.GrantedAuthority; 
     14 import org.acegisecurity.GrantedAuthorityImpl; 
     15 import org.acegisecurity.intercept.method.AbstractMethodDefinitionSource; 
     16 import org.springframework.util.Assert; 
     17 
     18 import sample.auth.cache.AuthorityBasedFunctionCache; 
     19 import sample.auth.cache.info.FunctionByNameCache; 
     20 import sample.dao.IBaseDao; 
     21 import sample.mappings.function.Function; 
     22 import sample.mappings.role.Role; 
     23 
     24 public class DatabaseDrivenMethodDefinitionSourcew extends 
     25                 AbstractMethodDefinitionSource { 
     26         
     27         // baseDao 提供通過(guò)HIbenate對(duì)數(shù)據(jù)庫(kù)操作的實(shí)現(xiàn) 
     28         private IBaseDao baseDao; 
     29         // AuthorityBasedFunctionCache 通過(guò)Function 查 Role 時(shí)緩存 
     30         private AuthorityBasedFunctionCache cache; 
     31         // FunctionByNameCache 由反射到的方法名查找 數(shù)據(jù)庫(kù)對(duì)應(yīng)的Function 時(shí)的緩存 
     32         private FunctionByNameCache functionCache; 
     33 
     34         public FunctionByNameCache getFunctionCache() { 
     35                 return functionCache; 
     36         } 
     37 
     38         public void setFunctionCache(FunctionByNameCache functionCache) { 
     39                 this.functionCache = functionCache; 
     40         } 
     41 
     42         protected ConfigAttributeDefinition lookupAttributes(Method mi) { 
     43         
     44                 Assert.notNull(mi,"lookupAttrubutes in the DatabaseDrivenMethodDefinitionSourcew is null"); 
     45                 String secureObjectName=mi.getDeclaringClass().getName() +"."+ mi.getName(); 
     46                 //Function 為數(shù)據(jù)庫(kù)中保護(hù)資源的映射 
     47                 Function secureObject=functionCache.getFunctionByCache(secureObjectName); 
     48 
     49                 if(secureObject==null)//if secure object not exist in database 
     50                 { 
     51                         secureObject=(Function)baseDao.loadByKey(Function.class"protectfunction", secureObjectName); 
     52                         functionCache.putFunctionInCache(secureObject); 
     53                 } 
     54                     
     55                 if(secureObject==null
     56                         Assert.notNull(secureObject,"secureObject(Function) not found in db"); 
     57                 //retrieving roles associated with this secure object 
     58                 
     59                 Collection roles = null
     60                 GrantedAuthority[] grantedAuthoritys = cache.getAuthorityFromCache(secureObject.getName()); 
     61                 // 如果是第一次 cache 為空 
     62                 if(grantedAuthoritys == null){ 
     63                         
     64                         Set rolesSet = secureObject.getRoles(); 
     65                         Iterator it = rolesSet.iterator(); 
     66                         List list = new ArrayList(); 
     67                         while(it.hasNext()){ 
     68                                 
     69                                 Role role = (Role)it.next(); 
     70                                 GrantedAuthority g = new  GrantedAuthorityImpl(role.getName()); 
     71                                 list.add(g);        
     72                         } 
     73                         grantedAuthoritys = (GrantedAuthority[])list.toArray(new GrantedAuthority[0]); 
     74                         cache.putAuthorityInCache(secureObject.getName(),grantedAuthoritys); 
     75                         roles = Arrays.asList(grantedAuthoritys); 
     76                 }else
     77                         
     78                         roles = Arrays.asList(grantedAuthoritys); 
     79                 } 
     80                 
     81                 if(!roles.isEmpty()){ 
     82                         ConfigAttributeEditor configAttrEditor=new ConfigAttributeEditor(); 
     83                         StringBuffer rolesStr=new StringBuffer(); 
     84                         for(Iterator it = roles.iterator();it.hasNext();){ 
     85                                 GrantedAuthority role=(GrantedAuthority)it.next(); 
     86                                 rolesStr.append(role.getAuthority()).append(","); 
     87                         } 
     88 
     89                         configAttrEditor.setAsText( rolesStr.toString().substring(0,rolesStr.length()-1) ); 
     90                         ConfigAttributeDefinition configAttrDef=(ConfigAttributeDefinition)configAttrEditor.getValue(); 
     91                         return configAttrDef; 
     92                 } 
     93 
     94                 Assert.notEmpty(roles,"collection of roles is null or empty"); 
     95                 return null
     96                 
     97 
     98         } 
     99 
    100         public Iterator getConfigAttributeDefinitions() { 
    101                 
    102                 return null
    103         } 
    104 
    105 
    106         public IBaseDao getBaseDao() { 
    107                 return baseDao; 
    108         } 
    109 
    110 
    111         public void setBaseDao(IBaseDao baseDao) { 
    112                 this.baseDao = baseDao; 
    113         } 
    114 
    115         public AuthorityBasedFunctionCache getCache() { 
    116                 return cache; 
    117         } 
    118 
    119         public void setCache(AuthorityBasedFunctionCache cache) { 
    120                 this.cache = cache; 
    121         } 
    122 
    123 
    124 

    2:定義 基于方法的 自定義標(biāo)志

    通過(guò)以上的分析 , 要想使用acegi 做頁(yè)面的顯示控制僅僅靠角色(Role)是不行的,因?yàn)橛脩艨赡茈S時(shí)定義出新的角色,所以只能 基于方法(Function)的控制。可是acegi 只是提供了基于 角色的 接口GrantedAuthority ,怎么辦?  ,如法炮制。 首先定義出我們自己的GrantedFunction,實(shí)現(xiàn)也雷同 GrantedAuthorityImpl

     1 package sample.auth; 
     2 
     3 import java.io.Serializable; 
     4 public class GrantedFunctionImpl implements GrantedFunction , Serializable{ 
     5 
     6     private String function; 
     7 
     8     //~ Constructors =========================================================== 
     9 
    10     public GrantedFunctionImpl(String function) { 
    11         super(); 
    12         this.function = function; 
    13     } 
    14 
    15     protected GrantedFunctionImpl() { 
    16         throw new IllegalArgumentException("Cannot use default constructor"); 
    17     } 
    18 
    19     //~ Methods ================================================================ 
    20 
    21     public String getFunction() { 
    22         return this.function; 
    23     } 
    24 
    25     public boolean equals(Object obj) { 
    26         if (obj instanceof String) { 
    27             return obj.equals(this.function); 
    28         } 
    29 
    30         if (obj instanceof GrantedFunction) { 
    31             GrantedFunction attr = (GrantedFunction) obj; 
    32 
    33             return this.function.equals(attr.getFunction()); 
    34         } 
    35 
    36         return false
    37     } 
    38 
    39     public int hashCode() { 
    40         return this.function.hashCode(); 
    41     } 
    42 
    43     public String toString() { 
    44         return this.function; 
    45     } 
    46 
    47 
    48 

    以下是我的標(biāo)志實(shí)現(xiàn),大致思路是 根據(jù) 頁(yè)面 的傳來(lái)的 方法名(即 FunctionName)查詢出對(duì)應(yīng)的Functions,并且包裝成grantedFunctions ,然后根據(jù)用戶的角色查詢出用戶對(duì)應(yīng)的Functions ,再取這兩個(gè)集合的交集,最后再根據(jù)這個(gè)集合是否為空判斷是否顯示標(biāo)志體的內(nèi)容。
      1 package sample.auth; 
      2 import java.util.Arrays; 
      3 import java.util.Collection; 
      4 import java.util.Collections; 
      5 import java.util.HashSet; 
      6 import java.util.Iterator; 
      7 import java.util.List; 
      8 import java.util.Set; 
      9 
     10 import javax.servlet.jsp.JspException; 
     11 import javax.servlet.jsp.tagext.Tag; 
     12 import javax.servlet.jsp.tagext.TagSupport; 
     13 
     14 import org.acegisecurity.Authentication; 
     15 import org.acegisecurity.GrantedAuthority; 
     16 import org.acegisecurity.context.SecurityContextHolder; 
     17 import org.springframework.util.StringUtils; 
     18 import org.springframework.web.util.ExpressionEvaluationUtils; 
     19 
     20 import sample.web.action.AppContext; 
     21 /** 
     22 
     23 @author limq 
     24 
     25 */ 
     26 public class AuthorizeActionTag extends TagSupport{ 
     27 
     28             private String ifAllGranted = ""
     29             private String ifAnyGranted = ""
     30             private String ifNotGranted = ""
     31             
     32             public void setIfAllGranted(String ifAllGranted) throws JspException { 
     33                 this.ifAllGranted = ifAllGranted; 
     34             } 
     35 
     36             public String getIfAllGranted() { 
     37                 return ifAllGranted; 
     38             } 
     39 
     40             public void setIfAnyGranted(String ifAnyGranted) throws JspException { 
     41                 this.ifAnyGranted = ifAnyGranted; 
     42             } 
     43 
     44             public String getIfAnyGranted() { 
     45                 return ifAnyGranted; 
     46             } 
     47 
     48             public void setIfNotGranted(String ifNotGranted) throws JspException { 
     49                 this.ifNotGranted = ifNotGranted; 
     50             } 
     51 
     52             public String getIfNotGranted() { 
     53                 return ifNotGranted; 
     54             } 
     55             
     56             public int doStartTag() throws JspException { 
     57                 if (((null == ifAllGranted) || "".equals(ifAllGranted)) 
     58                     && ((null == ifAnyGranted) || "".equals(ifAnyGranted)) 
     59                     && ((null == ifNotGranted) || "".equals(ifNotGranted))) { 
     60                     return Tag.SKIP_BODY; 
     61                 } 
     62 
     63                 final Collection granted = getPrincipalFunctionByAuthorities(); 
     64 
     65                 final String evaledIfNotGranted = ExpressionEvaluationUtils 
     66                     .evaluateString("ifNotGranted", ifNotGranted, pageContext); 
     67 
     68                 if ((null != evaledIfNotGranted) && !"".equals(evaledIfNotGranted)) { 
     69                     Set grantedCopy = retainAll(granted, 
     70                                     parseSecurityString(evaledIfNotGranted)); 
     71 
     72                     if (!grantedCopy.isEmpty()) { 
     73                         return Tag.SKIP_BODY; 
     74                     } 
     75                 } 
     76 
     77                 final String evaledIfAllGranted = ExpressionEvaluationUtils 
     78                     .evaluateString("ifAllGranted", ifAllGranted, pageContext); 
     79 
     80                 if ((null != evaledIfAllGranted) && !"".equals(evaledIfAllGranted)) { 
     81                     if (!granted.containsAll(parseSecurityString(evaledIfAllGranted))) { 
     82                         return Tag.SKIP_BODY; 
     83                     } 
     84                 } 
     85 
     86                 final String evaledIfAnyGranted = ExpressionEvaluationUtils 
     87                     .evaluateString("ifAnyGranted", ifAnyGranted, pageContext); 
     88 
     89                 if ((null != evaledIfAnyGranted) && !"".equals(evaledIfAnyGranted)) { 
     90                     Set grantedCopy = retainAll(granted, 
     91                                     parseSecurityString(evaledIfAnyGranted)); 
     92 
     93                     if (grantedCopy.isEmpty()) { 
     94                         return Tag.SKIP_BODY; 
     95                     } 
     96                 } 
     97 
     98                 return Tag.EVAL_BODY_INCLUDE; 
     99             } 
    100     /** 
    101      * 得到用戶的Authentication,并且從Authentication中獲得 Authorities,進(jìn)而得到 授予用戶的 Function 
    102      * @return 
    103      */ 
    104             private Collection getPrincipalFunctionByAuthorities() { 
    105                     
    106                     
    107             Authentication currentUser = SecurityContextHolder.getContext() 
    108             .getAuthentication(); 
    109                 if (null == currentUser) { 
    110                     return Collections.EMPTY_LIST; 
    111                 } 
    112 
    113                 if ((null == currentUser.getAuthorities()) 
    114                     || (currentUser.getAuthorities().length < 1)) { 
    115                     return Collections.EMPTY_LIST; 
    116                 } 
    117            // currentUser.getAuthorities() 返回的是 GrantedAuthority[] 
    118                 List granted = Arrays.asList(currentUser.getAuthorities()); 
    119                 AuthDao authDao =(AuthDao) AppContext.getInstance().getAppContext().getBean("authDao"); 
    120                 Collection grantedFunctions = authDao.getFunctionsByRoles(granted); 
    121                 return grantedFunctions; 
    122             } 
    123 
    124             /** 
    125              * 得到用戶功能(Function)的集合,并且驗(yàn)證是否合法 
    126              * @param c Collection 類型 
    127              * @return Set類型 
    128              */ 
    129             private Set SecurityObjectToFunctions(Collection c) { 
    130                 Set target = new HashSet(); 
    131 
    132                 for (Iterator iterator = c.iterator(); iterator.hasNext();) { 
    133                     GrantedFunction function = (GrantedFunction) iterator.next(); 
    134 
    135                     if (null == function.getFunction()) { 
    136                         throw new IllegalArgumentException( 
    137                             "Cannot process GrantedFunction objects which return null from getFunction() - attempting to process " 
    138                             + function.toString()); 
    139                     } 
    140 
    141                     target.add(function.getFunction()); 
    142                 } 
    143 
    144                 return target; 
    145             } 
    146 
    147             /** 
    148              * 處理頁(yè)面標(biāo)志屬性 ,用' ,'區(qū)分 
    149              */ 
    150             private Set parseSecurityString(String functionsString) { 
    151                 final Set requiredFunctions = new HashSet(); 
    152                 final String[] functions = StringUtils 
    153                     .commaDelimitedListToStringArray(functionsString); 
    154 
    155                 for (int i = 0; i < functions.length; i++) { 
    156                     String authority = functions[i]; 
    157 
    158                  // Remove the role's whitespace characters without depending on JDK 1.4+ 
    159                  // Includes space, tab, new line, carriage return and form feed. 
    160                  String function = StringUtils.replace(authority, " """); 
    161                  function = StringUtils.replace(function, "\t"""); 
    162                  function = StringUtils.replace(function, "\r"""); 
    163                  function = StringUtils.replace(function, "\n"""); 
    164                  function = StringUtils.replace(function, "\f"""); 
    165 
    166                  requiredFunctions.add(new GrantedFunctionImpl(function)); 
    167                 } 
    168 
    169                 return requiredFunctions; 
    170             } 
    171             /** 
    172              * 獲得用戶所擁有的Function 和 要求的 Function 的交集 
    173              * @param granted 用戶已經(jīng)獲得的Function 
    174              * @param required 所需要的Function 
    175              * @return 
    176              */ 
    177           
    178             private Set retainAll(final Collection granted, final Set required) { 
    179                 Set grantedFunction = SecurityObjectToFunctions(granted); 
    180                 Set requiredFunction = SecurityObjectToFunctions(required); 
    181                 // retailAll() 獲得 grantedFunction 和 requiredFunction 的交集 
    182                 // 即刪除 grantedFunction 中  除了 requiredFunction 的項(xiàng) 
    183                 grantedFunction.retainAll(requiredFunction); 
    184 
    185                 return rolesToAuthorities(grantedFunction, granted); 
    186             } 
    187 
    188             /** 
    189              * 
    190              * @param grantedFunctions 已經(jīng)被過(guò)濾過(guò)的Function            
    191              * @param granted 未被過(guò)濾過(guò)的,即用戶所擁有的Function 
    192              * @return 
    193              */ 
    194             private Set rolesToAuthorities(Set grantedFunctions, Collection granted) { 
    195                 Set target = new HashSet(); 
    196 
    197                 for (Iterator iterator = grantedFunctions.iterator(); iterator.hasNext();) { 
    198                     String function = (String) iterator.next(); 
    199 
    200                     for (Iterator grantedIterator = granted.iterator(); 
    201                         grantedIterator.hasNext();) { 
    202                         GrantedFunction grantedFunction = (GrantedFunction) grantedIterator 
    203                             .next(); 
    204 
    205                         if (grantedFunction.getFunction().equals(function)) { 
    206                             target.add(grantedFunction); 
    207 
    208                             break
    209                         } 
    210                     } 
    211                 } 
    212 
    213                 return target; 
    214             } 
    215 
    216 
    217 
    再說(shuō)明一下吧,通過(guò) AppContext 獲得了Spring的上下文,以及AuthDao(實(shí)際意義上講以不再是單純的Dao,應(yīng)該是Service)
    package sample.auth; 

    import java.util.Collection; 
    public interface  AuthDao 

        
    /** 
         *  根據(jù)用戶的角色集合 得到 用戶的 操作權(quán)限 
         * 
    @param granted 已授予用戶的角色集合 
         * 
    @return 操作權(quán)限的集合 
         
    */
     
            
    public Collection getFunctionsByRoles(Collection granted); 
    }
     
    以下是AuthDao 的實(shí)現(xiàn)

    package sample.auth; 

    import java.util.Collection; 
    import java.util.HashSet; 
    import java.util.Iterator; 
    import java.util.Set; 

    import org.acegisecurity.GrantedAuthority; 

    import sample.auth.cache.FunctionCache; 
    import sample.auth.cache.info.RoleByNameCache; 
    import sample.dao.IBaseDao; 
    import sample.mappings.function.Function; 
    import sample.mappings.role.Role; 


    public class AuthDaoImpl  implements AuthDao { 

        
    private IBaseDao baseDao; 
        
    private FunctionCache cache; 
        
    private RoleByNameCache roleCache; 
        
            
    public RoleByNameCache getRoleCache() { 
                    
    return roleCache; 
            } 

            
    public void setRoleCache(RoleByNameCache roleCache) { 
                    
    this.roleCache = roleCache; 
            } 

            
    public FunctionCache getCache() { 
                    
    return cache; 
            } 

            
    public void setCache(FunctionCache cache) { 
                    
    this.cache = cache; 
            } 

            
    public IBaseDao getBaseDao() { 
            
    return baseDao; 
        } 

        
    public void setBaseDao(IBaseDao baseDao) { 
            
    this.baseDao = baseDao; 
        } 

      

            
    public Collection getFunctionsByRoles(Collection granted) { 
                    Set set 
    = new HashSet(); 
                    
    if(null == granted) throw new IllegalArgumentException("Granted Roles cannot be null"); 
            
                    
    for(Iterator it = granted.iterator();it.hasNext();){ 
                
                GrantedAuthority grantedAuthority 
    = (GrantedAuthority)it.next(); 
                Role  role 
    = roleCache.getRoleByRoleNameCache(grantedAuthority.getAuthority()); // 
                if(role == null){ 
                        role 
    = (Role)baseDao.loadByKey(Role.class"name", grantedAuthority.getAuthority()); 
                        roleCache.putRoleInCache(role); 
                } 
                GrantedFunction[] grantedFunctions 
    = cache.getFunctionFromCache(role.getName()); 
                
                
    if(grantedFunctions == null){ 
                        
                        Set functions 
    = role.getFunctions(); 
                                
    for(Iterator it2 = functions.iterator();it2.hasNext();){        
                        Function function 
    = (Function)it2.next(); 
                        GrantedFunction grantedFunction 
    = new GrantedFunctionImpl(function.getName()); 
                                        set.add(  grantedFunction  ); 
                                } 
                      
                                grantedFunctions 
    = (GrantedFunction[]) set.toArray(new GrantedFunction[0]); 
                                cache.putFuncitonInCache(role.getName(),grantedFunctions); 
                } 
                
                
    for(int i = 0 ; i < grantedFunctions.length; i++){ 
                        GrantedFunction grantedFunction 
    = grantedFunctions[i]; 
                        set.add(grantedFunction); 
                } 
                    } 
            
                    
    return set; 
            } 



    3 基于hibernate的用戶驗(yàn)證

    acegi 默認(rèn)的 的 用戶驗(yàn)證是 通過(guò)UserDetailsService 接口 實(shí)現(xiàn)的 也就是說(shuō)我們只要實(shí)現(xiàn)了 它的loadUserByUsername 方法。
    1 
    2 public UserDetails loadUserByUsername(String username) 
    3         throws UsernameNotFoundException, DataAccessException; 
    以下是我的實(shí)現(xiàn)
      1 package sample.auth; 
      2 
      3 import java.util.ArrayList; 
      4 import java.util.Iterator; 
      5 import java.util.List; 
      6 import java.util.Set; 
      7 
      8 import org.acegisecurity.GrantedAuthority; 
      9 import org.acegisecurity.GrantedAuthorityImpl; 
     10 import org.acegisecurity.userdetails.User; 
     11 import org.acegisecurity.userdetails.UserDetails; 
     12 import org.acegisecurity.userdetails.UserDetailsService; 
     13 import org.acegisecurity.userdetails.UsernameNotFoundException; 
     14 import org.springframework.dao.DataAccessException; 
     15 
     16 import sample.auth.cache.AuthorityBasedUserCache; 
     17 import sample.dao.IBaseDao; 
     18 import sample.mappings.role.Role; 
     19 import sample.utils.MisUtils; 
     20 
     21 public class HibernateDaoImpl implements UserDetailsService{ 
     22 
     23         
     24         private String rolePrefix = ""
     25         private boolean usernameBasedPrimaryKey = false
     26     private AuthorityBasedUserCache cache; 
     27 
     28     private IBaseDao baseDao; 
     29 
     30         public String getRolePrefix() { 
     31                 return rolePrefix; 
     32         } 
     33         
     34         public void setRolePrefix(String rolePrefix) { 
     35                 this.rolePrefix = rolePrefix; 
     36         } 
     37         
     38         public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException { 
     39                 UserDetails user = getUsersByUsernameQuery(username); 
     40                 if(user == nullreturn null
     41                 
     42                 GrantedAuthority[] arrayAuths =getAuthoritiesByUsernameQuery(username); 
     43              if (arrayAuths.length == 0) { 
     44                     throw new UsernameNotFoundException("User has no GrantedAuthority"); 
     45                 } 
     46               
     47              return new User(username, user.getPassword(), user.isEnabled(), 
     48                      truetruetrue, arrayAuths); 
     49         } 
     50 
     51         /** 
     52         * 根據(jù)用戶名查找用戶 
     53         * @param username 
     54         * @return 
     55         * @throws DataAccessException 
     56         */ 
     57         public UserDetails getUsersByUsernameQuery(String username)throws DataAccessException { 
     58                         sample.mappings.user.User misUser = (sample.mappings.user.User)baseDao.loadByKey(sample.mappings.user.User.class,"name",username); 
     59                         if(misUser != null
     60                         { 
     61                         org.acegisecurity.userdetails.UserDetails user = 
     62                         new User(misUser.getName(),misUser.getPassword(),MisUtils.parseBoolean(misUser.getEnable()),true,true,true,getAuthoritiesByUsernameQuery(username)); 
     63                         return user; 
     64                         }else 
     65                         return null;        
     66                 } 
     67         
     68         /** 
     69           * 根據(jù)用戶名查找角色 
     70           * @param username 
     71           * @return GrantedAuthority[] 用戶角色 
     72           * @throws DataAccessException 
     73           */ 
     74         public GrantedAuthority[] getAuthoritiesByUsernameQuery(String username) 
     75                 throws DataAccessException { 
     76                 sample.mappings.user.User misUser 
     77                 = (sample.mappings.user.User)baseDao.loadByKey(sample.mappings.user.User.class,"name",username); 
     78 
     79         if(misUser != null){ 
     80                 GrantedAuthority[] grantedAuthoritys = cache.getAuthorityFromCache(misUser.getName()); 
     81         
     82                 if(grantedAuthoritys == null){ 
     83                 
     84                         Set roles =     misUser.getRoles(); 
     85                         Iterator it = roles.iterator(); 
     86                 
     87                         List list = new ArrayList(); 
     88                         while(it.hasNext() ){ 
     89         
     90                                 GrantedAuthorityImpl gai = new GrantedAuthorityImpl(  ((Role)it.next()).getName()  ); 
     91                                 list.add(gai); 
     92                                 } 
     93                         grantedAuthoritys =(GrantedAuthority[]) list.toArray(new  GrantedAuthority[0]); 
     94                         cache.putAuthorityInCache(misUser.getName(),grantedAuthoritys); 
     95                         return grantedAuthoritys; 
     96                 
     97                 } 
     98                return grantedAuthoritys; 
     99         } 
    100 
    101                 return null
    102 
    103 
    104         public IBaseDao getBaseDao() { 
    105                 return baseDao; 
    106         } 
    107 
    108         public void setBaseDao(IBaseDao baseDao) { 
    109                 this.baseDao = baseDao; 
    110         } 
    111 
    112         public AuthorityBasedUserCache getCache() { 
    113                 return cache; 
    114         } 
    115 
    116         public void setCache(AuthorityBasedUserCache cache) { 
    117                 this.cache = cache; 
    118         } 
    119 
    120 
    121 
    通過(guò)以上對(duì)acegi 的 處理,足以滿足我們目前在spring下基于RBAC的動(dòng)態(tài)權(quán)限管理。同時(shí)在對(duì)頻繁的數(shù)據(jù)庫(kù)查詢上使用了Ehcache作為緩存,在性能上有了很大的改善。


    ---------------------------------------------------------------------------------------------------------------------------------
    說(shuō)人之短,乃護(hù)己之短。夸己之長(zhǎng),乃忌人之長(zhǎng)。皆由存心不厚,識(shí)量太狹耳。能去此弊,可以進(jìn)德,可以遠(yuǎn)怨。
    http://www.tkk7.com/szhswl
    ------------------------------------------------------------------------------------------------------ ----------------- ---------
    posted on 2007-12-03 20:37 宋針還 閱讀(306) 評(píng)論(0)  編輯  收藏 所屬分類: JAVA
    主站蜘蛛池模板: 亚洲成人免费电影| 精品无码免费专区毛片| 亚洲中文字幕无码专区| 日本在线观看免费高清| 国产区卡一卡二卡三乱码免费| 亚洲码欧美码一区二区三区| 噜噜嘿在线视频免费观看| 亚洲小说图区综合在线| 天天看片天天爽_免费播放| 亚洲日韩av无码中文| 好吊妞视频免费视频| 亚洲欧美自偷自拍另类视| 成在人线AV无码免费| 亚洲日韩AV无码一区二区三区人| 在线观看成人免费视频| 亚洲精品无码高潮喷水A片软| 日韩免费福利视频| 大桥未久亚洲无av码在线| 免费观看午夜在线欧差毛片| 狠狠热精品免费观看| 风间由美在线亚洲一区| 国产成人免费手机在线观看视频| 久久无码av亚洲精品色午夜| 全黄性性激高免费视频| 乱淫片免费影院观看| 伊人亚洲综合青草青草久热| 免费无码又爽又刺激高潮软件| 破了亲妺妺的处免费视频国产| 亚洲AV无码片一区二区三区| 四虎亚洲国产成人久久精品| 亚洲一区二区三区四区视频| 欧美最猛性xxxxx免费| 亚洲高清一区二区三区电影| 凹凸精品视频分类国产品免费| 精品国产福利尤物免费| 亚洲av永久无码制服河南实里| 中文字幕亚洲免费无线观看日本| 亚洲一级毛片免费观看| 日本免费高清一本视频| 一级毛片aaaaaa视频免费看| 亚洲AV永久青草无码精品|