ACL授权实例

来源:互联网 发布:淘宝卖家中心页面错乱 编辑:程序博客网 时间:2024/05/16 08:06

上一篇关于ACL的文章中:位运算实现ACL授权与认证过程的原理解析,我们学习了通过位运算实现ACL授权与认证的原理核心,今天我们一起来看授权的实例。

实现的功能很简单:打开授权界面时,加载已授权信息。通过点击授权界面上面的复选框,实现授权与取消授权。


下面是Manager层的实现:

package com.lzq.manager.impl;import java.util.List;import com.lzq.model.ACL;/** * 主体授权管理实现 * @author lzq * */public class ACLManager extends AbstractPageManager {/** * 授权过程 * 添加或更新授权操作 * @param principalType 主体类型  用户或角色 * @param principalSn 主体标识  用户Id或角色Id * @param resourceSn 资源标识  模块Id * @param permission 权限  C/R/U/D 0 1 2 3  * @param yes 是否允许,true表示允许授权;false表示不允许授权 */public void addOrUpdatePermission(String principalType, int principalSn,int resourceSn, int permission, boolean yes) {//根据主体标识和资源标识查找ACL实例ACL acl = findACL(principalType, principalSn, resourceSn);//如果存在ACL实例,则更新其授权if (acl != null) {acl.setPermission(permission, yes);getHibernateTemplate().update(acl);return;}//如果不存在ACL实例,则创建ACL实例acl = new ACL();acl.setPrincipalType(principalType);acl.setPrincipalSn(principalSn);acl.setResourceSn(resourceSn);acl.setPermission(permission, yes);getHibernateTemplate().save(acl);}/** * 删除授权 * @param principalType 主体类型 * @param principalSn 主体标识 * @param resourceSn 资源标识 */public void delPermission(String principalType, int principalSn,int resourceSn) {getHibernateTemplate().delete    (    findACL(principalType, principalSn, resourceSn)            );}/** * 这是在用户授权页面调用的方法 * 设置用户某个资源授权的继承特性 * 添加或更新用户的继承特性 * i.-1继承:这些权限将使用其(即用户)所拥有的角色的权限,而不使用其(即用户)单独设置的权限 * ii.0表示不继承:这些权限将使用其单独设置的权限,而不使用其所拥有的角色的权限 * @param userId 用户标识  * @param sourceSn 资源标识 模块Id * @param yes true表示继承,false表示不继承 */public void addOrUpdateUserExtends(int userId, int sourceSn, boolean yes) {//根据主体标识和资源标识查找ACL实例ACL acl = findACL(ACL.TYPE_USER,userId, sourceSn);//如果存在ACL实例,则更新其授权if (yes) {acl.setExtends(yes);getHibernateTemplate().update(acl);return;}//如果不存在ACL实例,则创建ACL实例acl = new ACL();acl.setPrincipalType(ACL.TYPE_USER);acl.setPrincipalSn(userId);acl.setResourceSn(sourceSn);acl.setExtends(yes);getHibernateTemplate().save(acl);}/** * 根据主体类型、主体标识、资源标识查找ACL实例 * @param principalType * @param principalSn * @param resourceSn * @param permission * @return */private ACL findACL(String principalType, int principalSn,int resourceSn){String strSql ="select acl from ACL acl where acl.principalType = ? and acl.principalSn = ? and acl.resourceSn = ?";ACL acl =(ACL)getSession().createQuery(strSql).setParameter(0, principalType).setParameter(1, principalSn).setParameter(2, resourceSn).uniqueResult();return acl;}/** * 页面加载时,加载所有的授权信息 * @param principalType * @param principalSn * @return */public List searchACLRecord(String principalType, int principalSn) {String sql = "select resourceSn,aclState&1,aclState&2,"+ "aclState&4,aclState&8,aclTriState from T_ACL where "+ "principalType='"+principalType+"' and principalSn="+principalSn;List aclRecord = getSession().createSQLQuery(sql).list();return aclRecord;}}


通过DWR,在jsp页面上面调用Manager层的相应的方法,加载时实现对已授权信息的加载,以及用户对权限的动态控制。

<%@ page language="java" contentType="text/html; charset=GB18030"    pageEncoding="GB18030"%><%@ include file="/common/common.jsp" %><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=GB18030"><c:choose><c:when test="${aclForm.principalType eq 'Role' }"><c:set var="title" value="请给角色【${role.name }】授权" /></c:when><c:otherwise><c:set var="title" value="请给用户【${user.person.name }】授权" /></c:otherwise></c:choose><title>${title }</title><link href="style/oa.css" rel="stylesheet" type="text/css"><script language="javascript" src="script/public.js"></script><script type="text/javascript" src="dwr/engine.js"></script><script type="text/javascript" src="dwr/util.js"></script><script type="text/javascript" src="dwr/interface/aclManager.js"></script><script type="text/javascript">//授权function addOrUpdatePermission(field){//如果被选择上,则同时选择其"不继承"和"启用"checkboxif(field.checked){$(field.resourceSn+"_USE").checked = true;<c:if test="${aclForm.principalType eq 'User' }">$(field.resourceSn+"_EXT").checked = true;</c:if>}aclManager.addOrUpdatePermission("${aclForm.principalType}",${aclForm.principalSn},field.resourceSn,field.permission,field.checked);}//设置用户的继承特性function addOrUpdateUserExtends(field){aclManager.addOrUpdateUserExtends(${aclForm.principalSn},field.resourceSn,!field.checked);}//点击 启用  checkboxfunction usePermission(field){//如果checkbox被选中,意味着需要更新ACL的状态//更新C/R/U/D以及Extends状态//设置为同步状态,以便DWR依次发出下列请求dwr.engine.setAsync(false);if(field.checked){//更新C状态addOrUpdatePermission($(field.resourceSn+"_C"));//更新R状态addOrUpdatePermission($(field.resourceSn+"_R"));//更新U状态addOrUpdatePermission($(field.resourceSn+"_U"));//更新D状态addOrUpdatePermission($(field.resourceSn+"_D"));//更新Extends状态<c:if test="${aclForm.principalType eq 'User' }">addOrUpdateUserExtends($(field.resourceSn+"_EXT"));</c:if>}else{//如果不启用,则删除授权信息aclManager.delPermission("${aclForm.principalType}",${aclForm.principalSn},field.resourceSn);//并且在界面上去掉相应的CRUD选择的选项$(field.resourceSn+"_C").checked = false;$(field.resourceSn+"_R").checked = false;$(field.resourceSn+"_U").checked = false;$(field.resourceSn+"_D").checked = false;<c:if test="${aclForm.principalType eq 'User' }">$(field.resourceSn+"_EXT").checked = false;</c:if>}}//打开界面时,从数据库中加载授权信息function initTable(){aclManager.searchACLRecord("${aclForm.principalType}",${aclForm.principalSn},function(datas){for(var i=0;i<datas.length;i++){var resourceSn =datas[i][0];var cState = datas[i][1];var rState = datas[i][2];var uState = datas[i][3];var dState = datas[i][4];var extState = datas[i][5];$(resourceSn+"_C").checked =cState ==0 ? false : true;$(resourceSn+"_R").checked =rState ==0 ? false : true;$(resourceSn+"_U").checked =uState ==0 ? false : true;$(resourceSn+"_D").checked =dState ==0 ? false : true;//等于0,不继承,就要选择上,所以为true<c:if test="${aclForm.principalType eq 'User' }">$(resourceSn+"_EXT").checked=extState ==0 ? true : false;</c:if>$(resourceSn+"_USE").checked = true;}});}</script></head><body onload="initTable()"><form action="person.do"><TABLE class="tableEdit" border="0" cellspacing="1" cellpadding="0" style="width:580px;"><TBODY><TR><td><table class="tableEdit" style="width:580px;" cellspacing="0" border="0" cellpadding="0"><tr><!-- tdEditContent --><td class="tdEditLabel" >顶级模块</td><td class="tdEditContent">二级模块</td><td class="tdEditLabel">权限</td><c:if test="${aclForm.principalType eq 'User' }"><td class="tdEditLabel">不继承</td></c:if><td class="tdEditLabel">启用</td></tr><!-- 输出模块树 --><c:forEach items="${moduleList }" var="module"><tr><td>${module.name }</td><td>  </td><td><input type="checkbox" id="${module.id }_C" resourceSn="${module.id }" permission="0" onclick="addOrUpdatePermission(this)">C<input type="checkbox" id="${module.id }_R" resourceSn="${module.id }" permission="1" onclick="addOrUpdatePermission(this)">R<input type="checkbox" id="${module.id }_U" resourceSn="${module.id }" permission="2" onclick="addOrUpdatePermission(this)">U<input type="checkbox" id="${module.id }_D" resourceSn="${module.id }" permission="3" onclick="addOrUpdatePermission(this)">D</td><c:if test="${aclForm.principalType eq 'User' }"><td><input type="checkbox"  id="${module.id }_EXT" resourceSn="${module.id }" onclick="addOrUpdateUserExtends(this)"></td></c:if><td><input type="checkbox" id="${module.id }_USE" resourceSn="${module.id }" onclick="usePermission(this)"></td></tr><c:forEach items="${module.children }" var="child"><tr><td>  </td><td>${child.name }</td><td><input type="checkbox" id="${child.id }_C" resourceSn="${child.id }" permission="0" onclick="addOrUpdatePermission(this)">C<input type="checkbox" id="${child.id }_R" resourceSn="${child.id }" permission="1" onclick="addOrUpdatePermission(this)">R<input type="checkbox" id="${child.id }_U" resourceSn="${child.id }" permission="2" onclick="addOrUpdatePermission(this)">U<input type="checkbox" id="${child.id }_D" resourceSn="${child.id }" permission="3" onclick="addOrUpdatePermission(this)">D</td><c:if test="${aclForm.principalType eq 'User' }"><td><input type="checkbox"  id="${child.id }_EXT" resourceSn="${child.id }" onclick="addOrUpdateUserExtends(this)"></td></c:if><td><input type="checkbox" id="${child.id }_USE" onclick="usePermission(this)" resourceSn="${child.id }"></td></tr></c:forEach></c:forEach></table></td></TR></TBODY></TABLE></form></body></html>

下面是通过点击角色授权或者用户授权,进入的授权界面:



这个过程说难不难,说简单也不简单。我认为这个功能的主要亮点有:

1、对多选框的动态控制;

2、巧妙的使用位运算完成授权与认证。