第二章 基于二进制进行权限管理的理论知识

源代码GitHub:https://github.com/ZhaoRd/Zrd_0001_AuthorityManagement

1.介绍

第一章主要是介绍了这个DEMO的来由和主要使用的技术,这章内容主要是介绍如何通过二进制的位运算进行权限控制的内容。

第一章发布之后,有不少网友、园友反映程序代码运行不起来,很感谢您们的反馈,刚刚进行了代码修复,已经同步到github,感兴趣的朋友可以加我QQ!

2.二进制的位运算以及如何进行权限判断

基于二进制的权限管理,这个内容是我在两年前接触到过的一个知识,在这里重温一下。

2.1位运算

用二进制进行权限管理,那么首先要知道的内容是如何通过位运算来进行权限操作的。权限操作,我个人认为有 授权、取消授权和验证这三个操作。利用二进制的或运算来实现授权操作;利用二进制的先求补、在求与来实现取消授权的操作;利用与运算实现权限的验证操作。

先说明一下二进制的与(&)、或(|)、求补(~)运算:

或(|)运算的内容有:  1|1 =1 、1|0=1  、0|1=1、0|0=0. 通过或运算可以看出,只要有一个数位为1,那么所求结果就为1.

与(&)运算的内容有: 1&1 =1 、1&0=0、0&1=0、0&0=0,通过与运算可以看出,只要有一数为0,那么所求结果就为0.

求补(~)运算的内容有  ~1=0、~0=1,求补运算表面上看起来就是 1和0倒转过来。

2.2 权限内容

我们假设采用8位二进制代表具体的权限集合具体关系如下:

|  下载   |  打印   |  查看   |  审核    |  详细  |  删除  |   编辑  |   创建 |

|     0     |     0     |     0     |     0      |     0    |    0     |      0    |     0    |

如果某位为0,这表示没有改操作权限,如果为1,这表示具有该操作权限,比如: 0000 0001 表示只有创建权限、00100011这表示有创建、编辑、查看着三种操作权限,依次类推。

如果用一个整数来代表一个操作权限的话,那么

创建=1、编辑=2、删除=4、详细=8、审核=16、查看=32、打印=64、下载=128、全部=255(前面所有内容相加)、无=0。

那么数字3(00000011)则表示有创建和编辑的权限,13(00001101)折表示有详细、创建、编辑这三种操作权限。

2.3 授权操作

如果一个功能已经有了 创建和编辑的权限,二进制就是 0000 0011 ,这么现在要添加一个查看(0010 0000)权限,授权之后的权限的二进制就为(0010 0011),通过2.1的内容可知,当

0000 0011

|  0010 0000

-----------------

0010 0011,

这样就通过了或运算添加给原有的权限添加一个新的权限

2.4 取消授权操作

如果一个功能已经有了查看、创建、编辑的权限,二进制就是 0010 0011 ,现在要求要取消编辑的权限,取消授权之后的二进制就是: 0010 0001 ,整个内容看起来就是对编辑位进行求反运算,那么我们先看编辑权限的求补运算的结果:

~ 0000 0010

----------------

1111 1101 ,

那么求补的结果在和原有权限进行和运算

(0010 0011)

& (1111 1101)

-----------------

(0010 0001) ,

这样就得到了取消之后的二进制 0010 0001(17)

2.5 权限判断

现在要判断 0011 1100 这个代表的权限操作中,有没有审核权限(0001 0000),那么我们对这两个权限进行 与运算

(0011 1100)

& (0001 0000)

-------------------------

(0001 0000),

判断有没有创建权限(0000 0001),

(0011 1100)

& (0000 0001)

--------------------------

0000 0000,

也就是说,两个权限进行与运算,如果与运算的结果为0,则表示无该操作,反正,则表示具有该操作。

3.源代码

3.1 权限代码(枚举)

/// <summary>

/// 定义权限.

/// </summary>

[Flags]

public enum PermissionValue

