第二章 基於二進制進行權限管理的理論知識

源代碼GitHub:https://github.com/ZhaoRd/Zrd_0001_AuthorityManagementgit

1.介紹

      第一章主要是介紹了這個DEMO的來由和主要使用的技術,這章內容主要是介紹如何經過二進制的位運算進行權限控制的內容。github

      第一章發佈以後,有很多網友、園友反映程序代碼運行不起來,很感謝您們的反饋,剛剛進行了代碼修復,已經同步到github,感興趣的朋友能夠加我QQ!c#

 

2.二進制的位運算以及如何進行權限判斷

      基於二進制的權限管理,這個內容是我在兩年前接觸到過的一個知識,在這裏重溫一下。架構

      2.1位運算

            用二進制進行權限管理,那麼首先要知道的內容是如何經過位運算來進行權限操做的。權限操做,我我的認爲有 受權、取消受權和驗證這三個操做。利用二進制的或運算來實現受權操做;利用二進制的先求補、在求與來實現取消受權的操做;利用與運算實現權限的驗證操做。ui

       先說明一下二進制的與(&)、或(|)、求補(~)運算:     this

       或(|)運算的內容有:  1|1 =1 、1|0=1  、0|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倒轉過來。blog

       2.2 權限內容

       咱們假設採用8位二進制表明具體的權限集合具體關係以下:ip

      |  下載   |  打印   |  查看   |  審覈    |  詳細  |  刪除  |   編輯  |   建立 |

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

      若是某位爲0,這表示沒有改操做權限,若是爲1,這表示具備該操做權限,好比: 0000 0001 表示只有建立權限、00100011這表示有建立、編輯、查看着三種操做權限,依次類推。

       若是用一個整數來表明一個操做權限的話,那麼

       建立=一、編輯=二、刪除=四、詳細=八、審覈=1六、查看=3二、打印=6四、下載=12八、所有=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

相關文章
相關標籤/搜索