`
guojingxf
  • 浏览: 66003 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Acegi+hibernate 动态实现基于角色的权限管理

阅读更多



    最近在做项目遇到了权限管理,用户要求可以自己建立不同的角色对系统的资源进行控制, 不同的用户有不同的角色,又恰恰框架中用到了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作为缓存,在性能上有了很大的改善。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics