源代碼GitHub:https://github.com/ZhaoRd/Zrd_0001_AuthorityManagementgit
第一章主要是介紹了這個DEMO的來由和主要使用的技術,這章內容主要是介紹如何經過二進制的位運算進行權限控制的內容。github
第一章發佈以後,有很多網友、園友反映程序代碼運行不起來,很感謝您們的反饋,剛剛進行了代碼修復,已經同步到github,感興趣的朋友能夠加我QQ!c#
基於二進制的權限管理,這個內容是我在兩年前接觸到過的一個知識,在這裏重溫一下。架構
用二進制進行權限管理,那麼首先要知道的內容是如何經過位運算來進行權限操做的。權限操做,我我的認爲有 受權、取消受權和驗證這三個操做。利用二進制的或運算來實現受權操做;利用二進制的先求補、在求與來實現取消受權的操做;利用與運算實現權限的驗證操做。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
咱們假設採用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)折表示有詳細、建立、編輯這三種操做權限。
若是一個功能已經有了 建立和編輯的權限,二進制就是 0000 0011 ,這麼如今要添加一個查看(0010 0000)權限,受權以後的權限的二進制就爲(0010 0011),經過2.1的內容可知,當
0000 0011
| 0010 0000
-----------------
0010 0011,
這樣就經過了或運算添加給原有的權限添加一個新的權限
若是一個功能已經有了查看、建立、編輯的權限,二進制就是 0010 0011 ,如今要求要取消編輯的權限,取消受權以後的二進制就是: 0010 0001 ,整個內容看起來就是對編輯位進行求反運算,那麼咱們先看編輯權限的求補運算的結果:
~ 0000 0010
----------------
1111 1101 ,
那麼求補的結果在和原有權限進行和運算
(0010 0011)
& (1111 1101)
-----------------
(0010 0001) ,
這樣就獲得了取消以後的二進制 0010 0001(17)
如今要判斷 0011 1100 這個表明的權限操做中,有沒有審覈權限(0001 0000),那麼咱們對這兩個權限進行 與運算
(0011 1100)
& (0001 0000)
-------------------------
(0001 0000),
判斷有沒有建立權限(0000 0001),
(0011 1100)
& (0000 0001)
--------------------------
0000 0000,
也就是說,兩個權限進行與運算,若是與運算的結果爲0,則表示無該操做,反正,則表示具備該操做。
/// <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 }
/// <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("該模塊功能不具備須要添加的權限,禁止添加"); } }
本章主要是闡述瞭如何使用二進制的位運算進行權限操做的,包括受權、取消受權、驗證這三種操做。經過二進制的或運算能夠達到受權的操做,經過求補和與運算,能夠實現取消受權的操做,經過與運算,能夠實現權限驗證的操做。
下一章內容,主要是介紹項目結構,包括如何分層、類庫之間的引用關係等內容。
推薦QQ羣:
278252889(AngularJS中文社區)
5008599(MVC EF交流羣)
134710707(ABP架構設計交流羣 )
59557329(c#基地 )
230516560(.NET DDD基地 )
本人聯繫方式:QQ:351157970