{

/// <summary>

/// The create.

/// </summary>

[EnumDescription("创建")]

Create = 1,

/// <summary>

/// The edit.

/// </summary>

[EnumDescription("编辑")]

Edit = 2,

/// <summary>

/// The delete.

/// </summary>

[EnumDescription("删除")]

Delete = 4,

/// <summary>

/// The detail.

/// </summary>

[EnumDescription("详细")]

Detail = 8,

/// <summary>

/// The audit.

/// </summary>

[EnumDescription("审核")]

Audit = 16,

/// <summary>

/// The lookup.

/// </summary>

[EnumDescription("查看")]

Lookup = 32,

/// <summary>

/// The print.

/// </summary>

[EnumDescription("打印")]

Print = 64,

/// <summary>

/// The download.

/// </summary>

[EnumDescription("下载")]

Download = 128,

/// <summary>

/// The all.

/// </summary>

[EnumDescription("全部")]

All = Create | Edit | Delete | Detail | Audit | Lookup | Print | Download,

/// <summary>

/// The none.

/// </summary>

[EnumDescription("无")]

None = 0

}

  

3.2 权限操作代码

/// <summary>

/// 权限验证.

/// </summary>

/// <param name="toVerification">

/// 需要验证的权限.

/// </param>

/// <param name="functionInRole">

/// 已经存在的权限.

/// </param>

/// <returns>

/// The <see cref="bool"/>.

/// </returns>

public bool VerifyPermission(PermissionValue toVerification,

PermissionValue functionInRole)

{

return (toVerification & functionInRole) != 0;

}

/// <summary>

/// 权限验证.

/// </summary>

/// <param name="functionId">

/// 功能ID.

/// </param>

/// <param name="roleId">

/// 角色ID.

/// </param>

/// <param name="toVerification">

/// The 需要验证的权限.

/// </param>

/// <returns>

/// The <see cref="bool"/>.

/// </returns>

public bool VerifyPermission(Guid functionId,

Guid roleId,PermissionValue toVerification)

{

var spec = Specification<FunctionInRole>.Eval(u => u.Role.ID == roleId && u.Function.ID == functionId);

var isexist = this.functionInRoleRepository.Exists(spec);

// 不存在则表示未授权

if (!isexist)

{

return false;

}

var functionInRole = this.functionInRoleRepository.Find(spec);

return this.VerifyPermission(toVerification,functionInRole.PermissionValue);

}

/// <summary>

/// 增加权限.

/// </summary>

/// <param name="functionId">

/// 功能ID.

/// </param>

/// <param name="roleId">

/// 角色ID.

/// </param>

/// <param name="toAddPermission">

/// 需要添加的权限.

/// </param>

public void AddAuthority(Guid functionId, Guid roleId, PermissionValue toAddPermission)

{

this.GuardAuthorityAgum(functionId,roleId, toAddPermission);

var spec = Specification<FunctionInRole>.Eval(u => u.Role.ID == roleId && u.Function.ID == functionId);

var isexist = this.functionInRoleRepository.Exists(spec);

if (!isexist)

{

// 如果未进行过授权,这进行第一次授权

var role = this.roleRepository.GetByKey(roleId);

var function = this.functionRepository.GetByKey(functionId);

this.functionInRoleRepository.Add(new FunctionInRole()

{

ID = GuidHelper.GenerateGuid(),

Role = role,

Function = function,

PermissionValue = toAddPermission

});

}

else

{

// 如果已经进行过授权,则在原有权限上增加新权限

var functionInRole = this.functionInRoleRepository.Find(spec);

// 或运算实现授权

functionInRole.PermissionValue |= toAddPermission;

this.functionInRoleRepository.Update(functionInRole);

}

// TODO:unitofwork模式

this.functionInRoleRepository.Context.Commit();

}

/// <summary>

/// 删除权限.

/// </summary>

/// <param name="functionId">

/// 功能ID.

/// </param>

/// <param name="roleId">

/// 角色ID.

/// </param>

/// <param name="toRemovePermission">

