二进制权限控制(二)

本文深入探讨了二进制权限控制的概念,通过二进制位设定来表示不同的权限,例如00000001表示拥有第1个菜单权限。接着介绍了如何赋予和回收权限,如通过按位或操作添加权限,使用按位取反和与操作回收权限。以张三为例,解释了如何动态管理他的权限,如赋予他访问菜单3的权限。

二进制权限控制(二)

标签(空格分隔): 未分类


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 = 15

3.权限的回收(权限取反后“与”操作)
如要回收菜单编号为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;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值