[Abp vNext 源码分析] - 7. 权限与验证 (6)

与 ClaimsAuthorizationRequirement 不同的是,ABP vNext 并没有将限定条件处理器和限定条件定义放在一起实现,而是分开的,分别构成了 PermissionRequirement 和 PermissionRequirementHandler ,后者在模块配置的时候被注入到 IoC 里面。

PS:

对于 Handler 来说,我们可以编写多个 Handler 注入到 IoC 容器内部,如下代码:

services.AddSingleton<IAuthorizationHandler, BadgeEntryHandler>(); services.AddSingleton<IAuthorizationHandler, HasTemporaryStickerHandler>();

首先看限定条件 PermissionRequirement 的定义,非常简单。

public class PermissionRequirement : IAuthorizationRequirement { public string PermissionName { get; } public PermissionRequirement([NotNull]string permissionName) { Check.NotNull(permissionName, nameof(permissionName)); PermissionName = permissionName; } }

在限定条件内部,我们只用了权限的唯一标识来进行处理,接下来看一下权限处理器。

public class PermissionRequirementHandler : AuthorizationHandler<PermissionRequirement> { // 这里通过权限检查器来确定当前用户是否拥有某个权限。 private readonly IPermissionChecker _permissionChecker; public PermissionRequirementHandler(IPermissionChecker permissionChecker) { _permissionChecker = permissionChecker; } protected override async Task HandleRequirementAsync( AuthorizationHandlerContext context, PermissionRequirement requirement) { // 如果当前用户拥有某个权限,则通过 Contxt.Succeed() 通过授权验证。 if (await _permissionChecker.IsGrantedAsync(context.User, requirement.PermissionName)) { context.Succeed(requirement); } } } 2.2.5 权限检查器

在上面的处理器我们看到了,ABP vNext 是通过权限检查器来校验某个用户是否满足某个授权策略,先看一下 IPermissionChecker 接口的定义,基本都是传入身份证(ClaimsPrincipal)和需要校验的权限进行处理。

public interface IPermissionChecker { Task<bool> IsGrantedAsync([NotNull]string name); Task<bool> IsGrantedAsync([CanBeNull] ClaimsPrincipal claimsPrincipal, [NotNull]string name); }

第一个方法内部就是调用的第二个方法,只不过传递的身份证是通过 ICurrentPrincipalAccessor 拿到的,所以我们的核心还是看第二个方法的实现。

public virtual async Task<bool> IsGrantedAsync(ClaimsPrincipal claimsPrincipal, string name) { Check.NotNull(name, nameof(name)); var permission = PermissionDefinitionManager.Get(name); var multiTenancySide = claimsPrincipal?.GetMultiTenancySide() ?? CurrentTenant.GetMultiTenancySide(); // 检查传入的权限是否允许当前的用户模式(租户/租主)进行访问。 if (!permission.MultiTenancySide.HasFlag(multiTenancySide)) { return false; } var isGranted = false; // 这里是重点哦,这个权限值检测上下文是之前没有说过的东西,说白了就是针对不同维度的权限检测。 // 之前这部分东西是通过权限策略下面的 Requirement 提供的,这里 ABP vNext 将其抽象为 PermissionValueProvider。 var context = new PermissionValueCheckContext(permission, claimsPrincipal); foreach (var provider in PermissionValueProviderManager.ValueProviders) { // 如果指定的权限允许的权限值提供者集合不包含当前的 Provider,则跳过处理。 if (context.Permission.Providers.Any() && !context.Permission.Providers.Contains(provider.Name)) { continue; } // 调用 Provider 的检测方法,传入身份证明和权限定义进行具体校验。 var result = await provider.CheckAsync(context); // 根据返回的结果,判断是否通过了权限校验。 if (result == PermissionGrantResult.Granted) { isGranted = true; } else if (result == PermissionGrantResult.Prohibited) { return false; } } // 返回 true 说明已经授权,返回 false 说明是没有授权的。 return isGranted; } 2.2.6 PermissionValueProvider

在模块配置方法内部,可以看到通过 Configure<PermissionOptions>() 方法添加了三个 PermissionValueProvider ,即 UserPermissionValueProvider、RolePermissionValueProvider、ClientPermissionValueProvider 。在它们的内部实现,都是通过 IPermissionStore 从持久化存储 检查传入的用户是否拥有某个权限

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpzzps.html