这两天在做一个小型管理系统的权限系统,最初考虑了spring security,发现很多地方都不清楚具体实现细节,看文档明显来不及,因为需要两天之内做好。刚好最近看到java eye上面有篇文章,说到可以用类似linux的权限管理的思路,利用二进制每位的0,1分别代表有无权限,按位与得到结果,具体思路看博文:
http://www.dukai168.cn/blog/63.html
具体实现步骤:
(1)数据字典(不是系统运行必须的,但如果没有这个字典,没人看的懂,下次自己要修改的时候也没办法改了)
//访问对象a权限字典
删除 0
修改 1
添加 2
查看 3
//访问对象b的权限字典
删除 4
修改 5
添加 6
查看 7
//访问对象c的权限字典
删除 8
修改 9
添加 10
查看 11
//访问对象d的权限字典
删除 12
修改 13
添加 14
查看 15
(2)权限配置文件(放到system.properties,使用一个单例模式的propertyConfig类读取该属性)
system.properties
...
#user rights(2^3+2^7+2^5=32768),3查看a;7查看未审核b;5修改未审核b;就是10101000
check={"privilege":"168","needcheck":"1","checkflg":"1"}
#2^3+2^11+2^15
test={"privilege":"34824","needcheck":"1","checkflg":"0"}
...
2^3为2的3次方
check是用户名,168是权限,1是需要做权限验证
(3)自定义标签,jsp中打标签的地方,调用验证
a.定义文件privilege.tld
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>1.1</jspversion>
<shortname>privilege</shortname>
<uri>www.***.com</uri>
<tag>
<name>enable</name>
<tagclass>com.***.***.util.privilege.PrivilegeTag </tagclass><!-- 这个类是具体业务处理逻辑 -->
<bodycontent>JSP</bodycontent>
<attribute>
<name>operator</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>privilege</name>
<required>true</required>
</attribute>
</tag>
</taglib>
b.web.xml配置加载
<!-- self defined tags -->
<jsp-config>
<taglib>
<taglib-uri>/WEB-INF/privilege</taglib-uri>
<taglib-location>/WEB-INF/privilege.tld</taglib-location>
</taglib>
</jsp-config>
c.页面引入和使用
头部引入标签库
<%@ taglib uri="/WEB-INF/privilege" prefix="privilege"%>
具体标签使用
<privilege:enable operator="${operator}" privilege="7">
<a href="chan_list_item.action?check=1&listType=0&channelId=${channelId }" <c:if test="${listType == 0}"> class="on"</c:if>>编辑推荐</a>
</privilege:enable>
d.标签处理类
package com.**.**.util.privilege;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import com.**.**.util.PropertyConfig;
public class PrivilegeTag extends TagSupport {
private static final long serialVersionUID = -532517444654109642L;
private String operator; //对应Attribute,加上set方法。
private int privilege;
public void setOperator(String operator) {
this.operator = operator;
}
public void setPrivilege(int privilege){
this.privilege = privilege;
}
public int doStartTag() throws JspException {
JSONObject property = getProperty(operator);
if (property != null && Integer.parseInt((String)property.get("checkflg"))== 1) {
if(checkRights(Integer.parseInt((String)property.get("privilege")),privilege))
return EVAL_PAGE;
else
return SKIP_BODY;//跳过body,body部分不会显示
}
return EVAL_PAGE;
}
//解析权限
//userPurview是用户具有的总权限
//optPurview是一个操作要求的权限为一个整数(没有经过权的!)
public static boolean checkRights(int userPurview, int optPurview) {
int purviewValue = (int) Math.pow(2, optPurview);
return (userPurview & purviewValue) == purviewValue;
}
public JSONObject getProperty(String user){
String privilegestr = PropertyConfig.getInstance().getString(user, null);
JSONObject JSONObject = null;
if(privilegestr!=null && !"".equals(privilegestr))
JSONObject = (JSONObject) JSONValue.parse(privilegestr);
return JSONObject;
}
}
还有很多需要改进的地方,这个是初版,仅仅是验证了可以实现最基本的功能