/// 需要移除的权限.

/// </param>

/// <exception cref="Exception">

/// 未授权

/// </exception>

public void DeleteAuthority(Guid functionId,Guid roleId, PermissionValue toRemovePermission)

{

var spec = Specification<FunctionInRole>.Eval(u => u.Role.ID == roleId

&& u.Function.ID == functionId);

var isexist = this.functionInRoleRepository.Exists(spec);

if (!isexist)

{

throw new Exception("尚未赋予权限");

}

var functionInRole = this.functionInRoleRepository.Find(spec);

// 求补和与运算实现权限移除:value= value&(~toremove)

functionInRole.PermissionValue &= ~toRemovePermission;

this.functionInRoleRepository.Update(functionInRole);

// TODO:应当使用unitofwork模式

// 领域服务是否依赖仓储?

this.functionInRoleRepository.Context.Commit();

}

/// <summary>

/// 检验角色、功能是否存在和功能点是否能够对某种权限进行操作.

/// </summary>

/// <param name="functionId">

/// 功能ID.

/// </param>

/// <param name="roleId">

/// 角色ID.

/// </param>

/// <param name="permissionValue">

/// 待验证权限.

/// </param>

/// <exception cref="Exception">

/// </exception>

private void GuardAuthorityAgum(Guid functionId,

Guid roleId, PermissionValue permissionValue)

{

var functionIsExist = this.functionRepository.Exists(Specification<Function>.Eval(f => f.ID == functionId));

var roleIsExist = this.roleRepository.Exists(Specification<Role>.Eval(u => u.ID == roleId));

if (!functionIsExist || !roleIsExist)

{

throw new Exception("功能或角色不存在,请检查参数信息");

}

var function = this.functionRepository.GetByKey(functionId);

if (!this.VerifyPermission(permissionValue, function.PermissionValue))

{

throw new Exception("该模块功能不具有需要添加的权限,禁止添加");

}

}

  

4. 总结

本章主要是阐述了如何使用二进制的位运算进行权限操作的,包括授权、取消授权、验证这三种操作。通过二进制的或运算可以达到授权的操作,通过求补和与运算,可以实现取消授权的操作,通过与运算,可以实现权限验证的操作。

下一章内容,主要是介绍项目结构,包括如何分层、类库之间的引用关系等内容。

推荐QQ群:

278252889(AngularJS中文社区)

5008599(MVC EF交流群)

134710707(ABP架构设计交流群 )

