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

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

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

    隨筆 - 13  文章 - 47  trackbacks - 0
    <2006年12月>
    262728293012
    3456789
    10111213141516
    17181920212223
    24252627282930
    31123456

    常用鏈接

    留言簿(4)

    隨筆分類

    隨筆檔案

    收藏夾

    個人博客

    參考文檔

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    轉自:http://www.cublog.cn/u/11905/showart_162625.html

    最近在做項目遇到了權限管理,用戶要求可以自己建立不同的角色對系統的資源進行控制, 不同的用戶有不同的角色,又恰恰框架中用到了struts+spring+hibernate,要求在web層調用 業務邏輯層 時不考慮權限,web層可以控制用戶的顯示界面,邏輯層處理用戶權限問題。
    想來想去好像只有spring 的aop 可以做到,在調用到 接口 中的方法時,首先檢查用戶的權限,如果檢查通過則繼續執行,否則拋出異常。但是新的問題又出現了,如何在邏輯層上來得到當前用戶的id,以致用戶的 角色,總不能每次都要從web中傳來一個 httprequest,或者 session 這類的吧。在網上看了很多資料,發現了acegi,恰好解決了以上的難題,具體的實現原理這里就不多說了,網上有很多相關資料。
    說正題,首先來看看acegi 的官方 example ,我下載的是acegi-security-1.0.0-RC1,解壓縮后可以看到acegi-security-sample-contacts-filter.war,打開配置文件有這樣幾句
    ?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?

    可以看到它是通過讀配置文件來判斷執行某個方法所需要的角色的,再看這幾句
    <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>?
    同樣是將頁面的訪問權限寫死在配置文件中,再來看看它的tag是如何處理的
    <auth:authorize?ifAnyGranted="ROLE_DELETE">?
    ??????????
    <a?href="">刪除</a>?
    </auth:authorize>?
    可見它是要求我們對鏈接或者其他資源的保護時提供 用戶角色,可是既然角色是用戶自己添加的我們又如何來寫死在這里呢?
    還有就是它對用戶驗證默認使用的是jdbc,即 JdbcDaoImpl
    <bean?id="transactionManager"?class="org.springframework.jdbc.datasource.DataSourceTransactionManager">?
    ????????????????
    <property?name="dataSource"><ref?local="dataSource"/></property>?
    ????????
    </bean>?
    而我們希望基于Hibernate的Dao來實現。
    可見僅僅使用現有的acegi 是 無法滿足我們項目開發的需求的。
    解決方法:

    1: 開發基于數據庫的保護資源。

    看過acegi的源代碼就會知道,對保護資源的定義是通過實現ObjectDefinitionSource這個接口來實現的,而且acegi為我們提供了默認實現的抽象類
    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);?
    }
    ?

    我們要做的就是實現它的
    protected abstract ConfigAttributeDefinition lookupAttributes(Method method);方法,
    以下是我的實現方法,大致思路是這樣,通過由抽象類傳來的Method 對象得到
    調用這個方法的 包名,類名,方法名 也就是secureObjectName, 查詢數據庫并將結果映射為Function 也就是secureObject ,由于Function 與 Role 的多對多關系 可以得到 Function所對應的 Roles ,在將role 包裝成GrantedAuthority (也就是acegi中的角色)。其中由于頻繁的對數據庫的查詢 所以使用Ehcache 來作為緩存。
    ??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?提供通過HIbenate對數據庫操作的實現?
    ?28?????????private?IBaseDao?baseDao;?
    ?29?????????//?AuthorityBasedFunctionCache?通過Function?查?Role?時緩存?
    ?30?????????private?AuthorityBasedFunctionCache?cache;?
    ?31?????????//?FunctionByNameCache?由反射到的方法名查找?數據庫對應的Function?時的緩存?
    ?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?為數據庫中保護資源的映射?
    ?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:定義 基于方法的 自定義標志

    通過以上的分析 , 要想使用acegi 做頁面的顯示控制僅僅靠角色(Role)是不行的,因為用戶可能隨時定義出新的角色,所以只能 基于方法(Function)的控制。可是acegi 只是提供了基于 角色的 接口GrantedAuthority ,怎么辦?? ,如法炮制。 首先定義出我們自己的GrantedFunction,實現也雷同 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?

    以下是我的標志實現,大致思路是 根據 頁面 的傳來的 方法名(即 FunctionName)查詢出對應的Functions,并且包裝成grantedFunctions ,然后根據用戶的角色查詢出用戶對應的Functions ,再取這兩個集合的交集,最后再根據這個集合是否為空判斷是否顯示標志體的內容。
    ??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,進而得到?授予用戶的?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)的集合,并且驗證是否合法?
    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??????????????*?處理頁面標志屬性?,用'?,'區分?
    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?用戶已經獲得的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?的項?
    183?????????????????grantedFunction.retainAll(requiredFunction);?
    184?
    185?????????????????return?rolesToAuthorities(grantedFunction,?granted);?
    186?????????????}?
    187?
    188?????????????/**?
    189??????????????*?
    190??????????????*?@param?grantedFunctions?已經被過濾過的Function????????????
    191??????????????*?@param?granted?未被過濾過的,即用戶所擁有的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?
    再說明一下吧,通過 AppContext 獲得了Spring的上下文,以及AuthDao(實際意義上講以不再是單純的Dao,應該是Service)
    package?sample.auth;?

    import?java.util.Collection;?
    public?interface??AuthDao?{?

    ????
    /**?
    ?????*??根據用戶的角色集合?得到?用戶的?操作權限?
    ?????*?
    @param?granted?已授予用戶的角色集合?
    ?????*?
    @return?操作權限的集合?
    ?????
    */
    ?
    ????????
    public?Collection?getFunctionsByRoles(Collection?granted);?
    }
    ?
    以下是AuthDao 的實現

    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的用戶驗證

    acegi 默認的 的 用戶驗證是 通過UserDetailsService 接口 實現的 也就是說我們只要實現了 它的loadUserByUsername 方法。
    1?
    2?public?UserDetails?loadUserByUsername(String?username)?
    3?????????throws?UsernameNotFoundException,?DataAccessException;?
    以下是我的實現
    ??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?==?null)?return?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??????????????????????true,?true,?true,?arrayAuths);?
    ?49?????????}?
    ?50?
    ?51?????????/**?
    ?52?????????*?根據用戶名查找用戶?
    ?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???????????*?根據用戶名查找角色?
    ?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?
    通過以上對acegi 的 處理,足以滿足我們目前在spring下基于RBAC的動態權限管理。同時在對頻繁的數據庫查詢上使用了Ehcache作為緩存,在性能上有了很大的改善。
    posted on 2006-12-03 16:04 西紅柿(tomato) 閱讀(1564) 評論(1)  編輯  收藏 所屬分類: 安全認證相關

    FeedBack:
    # re: Acegi+hibernate 動態實現基于角色的權限管理 2006-12-14 12:18 信天翁
    太好了!  回復  更多評論
      
    主站蜘蛛池模板: 国产成人免费全部网站| 久久午夜无码免费| 国产亚洲精品国产福利在线观看| 亚洲另类视频在线观看| 亚洲福利一区二区精品秒拍| 亚洲精品人成电影网| 亚洲成a人片在线观看播放| 亚洲大片免费观看| 亚洲人成影院午夜网站| 亚洲国产成人在线视频| 亚洲 欧洲 视频 伦小说| 亚洲欧美日韩自偷自拍| 亚洲AV无码男人的天堂| 人妻18毛片a级毛片免费看| 一个人看的www视频免费在线观看 一个人看的免费观看日本视频www | 久热综合在线亚洲精品| 亚洲国产国产综合一区首页| 亚洲美女中文字幕| 亚洲mv国产精品mv日本mv| 亚洲日韩精品A∨片无码加勒比| 色欲aⅴ亚洲情无码AV蜜桃| 一级毛片大全免费播放| 免费一级不卡毛片| 91精品免费国产高清在线| 在线视频免费观看www动漫 | 亚洲免费视频网站| 成人免费毛片观看| 亚洲AV网站在线观看| 亚洲精品无码永久中文字幕| 亚洲精品视频观看| 亚洲国产成人无码AV在线 | 666精品国产精品亚洲| 亚洲人成网站在线观看播放青青| 亚洲AV无码一区二区三区久久精品| 美女视频黄a视频全免费网站一区 美女视频黄a视频全免费网站色 | 亚洲网站在线观看| 亚洲欧美国产国产一区二区三区| 一个人免费观看www视频| 性xxxxx大片免费视频| 成年女人免费视频播放体验区| 亚洲国产精品日韩专区AV|