二进制权限控制(二)
标签(空格分隔): 未分类
1、权限值的设定
用二进制来表示权限值应该是按位来设置,每个位占一个,表示一种权限或一个菜单,如:
0000000 1 表示拥有菜单编号为1的权限
000000 1 0 表示拥有菜单编号为2的权限
……
如张三拥有权限11(00001011),表示张三可以访问菜单编号为4、2、1的菜单。2.权限的赋予(或操作):
如果张三的权限为11(00001011),现在要给他赋于菜单编号为3(00000100=4,从右往左数第三位为1)的权限,则进行‘或’操作,即:11 | 4 = 00001011 | 00000100 = 00001111 = 153.权限的回收(权限取反后“与”操作)
如要回收菜单编号为2(00000010)的权限,先对菜单权限取反:~2 = 11111101
与原来的权限进行“与”操作:00001111 & 11111101 = 00001101 = 13,即回收了张三菜单2的访问权限。
CREATE TABLE StatRole(
RoleID INT,
RoleName VARCHAR(100), --角色名称
MenuRights LVARCHAR(1000) DEFAULT '0', --菜单权限
ARights LVARCHAR(1000) DEFAULT '0', --添加权限
DRights LVARCHAR(1000) DEFAULT '0', --删除权限
ERights LVARCHAR(1000) DEFAULT '0', --修改权限
QRights LVARCHAR(1000) DEFAULT '0', --查询权限
XRights LVARCHAR(1000) DEFAULT '0', --备用权限x
YRights LVARCHAR(1000) DEFAULT '0', --备用权限y
ZRights LVARCHAR(1000) DEFAULT '0', --备用权限z
ModifyTime CHAR(19)
);
CREATE TABLE StatMenu(
MenuID INT,
PID INT,
MenuType SMALLINT,
MenuUrl CHAR(100),
MenuName CHAR(100),
ModifyTime CHAR(19)
);
CREATE TABLE StatUser(
UserName VARCHAR(10),
UserCName VARCHAR(100),
Password CHAR(32),
ComCode CHAR(8),
Roles LVARCHAR(1000),
ModifyTime CHAR(19)
);
package com.sinosoft.auth;
import java.math.BigInteger;
import java.util.List;
import javax.annotation.Resource;
import org.junit.Test;
import com.sinosoft.BaseTest;
import com.sinosoft.dao.DaoSupport;
public class TestAuth extends BaseTest{
@Resource DaoSupport dao;
@Test
public void test() throws Exception {
auth("1", "3", false, true, true, true);
check("zhangsan");
revoke("1", "1", false, false, false, false);
check("zhangsan");
}
private void check(String userID) throws Exception{
List<StatMenu> list = (List<StatMenu>) dao.findForList("StatDTest.listMenu", null);
StatUser user = (StatUser) dao.findForObject("StatDTest.getUser", userID);
for(StatMenu menu : list){
StatMenu menu2 = getMenu(user.getRoles(), menu.getMenuID());
System.out.println("用户["+userID + "]"+(menu2.isAdd()?"有":"没有")+"[" + menu2.getMenuName() + "]的\"添加\"添加权限");
System.out.println("用户["+userID + "]"+(menu2.isDel()?"有":"没有")+"[" + menu2.getMenuName() + "]的\"删除\"添加权限");
System.out.println("用户["+userID + "]"+(menu2.isEdit()?"有":"没有")+"[" + menu2.getMenuName() + "]的\"修改\"添加权限");
System.out.println("用户["+userID + "]"+(menu2.isQuery()?"有":"没有")+"[" + menu2.getMenuName() + "]的\"查询\"添加权限");
}
}
public void auth(String roleID, String menuID, boolean ... op) throws Exception {
StatRole role = (StatRole) dao.findForObject("StatDTest.getRole", roleID);
BigInteger menu = new BigInteger("0").setBit(Integer.parseInt(menuID));
//赋操作权限
if(op[0]){
BigInteger aRights = new BigInteger(role.getaRights(), 32).or(menu);
role.setaRights(aRights.toString(32));
}
if(op[1]){
BigInteger dRights = new BigInteger(role.getdRights(), 32).or(menu);
role.setdRights(dRights.toString(32));
}
if(op[2]){
BigInteger eRights = new BigInteger(role.geteRights(), 32).or(menu);
role.seteRights(eRights.toString(32));
}
if(op[3]){
BigInteger qRights = new BigInteger(role.getqRights(), 32).or(menu);
role.setqRights(qRights.toString(32));
}
//赋菜单权限,进行“或”操作,如: 1 | 2 = 3, 00000001 | 00000010 = 00000011
BigInteger menuRights = new BigInteger(role.getMenuRights(), 32).or(menu);
role.setMenuRights(menuRights.toString(32));
dao.update("StatDTest.updateRole", role);
}
public void revoke(String roleID, String menuID, boolean ... op) throws Exception {
StatRole role = (StatRole) dao.findForObject("StatDTest.getRole", roleID);
BigInteger menu = new BigInteger("0").setBit(Integer.parseInt(menuID)).not();
//赋操作权限
if(!op[0]){
BigInteger aRights = new BigInteger(role.getaRights(), 32).and(menu);
role.setaRights(aRights.toString(32));
}
if(!op[1]){
BigInteger dRights = new BigInteger(role.getdRights(), 32).and(menu);
role.setdRights(dRights.toString(32));
}
if(!op[2]){
BigInteger eRights = new BigInteger(role.geteRights(), 32).and(menu);
role.seteRights(eRights.toString(32));
}
if(!op[3]){
BigInteger qRights = new BigInteger(role.getqRights(), 32).and(menu);
role.setqRights(qRights.toString(32));
}
//回收菜单菜单权限,取反后进行“与”操作,如: 3 & (~1) = 2, 00000011 & 11111110 = 00000010
BigInteger menuRights = new BigInteger(role.getMenuRights(), 32).and(menu);
role.setMenuRights(menuRights.toString(32));
dao.update("StatDTest.updateRole", role);
}
private StatMenu getMenu(String roleId, String menuID) throws Exception{
StatMenu menu = (StatMenu) dao.findForObject("StatDTest.getMenu", menuID);
BigInteger bi = new BigInteger("0");
BigInteger need = bi.setBit(Integer.parseInt(menu.getMenuID()));
StatRole role = (StatRole) dao.findForObject("StatDTest.getRole", roleId);
BigInteger menuRights = new BigInteger(role.getMenuRights(),32);
BigInteger needMenu = need.and(menuRights);
BigInteger aRights = new BigInteger(role.getaRights(), 32);
BigInteger dRights = new BigInteger(role.getdRights(), 32);
BigInteger eRights = new BigInteger(role.geteRights(), 32);
BigInteger qRights = new BigInteger(role.getqRights(), 32);
menu.setAdd(needMenu.and(aRights).intValue() != 0);
menu.setDel(needMenu.and(dRights).intValue() != 0);
menu.setEdit(needMenu.and(eRights).intValue() != 0);
menu.setQuery(needMenu.and(qRights).intValue() != 0);
return menu;
}
}
本文深入探讨了二进制权限控制的概念,通过二进制位设定来表示不同的权限,例如00000001表示拥有第1个菜单权限。接着介绍了如何赋予和回收权限,如通过按位或操作添加权限,使用按位取反和与操作回收权限。以张三为例,解释了如何动态管理他的权限,如赋予他访问菜单3的权限。
&spm=1001.2101.3001.5002&articleId=46633473&d=1&t=3&u=43efc07a202c434ab241bae385bf4558)
7万+

被折叠的 条评论
为什么被折叠?