59557329(c#基地 )

230516560(.NET DDD基地 )

本人联系方式:QQ:351157970

时间: 2024-07-31 14:33:48

第二章 基于二进制进行权限管理的理论知识的相关文章

账号和权限管理(理论知识铺垫)

一.用户账号和组账号概述 二.用户账号和组账号管理 三.查询账号信息 四.查看目录或文件的属性 五.设置目录或文件的权限 六.设置目录或文件的归属 ■Linux基于用户身份对资源访问进行控制●用户帐号超级用户:人为交互的权限最高用户普通用户:普通使用文档.文件的用户程序用户:人为不可使用,专门管理系统的某一个服务(1----499)●组帐号基本组(私有组):伴随用户的创建而自行创建与用户同名.附加组(公共组):自己创建的组.●UID和GIDUID?(User?lDentity,用户标识号):(0

第二章、linux的时间管理

第二章.linux的时间管理 linux系统一般存在两个时间,一个属于linux操作系统的系统时间,系统时间受操作系统影响,可能会出现时间不准确,但另一个真实硬件上的时间,也就是用纽扣电子持续供电的硬件时间,误差是非常小的. 一.如何查看两种不同的时间 查看系统时间: date 例子: [[email protected] ~]# date Thu Jan 21 12:44:21 CST 2016 查看硬件时间: hwclock 或 clock 例子: [[email protected] ~]

Java 线程第三版 第一章Thread导论、 第二章Thread的创建与管理读书笔记

第一章 Thread导论 为何要用Thread ? 非阻塞I/O I/O多路技术 轮询(polling) 信号 警告(Alarm)和定时器(Timer) 独立的任务(Task) 并行算法 第二章 Thread的创建与管理 一.什么是Thread ? Thread是所在主机执行的应用程序任务(task). 只有一个线程的例子: public class Factorial { public static void main(String[] args) { int n = 5; System.ou

基于DDDLite的权限管理OpenAuth.net 1.0版正式发布

距离上一篇OpenAuth.net的文章已经有5个多月了,在这段时间里项目得到了很多朋友的认可,开源中国上面的Star数接近300,于是坚定了我做下去的信心.最近稍微清闲点,正式推出1.0版,并在阿里云上部署了一个在线演示(文章结尾处给出在线演示链接).相比刚开始时的版本,现在整个架构已经稳定,系统功能性,代码可读性维护性都有质的飞跃. 本文主要介绍系统结构及未来一段时间的开发计划. 项目简介 本项目采用经典DDD架构(用沃恩.弗农大神的话,其实这是DDD-Lite)思想进行开发的一套符合国情的

第01章 mySQL用户和权限管理v1

韩立刚老师视频教学网站 http://www.91xueit.com 韩老师QQ458717185 第01章 MySQL用户和权限管理 mySQL权限控制通过两步控制,能不能连接(验证用户身份),能执行什么操作(验证用户权限). 验证用户身份,需要验证,连接mySQL的计算机的IP地址或计算机名称,用户账户和密码.验证过程如下: 管理mySQL用户 查看mySQL用户账户 mySQL用户存储在mysql数据库的user表,该表在mySQL服务启动时自动加载到内存,控制用户的登录. [[email

从零开始——基于角色的权限管理01(补充)

此博文较为详细的介绍从零开始--基于角色的权限管理01文中的两个部分的流程(解释代码). 1) index.jsp中提交跳转action action的login,获取jsp页面传过来的用户名密码和验证码,进行验证 首先到userDao中,执行login方法,判断是否存在这组用户名和密码 接着到roleDao中,执行getRoleNameById以获取角色名 最后,进入main.jsp中 2)在main.jsp中,有一个树的显示,再次进入authServlet中执行menuAction   先后

RBAC基于角色的权限管理模型

一.权限管理模型的必要性: a. 安全性:防止误操作,防止数据泄露,保证信息的安全. b. 数据隔离:保持不同的角色具有不同的权限,只能看到自己权限范围内的数据 二.权限管理模型的发展: a. 传统的权限管理:随着用户数量的增大和用户权限区别的增大,传统的权限管理需要针对每个用户依次管理,成本较高. b. RBAC:Role-Based Access Control 用户-角色-权限,权限与角色相关联,用户与角色相关联,通过对用户赋予相应的角色,再去获取相应的权限,从而实现了用户与权限的解耦,具

第15章 mysql 用户、权限管理

2015-10-24 目录 参考资料 [1] 唐汉明.深入浅出MySQL 数据库开发.优化与管理维护(第2版)[M].北京:人民邮电出版社,2014 [2] Schwartz.高性能MySQL(第3版)[M].北京:电子工业出版社,2013 [3] 范德兰斯.MySQL开发者SQL权威指南 [M].北京:机械工业出版社,2008 [4] Forta.MySQL必知必会 [M].北京:人民邮电出版社,2009 [5] Chapter 6 Security [6] 5.7. MySQL访问权限系统

RBAC 基于角色的权限管理的简单实现

1.什么是权限管理,权限管理就是对后台功能的细分,和对不同工作人员划分不同的工作的管理 RBAC是如何实现的,通过对不同控制器和控制器不同方法的限制,实现的管理. 要实现RBAC需要三张表,一张用户表,一张角色表 ,一张权限表 用户表: id   ******  role_id 角色表 role_id ****** access_ids(记录所有可以访问的权限id) 权限表 access_id    记录所有控制器 或者控制器下的 action 2.如何控制,在控制器的父类 或者控制器的初始化的