大、小項目都要設(shè)計權(quán)限,都想設(shè)計一個通用的權(quán)限,把權(quán)限做的比較復(fù)雜,現(xiàn)在了解了ABP的設(shè)計思路,覺得設(shè)計很簡單,但實現(xiàn)方法與思路耐人尋味。
本篇只介紹AbpPermissions的數(shù)據(jù)庫設(shè)計,其它表結(jié)構(gòu)參考源代碼即可[Name(資源文件唯一Id)]、[IsGranted(是否授權(quán))]、[RoleId、UserId(授權(quán)于角色或用戶)]
ABP所有常量數(shù)據(jù),都是程序啟動時通過AbpKernelModule一次性加載完成,用的時候直接從內(nèi)存中讀取即可
public override void PostInitialize() { RegisterMissingComponents(); IocManager.Resolve<LocalizationManager>().Initialize(); //初始化資源文件 IocManager.Resolve<NavigationManager>().Initialize(); //初始化導(dǎo)航權(quán)限 IocManager.Resolve<PermissionManager>().Initialize(); //初始化操作權(quán)限 IocManager.Resolve<SettingDefinitionManager>().Initialize(); }權(quán)限分為前臺權(quán)限判斷和后臺權(quán)限判斷兩種情況JS判斷權(quán)限是通過引用<script src="~/AbpScripts/GetScripts" type="text/javascript"></script> 這個腳本,把相關(guān)JS對象與方法加載到JS文件

上圖中有兩個紅框,是后臺構(gòu)建的兩個導(dǎo)航,MainMenu是系統(tǒng)默認(rèn)的屬性,Test是自定義屬性,如下代碼

public class ModuleZeroSamplePRojectNavigationProvider : NavigationProvider { public override void SetNavigation(INavigationProviderContext context) { SetNavigation1(context); SetTestNavigation(context); } private void SetNavigation1(INavigationProviderContext context) { context.Manager.MainMenu //默認(rèn)導(dǎo)航屬性 .AddItem( new MenuItemDefinition( "Questions", new LocalizableString("Questions", ModuleZeroSampleProjectConsts.LocalizationSourceName), url: "#/questions", icon: "fa fa-question", requiredPermissionName: "Questions" //根據(jù)變量進(jìn)行權(quán)限判斷 ) ).AddItem( new MenuItemDefinition( "Users", new LocalizableString("Users", ModuleZeroSampleProjectConsts.LocalizationSourceName), url: "#/users", icon: "fa fa-users" ) ); } public const string TestName = "Test"; //自定義導(dǎo)航屬性 private void SetTestNavigation(INavigationProviderContext context) { var testMenu = new MenuDefinition(TestName, new FixedLocalizableString("Frontend menu")); context.Manager.Menus[TestName] = testMenu; testMenu .AddItem( new MenuItemDefinition( "Questions", new LocalizableString("Questions", ModuleZeroSampleProjectConsts.LocalizationSourceName), url: "#/questions", icon: "fa fa-question" ) ).AddItem( new MenuItemDefinition( "Users", new LocalizableString("Users", ModuleZeroSampleProjectConsts.LocalizationSourceName), url: "#/users", icon: "fa fa-users" ) ); } }View Code
JS代碼是通過NavigationScriptManager 類的GetScriptAsync()進(jìn)行加載與權(quán)限進(jìn)行判斷,獲取導(dǎo)航數(shù)據(jù)通過abp.nav.menus.MainMenu

public async Task<IReadOnlyList<UserMenu>> GetMenusAsync(long? userId) //根據(jù)當(dāng)前用戶加載相關(guān)導(dǎo)航 { var userMenus = new List<UserMenu>(); foreach (var menu in _navigationManager.Menus.Values) // 默認(rèn)初始化的所有 導(dǎo)航屬性 { userMenus.Add(await GetMenuAsync(menu.Name, userId)); } return userMenus; } private async Task<int> FillUserMenuItems(long? userId, IList<MenuItemDefinition> menuItemDefinitions, IList<UserMenuItem> userMenuItems) { var addedMenuItemCount = 0; foreach (var menuItemDefinition in menuItemDefinitions) { if (menuItemDefinition.RequiresAuthentication && !userId.HasValue) { continue; } if (!string.IsNullOrEmpty(menuItemDefinition.RequiredPermissionName) && (!userId.HasValue || !(await PermissionChecker.IsGrantedAsync(userId.Value, menuItemDefinition.RequiredPermissionName)))) //根據(jù)當(dāng)前用戶Id和權(quán)限判斷當(dāng)前用戶是否有導(dǎo)航權(quán)限 { continue; } var userMenuItem = new UserMenuItem(menuItemDefinition); if (menuItemDefinition.IsLeaf || (await FillUserMenuItems(userId, menuItemDefinition.Items, userMenuItem.Items)) > 0) //遞歸加載層級導(dǎo)航 { userMenuItems.Add(userMenuItem); ++addedMenuItemCount; } } return addedMenuItemCount; }View Codeabp.js 定義了很多方法與屬性,用戶判斷權(quán)限的是abp.auth.haspermission(),該方法的參數(shù)是 后臺Action對應(yīng)的操作權(quán)限,如果該方法返回值為True,則說明當(dāng)前用戶被授予了權(quán)限。
前臺JS通過AuthorizationScriptManager 類的 GetScript 方法 加載所有權(quán)限及當(dāng)前用戶的權(quán)限

public async Task<string> GetScriptAsync() { var allPermissionNames = _permissionManager.GetAllPermissions(false).Select(p => p.Name).ToList(); //獲取所有權(quán)限 var grantedPermissionNames = new List<string>(); if (Abpsession.UserId.HasValue) { foreach (var permissionName in allPermissionNames) { if (await PermissionChecker.IsGrantedAsync(AbpSession.UserId.Value, permissionName)) { grantedPermissionNames.Add(permissionName); // 獲取當(dāng)前用戶的權(quán)限 } } } var script = new StringBuilder(); script.AppendLine("(function(){"); script.AppendLine(); script.AppendLine(" abp.auth = abp.auth || {};"); script.AppendLine(); AppendPermissionList(script, "allPermissions", allPermissionNames); script.AppendLine(); AppendPermissionList(script, "grantedPermissions", grantedPermissionNames); script.AppendLine(); script.Append("})();"); return script.ToString(); }View Code權(quán)限初始化定義需集成AuthorizationProvider,如下

public class ModuleZeroSampleProjectAuthorizationProvider : AuthorizationProvider { public override void SetPermissions(IPermissionDefinitionContext context) { //TODO: Localize (Change FixedLocalizableString to LocalizableString) context.CreatePermission("CanCreateQuestions", new Fi
新聞熱點
疑難解答