ABP+AdminLTE+Bootstrap Table權限管理系統一期
Github:https://github.com/Jimmey-Jiang/ABP-ASP.NET-Boilerplate-Project-CMSjavascript
角色訪問控制(RBAC)應該是目前用得最多也是關注最多的權限管理模型了。
權限(Permission
)與角色(Role
)相關聯,用戶(User
)經過成爲適當角色的成員而獲得這些角色的權限。這就極大地簡化了權限的管理。
RBAC引入了角色(Role
)概念,目的應該是解耦了Permission
與User
之間的關係,直接受權給Role
,而不是直接受權給用戶,或者用戶組。
基於角色的訪問控制方法(RBAC)的顯著的兩大特徵是:html
RBAC認爲權限受權其實是Who、What、How的問題。在RBAC模型中,who、what、how構成了訪問權限三元組,也就是「Who對What(Which)進行How的操做」。前端
assignment(UA)
和Permission assignment(PA)
.關係的左右兩邊都是Many-to-Many關係。就是user能夠有多個role,role能夠包括多個user。Business Modeling With UML
一書Actor-Role模式。考慮到多人能夠有相同權限,RBAC引入了Group的概念。Group一樣也看做是Actor。而User的概念就具象到一我的。首先ABP權限管理也是基於RBAC的。
在 RBAC之中,包含用戶users(USERS)、角色roles(ROLES)、目標objects(OBS)、操做operations(OPS)、許可權permissions(PRMS)五個基本數據元素,權限被賦予角色,而不是用戶,當一個角色被指定給一個用戶時,此用戶就擁有了該角色所包含的權限。會話sessions是用戶與激活的角色集合之間的映射。
而後咱們來看一下一開始就生成的AbpPermissions
表。
java
咱們能夠看到一個權限(AbpPermissions
)有如下屬性:
Name:系統範圍內的惟一名字。把它定義爲一個字符串常量是個不錯的注意。咱們傾向於將「.」分割不一樣的層級,但並不要求這麼作。你能夠設置你任何喜歡的名字。惟一的規則就是這個名字必須是惟一的。git
前面幾篇文章,咱們已經完成了用戶詳情列表的增刪改查。
這裏咱們來給他們加上權限,首先,在module-zero
項目中已經完整實現了。咱們先看下默認已經存在的代碼。github
public class ABPCMSAuthorizationProvider : AuthorizationProvider { public override void SetPermissions(IPermissionDefinitionContext context) { context.CreatePermission(PermissionNames.Pages_Users, L("Users")); context.CreatePermission(PermissionNames.Pages_Roles, L("Roles")); context.CreatePermission(PermissionNames.Pages_Tenants, L("Tenants"), multiTenancySides: MultiTenancySides.Host); } private static ILocalizableString L(string name) { return new LocalizableString(name, ABPCMSConsts.LocalizationSourceName); } }
咱們仿照這段代碼,新建一個類UserInfoAuthorizationProvider
,繼承自AuthorizationProvider
,看下代碼:web
public class UserInfoAuthorizationProvider: AuthorizationProvider { public override void SetPermissions(IPermissionDefinitionContext context) { var pages = context.GetPermissionOrNull(PermissionNames.Pages); if (pages == null) pages = context.CreatePermission(PermissionNames.Pages, L("Pages")); var UserInfos= pages.CreateChildPermission(PermissionNames.Pages_UserInfos, L("UserInfos")); UserInfos.CreateChildPermission(PermissionNames.Pages_UserInfos_Create, L("UserInfosCreate")); UserInfos.CreateChildPermission(PermissionNames.Pages_UserInfos_Delete, L("UserInfosDelete")); UserInfos.CreateChildPermission(PermissionNames.Pages_UserInfos_Update, L("UserInfosUpdate")); } private static ILocalizableString L(string name) { return new LocalizableString(name, ABPCMSConsts.LocalizationSourceName); } }
而後再PermissionNames
中依樣添加以下常量。數據庫
public static class PermissionNames { public const string Pages_Tenants = "Pages.Tenants"; public const string Pages_Users = "Pages.Users"; public const string Pages_Roles = "Pages.Roles"; public const string Pages = "Pages"; public const string Pages_UserInfos = "Pages.UserInfos"; public const string Pages_UserInfos_Create = "Pages.UserInfo.Create"; public const string Pages_UserInfos_Delete = "Pages.UserInfo.Delete"; public const string Pages_UserInfos_Update = "Pages.UserInfo.Update"; }
定位到ABPCMSCoreModule.cs
,這裏已經有關於 Configuration.Authorization.Providers.Add<ABPCMSAuthorizationProvider>();
咱們在他的下面補上咱們本身的類。
Configuration.Authorization.Providers.Add<UserInfoAuthorizationProvider>();
安全
定位到HostRoleAndUserCreator
和TenantRoleAndUserBuilder
類
而後手動在下面添加上以下代碼。session
//Grant all tenant permissions var permissions = PermissionFinder .GetAllPermissions(new ABPCMSAuthorizationProvider()) .Where(p => p.MultiTenancySides.HasFlag(MultiTenancySides.Host)) .ToList();
在這段代碼之下,添加以下代碼。
//將UserInfoAuthorizationProvider相關Permission賦予給Admin var UserInfoAuthorization = PermissionFinder.GetAllPermissions(new UserInfoAuthorizationProvider()).ToList(); permissions.AddRange(UserInfoAuthorization);
有了上面的基礎,咱們先刪除數據庫,在生成數據庫,有人說這裏爲何要刪除數據庫,由於在在ABP模板項目中暫未提供用戶角色權限管理功能,但在AbpZero中提供了該功能,支持按用戶或角色賦予權限,在數據庫初始化的時候,將權限賦給Admin。咱們已經建立了數據庫,因此要刪除數據庫從新初始化。
執行update-database -Verbose命令,因而生成數據庫以下。
有了數據,admin用戶已經賦予了權限,天然不須要咱們去管,可是若是咱們切換用戶進來,就沒有權限,咱們怎麼出給他加上權限呢。
咱們直接在控制方法上添加上標籤[AbpAuthorize(PermissionNames.Pages_UserInfos)]
就能夠了
[AbpAuthorize(PermissionNames.Pages_UserInfos)] [HttpGet] [DontWrapResult] public async Task<ActionResult> GetUserInfo() { string pageNumber = string.IsNullOrWhiteSpace(Request["pageNumber"]) ? "0" : Request["pageNumber"]; string pageSize = string.IsNullOrWhiteSpace(Request["pageSize"]) ? "20" : Request["pageSize"]; var users = (await _userAppService.GetAll(new PagedResultRequestDto { MaxResultCount = int.MaxValue })).Items; var Userlist = users.Skip(int.Parse(pageNumber) * int.Parse(pageSize)).Take(int.Parse(pageSize)).ToList(); int totaldata = Userlist.Count(); var result = new { total = 10, rows = Userlist }; return Json(result, JsonRequestBehavior.AllowGet); }
同時這裏是用區別的。
[AbpAuthorize]
特性,[AbpMvcAuthorize]
特性,[AbpApiAuthorize]
。AbpAuthorize
屬性說明(AbpAuthorize attribute notes)
AbpAuthorize
特性的方法會有些限制。以下:AbpAuthorize
特性能夠應用於任何的Public方法,若是此方法被接口調用(好比在Application Services
中經過接口調用)virtual
)方法,若是此方法是protected
。AbpAuthorize
特性:application layer
),咱們使用Abp.Authorization.AbpAuthorize
;Abp.Web.Mvc.Authorization.AbpMvcAuthorize
;Abp.WebApi.Authorization.AbpApiAuthorize
。AbpAuthorize
適用於大部分的狀況,可是某些狀況下,咱們仍是須要本身在方法體裏進行權限驗證。咱們能夠注入和使用IPermissionChecker
對象。以下邊的代碼所示:public void CreateUser(CreateOrUpdateUserInput input) { if (!PermissionChecker.IsGranted("Administration.UserManagement.CreateUser")) { throw new AbpAuthorizationException("You are not authorized to create user!"); } //A user can not reach this point if he is not granted for "Administration.UserManagement.CreateUser" permission. }
由於受權通常在應用服務層中進行,因此ABP默認在ApplicationService
基類注入並定義了PermissionChecker
屬性。這樣,在應用服務層就能夠直接使用PermissionChecker
屬性進行權限檢查。以下面的代碼:
protected override async Task<User> GetEntityByIdAsync(long id) { bool UserInfos = PermissionChecker.IsGranted(PermissionNames.Pages_UserInfos); //若是當前人員沒有權限,則拋出異常 if (!UserInfos) { throw new AbpAuthorizationException("沒有權限!"); } var user = Repository.GetAllIncluding(x => x.Roles).FirstOrDefault(x => x.Id == id); return await Task.FromResult(user); }
@if (IsGranted(PermissionNames.Pages_UserInfos)) { //業務代碼 }
abp.auth.hasPermission('PermissionNames.Pages_UserInfos);
注意:自ABP 0.7.8版本開始,將javascript端的abp.auth.hasPermission改名爲abp.auth.isGranted。hasPermission已通過時了。在新的項目中不要使用abp.auth.hasPermission。
其實ABP module-zero中的權限管理讓人痛苦,若是我要去對AbpPermissions
表等其餘表進行增刪查改的時候,很痛苦,或者給要admin賦值的時候不可能每次都刪數據庫去實現,雖然在abp zero已經實現。我以爲最好的方式是不要module-zero
那套東西,一切都本身去建立一套RBAC。
送上本文源碼:https://github.com/Jimmey-Jiang/ABP-ASP.NET-Boilerplate-Project-CMS。
github地址: https://github.com/Jimmey-Jiang/WY.MVC.RMS
一套完整權限管理系統,codefirst,直接生成數據庫可用。