通過AOP+特性實現
ABP默認的權限驗證過濾器 AbpAuthorizationFilter 可以通過繼承AsyncAuthorizationFilter 自定義自己的權限過濾器
權限數據存放表 [AbpPermissions]
1.設置權限的class需要需要派生自AuthorizationProvider類
public class MyAuthorizationProvider : AuthorizationProvider { public override void SetPermissions(IPermissionDefinitionContext context) { var pages = context.CreatePermission(PermissionNames.Pages_Users, FL("后台頁面")); //物料管理 var product = pages.CreateChildPermission(PermissionNames.Pages_Product, FL("物料管理")); product.CreateChildPermission(PermissionNames.Pages_Product_CreateOrEdit, FL("添加修改物料"));
2.ABP中Application層需要進行權限驗證 在Module中注冊權限
public override void PreInitialize() { Configuration.Authorization.Providers.Add<MyAuthorizationProvider>(); }
3.在接口或方法上添加權限
所有權限都保存在 PermissionDictionary Permissions對象中 這個PermissionDictionary類型繼承Dictionary<string, Permission>
權限就是一份存在內存中的數據字典
protected readonly PermissionDictionary Permissions;
權限對象(Permission):用於定義一個Permission,一個permission可以包含多個子Permission.
public class Permission { /// <summary> /// Parent of this permission if one exists. /// If set, this permission can be granted only if parent is granted. /// </summary> public Permission Parent { get; private set; } /// <summary> /// List of child permissions. A child permission can be granted only if parent is granted. /// </summary> public IReadOnlyList<Permission> Children => _children.ToImmutableList(); private readonly List<Permission> _children;
驗證權限的過程
找到當前請求需要執行的方法 找到當前方法繼承權限的特性和當前方法所在的類繼承的權限的特性
如果都不存在 直接通過
如果存在 循環存在的所有權限特性中的權限
去獲取當前用戶的權限 跟當前需要的權限進行匹配 全部匹配 就通過
可以自己注入 這個對象來檢查權限
//檢查是否存在當前的權限
public virtual async Task<bool> IsGrantedAsync(string permissionName) { return AbpSession.UserId.HasValue && await _userManager.IsGrantedAsync(AbpSession.UserId.Value, permissionName); } public virtual async Task<bool> IsGrantedAsync(long userId, string permissionName) { return await _userManager.IsGrantedAsync(userId, permissionName); }
//獲取當前用戶的所有權限
private async Task<UserPermissionCacheItem> GetUserPermissionCacheItemAsync(long userId) { var cacheKey = userId + "@" + (GetCurrentTenantId() ?? 0); return await _cacheManager.GetUserPermissionCache().GetAsync(cacheKey, async () => { var user = await FindByIdAsync(userId); if (user == null) { return null; } var newCacheItem = new UserPermissionCacheItem(userId); foreach (var roleName in await GetRolesAsync(userId)) { newCacheItem.RoleIds.Add((await RoleManager.GetRoleByNameAsync(roleName)).Id); } foreach (var permissionInfo in await UserPermissionStore.GetPermissionsAsync(userId)) { //當前權限是否授予 if (permissionInfo.IsGranted) { //授予的權限 newCacheItem.GrantedPermissions.Add(permissionInfo.Name); } else { //禁止的權限 newCacheItem.ProhibitedPermissions.Add(permissionInfo.Name); } } //當前用戶的所有權限 return newCacheItem; }); }
//檢查是否有權限
//檢查當前方法的權限是否在該用戶的授予權限中 if (cacheItem.GrantedPermissions.Contains(permission.Name)) { return true; } //禁止權限 if (cacheItem.ProhibitedPermissions.Contains(permission.Name)) { return false; }