ACL登陆认证

前篇文章ACL授权实例介绍了授权,授权完成之后,就要进行认证。ACL的认证主要分为登陆认证与即时认证。所谓登录认证就是在用户登陆的时候,进行信息认证。根据用户Id,加载上来该用户所拥有的权限模块;而即时认证指的是用户对某一模块或记录是否有增删改查的权限。

首先来看登录认证。

下面是manager层ACLManager中有关登陆授权的信息。

 

package com.lzq.manager.impl;

/**
 * 认证管理实现
 * @author lzq
 *
 */
public class ACLManager extends AbstractPageManager {
	
	/**
	 * 搜索某个用户拥有读取权限的模块列表(用于登录,形成导航菜单的时候)
	 * @param userId 用户标识
	 * @return 模块列表(即列表的元素是Module对象)
	 */
	public List searchModules(int userId) {
		
		//定义临时变量
		Map temp =new HashMap();
		
		//按优先级从低到高查找用户拥有的角色
		String hql = "select r.id from UsersRoles ur join ur.role r join ur.user u " +
				"where u.id = ? order by ur.orderNo desc";
		List aclIds = getHibernateTemplate().find(hql, userId);
		
		//依次循环角色
		for (Iterator iter = aclIds.iterator(); iter.hasNext();) {
			Integer rid = (Integer) iter.next();
			
			//根据角色获得角色拥有的授权列表
			List acls = findRoleACLs(rid);
			
			//把授权放入临时变量
			for (Iterator iterator = acls.iterator(); iterator.hasNext();) {
				ACL  acl = (ACL ) iterator.next();
				temp.put(acl.getResourceSn(), acl);
			}
		}
		
		//查找直接授予用户的授权列表
		List acls = findUserACLs(userId);
		for (Iterator iter = acls.iterator(); iter.hasNext();) {
			ACL acl = (ACL) iter.next();
			temp.put(acl.getResourceSn(), acl);
		}
		
		//现在已获得用户拥有的所有授权(包括直接授予用户自身以及其包含的角色的授权)
		List delResources = new ArrayList();
		Set entries = temp.entrySet();
		for (Iterator iter = entries.iterator(); iter.hasNext();) {
			Map.Entry entry = (Map.Entry) iter.next();
			ACL acl = (ACL)entry.getValue();
			
			//如果没有读取权限,则需要在临时变量中删除这个授权
			if(acl.getPermission(Permission.READ) == ACL.ACL_NO){
				delResources.add(entry.getKey());
			}
		}
		
		//在临时变量中删除这些需要删除的授权
		for (Iterator iter = delResources.iterator(); iter.hasNext();) {
			Object key = (Object) iter.next();
			temp.remove(key);
		}
		
		//如果授权列表是空的,则返回0长度的集合
		if(temp.isEmpty()){
			return new ArrayList();
		}
		
		//现在已获得用户拥有读取权限的授权
		String searchModules = "select m from Module m where m.id in (:ids)";
		return getSession().createQuery(searchModules)
				.setParameterList("ids", temp.keySet())
				.list();
	}
	
	/**
	 * 根据角色查找角色的授权列表,返回列表的元素是:ACL实例
	 * @param roleId 角色Id
	 * @return
	 */
	private List findRoleACLs(int roleId){
		
		String hql = "select acl from ACL acl where acl.principalType = ? and acl.principalSn = ?";
		return getHibernateTemplate().find(hql, new Object[]{ACL.TYPE_ROLE,roleId});	
	}

	/**
	 * 根据用户查找直接授予用户的授权列表,返回的列表元素是ACL实例。
	 * 注意:如果直接授予用户的授权是继承的话,则不应该包括在这个列表中
	 * @param userId
	 * @return
	 */
	private List findUserACLs(int userId){
		String hql = "select acl from ACL acl where acl.principalType = ? and acl.principalSn = ? and acl.aclTriState = 0";
		return getHibernateTemplate().find(hql, new Object[]{ACL.TYPE_USER,userId});
	}
}	


 

下面是对应的IndexAction,通过当前用户的Id,调用上面的方法,查询上来有权限的模块。

 

package com.lzq.web.actions;

public class IndexAction extends BaseAction {

	private ACLManager aclManager;
	public void setAclManager(ACLManager aclManager) {
		this.aclManager = aclManager;
	}
	public ActionForward outlook(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		//获取当前登陆用户的所有权限
		User user = (User)request.getSession().getAttribute("login");
		List moduleList = aclManager.searchModules(user.getId());
		
		request.setAttribute("moduleList", moduleList);
		
		return mapping.findForward("outlook");
	}
}

 

 

这样,便基本完成了登陆时的认证功能。

 

posted on 2013-10-31 22:07  you Richer  阅读(1194)  评论(0编辑  收藏  举报