不知道的权限模块

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp3
{
class AuthorizeAttributeDemo
{
/*
* 模块的配置
增加权限拦截器,只要类型和方法有AuthorizeAttribute都增加AuthorizationInterceptor

     */
    public static void RegisterIfNeeded(IOnServiceRegisteredContext context)
    {
        if (ShouIdIntercept(context.ImplementationType))
        {
            context.Interceptors.TryAdd<AuthorizationInterceptor>();
        }
    }
    private static bool ShouldIntercept(Type type)
    {
        return type.IdDefined(type(AuthorizeAttribute, true)) || AnyMethodHasAuthorizeAttribute(type);
    }
    /*
     2 PermisstionOptions权限的两个集合,权限的定义IPermissionDefinitionProvider,以及权限的提供者IPermissionValueProvider
    注册PermissionRequireHandler到DI系统里面

     */
    public override void PreConfigureServices(ServiceConfigurationContext context)
    {
        context.Service.OnRegistered(AuthorizeInterceptionRegistrar.RegisterIfNeeded);
        AutoAddDefinitionProviders(context.Services);
    }

    public override void ConfigureService(ServiceConfigurationContext context)
    {
        context.Service.AddAuthorization();
        context.Service.AddSingleton<IAuthorizationHandler, PermissionRequirementHandler>();
        Configure<PermissionOPtions>(options =>
        {
            options.valueProviders.Add<UserPermissionValueProvider>();
            options.ValueProviders.Add<RolePermissionValueProvider>();
            options.ValueProviders.Add<ClientPermissionValueValueProvider>();
        });
    }
    /*
     PermissionDefinition的定义有,名称,父定义Parent,租户端(Tenant,Host,Both),允许providers(指的valueProvider)显示名字
    子权限Children列表List<PermissionDefinition>,客户端属性定义Dictionary<string,object>Properties,WithProperty,WithProviders
    两个方法设置
    2、PermissionGroupDefinition组定义,基本同PermissionDefinition,重点方法GetPermissionsWithChildren,是递归获取所有的PermissionDefinition
    3PermissionDefinitionContext,是组定义字典的Dictionary<string,PermissionGroupDefinition>Groups,及一些方法AddGroup
    GetGroupOrNull方法
    4IPermissionDefinitionManager,有组的定义,也有PermissionDefinition的方法,构造函数遍历Options.DefinitionProviders遍历视线中
    Define方法,填充PermissionDefinitionContext,返回PermissionGroupDefinition的字典

     */
    protected virtual Dictionary<string, PermissionGroupDefinition> CreatePermissionGroupDefinitions() 
    {
        var context = new PermissionDefinitionContext();
        using (var scope = _serviceProvider.CreateScope()) 
        {
           var providers = Options.DefinitionProviders.Select(p=>scope.ServiceProvider.GetRequiredService(p) as IPermissionDefinitionProvider).ToList()
        }
        foreach (var provider in providers)
        {
            provider.Define(context);
        }
        return context.Groups;
    }
    /*
     2权限的提供者IPermissionValueProvider(三个分别是用户、角色和客户端)其主要方法Task<PermissionGrantResult>
    CheckAsync(PermissionValueCheckContext context)返回结果是Undefined,Granted,Prohibited的其中的一个
    其中:PermissionValueCheckContext的上下文要引入PermissionDefinition要鉴权的权限定义以及ClamsPrincipal(用户的信息)
    PermissionValueCheckContext的构建见PermissionChecker类,它是调用PermissionValueProvider来获取是否存在权限
    var context = new PermissionValueCheckContext(permission,claimsPrincipal)
    IPermissionValueProvider的抽象方法PermissionValueProvider,注入IPermissionStore

     */
    public abstract class PermissionValueProvider : IPermissionValueProvider, ISingleDependency //TODO:to transient
    {
      public abstract string name { get; }
        protected IPermissionStore PermissionStore { get; }
        protected PermissionValueProvider(IPermissionStore permissionStore)
        {
            PermissionStore = permissionStore;
        }
        public abstract Task<PermissionGrantResult> CheckAsync(PermissionValueCheckContext context);
    }
    /*
     其一实现方法,用户UserPermissionValueProvider,用户AbpClaimType.UserId,角色AbpClaimTypes.Role,客户端
    AbpClaimTypes.ClientId,同理

     */
    public override async Task<PermissionGrantResult> CheckAsync(PermissionValueCheckContext context)
    {
        var userId = context.Principal?.FindFirst(AbpClaimTypes.UserId)?.Value;
        if (userId == null)
        {
            return PermissionGrantResult.Undefined;
        }
        return await PermissionStore.IsGrantAsync(context.Permission.Name, nameof, userId) ?
            PermissionGrantResult.Granted : PermissionGrantResult.Undefined;
    }
    /*
     二 IPermissionChecker是检查既定的认证信息是否有权限,见构造函数
     */
    public PermissionChecker(
        IOptions<PermissionOptions> options,
        IServiceProvider serviceProvider,
        ICurrentPrincipalAccessor principalAccessor,
        IPermissionDefinitionManager permissionDefinitionManager,
        ICurrentTenant currentTenant
        ) 
    {
        principalAccessor = principalAccessor;
        permissionDefinitionManager = permissionDefinitionManager;
        currentTenant = currentTenant;
        options = options.Value;

        _lazyProviders = new Lazy<List<IPermissionValueProvider>>(
            () => options.ValueProviders.Select(
                c => serviceProvider.GetRequiredService(c) as IPermissionValueProvider
                ).ToList();
        true

    }
    /*
     这是权限判断的方法,遍历IPermissionValueProvider在Options里面ValueProviders字典

     */
    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.GetMuliTenancySide();
        if (!permission.MultiTenancySide.HasFlag(multiTenancySide))
        {
            return false;
        }
        var isGranted = false;
        var context = new PermissionValueCheckContext(permission,claimsPrincipal);
        foreach (var provider in ValueProviders)
        {
            if (context.Permission.Provider.Any()&&!context.Permission.Providers.Contains(provider.Name))
            {
                continue;
            }
        }
        var result = await EncodingProvider.CheckAsync(context);
        if (result = PermissionGrantResult.Granted)
        {
            isGranted = true;
        }
        else if (result == PermissionGrantResult.Prohibited)
        {
            return false;
        }
        return isGranted;
    }
    protected async Task CheckAsync(IAuthorizeData authorizationAttribute)
    {
        if (authorizationAttribute.Policy == null)
        {
            if (!_currentUser.IsAuthenticated&&!_currentClient.IsAuthenticated)
            {
                throw new AbpAuthorizationException("Authorzation failed!User has not loggin in");
            }
        }
        else
        {
            await _authorizationService.CheckAsync(authorizationAttribute.Policy);
        }
    }
        
}
/*
 IMehtodInvocationAuthorizationService,用于拦截器
Asp.net Core的认证和授权,Abp进行集成
基于策略的授权是授权的核心,基于角色的授权和基于Scheme的授权只是一种语法上的边界,最终都会生成授权策略
使用基于策略的授权时,首先要定义授权策略,而授权策略本质上就是对Claims的一系列的断言
每一个Requirement都代表一个授权条件,比如DenyAnonymousAuthorizationRequirement表示禁止匿名用户访问的授权策略
ClaimsAuthorizationReuqirement用于表示判断Cliams中是否包含预期的Claims的授权策略
因此,我们先定义一个代表操作的Requirement

 */
public class PermissionRequirement : IAuthorizationRequirement 
{
  public string PermissionName { get; }
    public PermissionRequirement([NotNull]string permissionName)
    {
     checked.NotNull(permissionName,nameof(permissionName));
        PermissionName = PermissionName;
    }
}
    /*
     每一个Requirement都需要有一个对应的Handler,来完成授权逻辑,可以直接让Requirement实现IAuthorizationHandler接口
    也可以单独定义授权Handler
    我们在实现IAuthorzationHandler接口时,通常是继承自AuthorizationHandler<TRequirement>来实现,它有如下定义
    依赖于_permissionChecker进行验证
     */
    public class PermissionRequirementHandler : AuthorzationHandler<PermissionRequirement>
    {
        private readonly IPermissionChecker _permissionChecker;
        public PermissionRequirementHandler(IPermissionChecker permissionChecker)
        {
            _permissionChecker = permissionChecker;
        }
        protected override async Task HandleRequirementAsync(
            AuthorizationHandlerContext context,
            PermissionRequirement requirement
            ) 
        {
            if (await _permissionChecker.IsGrantedAsync(context.User,requirement.PermissionName))
            {
                context.Succeed(requirement);
            }
        }
    }
    /*
     授权策略具体表现为要给AuthorizationPolicy对象,要判断的用户是否具有针对该资源的某项操作
    AuthorizationPlicyBuilder它提供了一系列创建AuthorizationPolicy的快捷方法
    IAuthorizationPolicyProvider是根据名臣获取到策略对象,默认时限为DefaultAuthorizationPolicyProvider
    从AuthorizationOptions _options里面获取_options.GetPolicy(policyName)
    ABP自定义AbpAuthorizationPolicyProvider,派生DefautAuthorizationPolicyProvider,在GetPolicyAsync方法里从
    IPermissionDefinicationManager得到permissiondefinition的定义,在利用AuthorizationPolicyBuilder创建AuthorizationPolicy
    对象
     */
    public override async Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
    {
        var policy = await base.GetPolicyAsync(policyName);
        if (policy!= null)
        {
            return policy;
        }
        var permission = _permissionDefinitionManager.GetOrNull(policyName);
        if (permission!=null)
        {
            AuthorizationPolicyBuilder(Array.Empty<string>());
            policyBuilder.Requirements.Add(new PermissionRequirement(policyName));
            return policyBuilder.Build();
        }
        return null;
    }
    /*
     权限主要通过调用IAuthorizationService来完成的,而授权策略的本质是提供Requrement,我们完全可以使用他们两个来完成各种灵活的授权方式
    而不用局限于策略,在默认的AuthorizationHandlerProvider中,会从DI系统获取我们注册的所有Handler
    最终调用其HandleAsync方法

     */
    public class DefaultAuthorizationService : IAuthorizationService
    {
        private readonly AuthorizationOptions _options1;
        private readonly IAuthorizationHandlerContextFactory _contextFactory;
        private readonly IAuthorizationHanlerProvider _handlers;
        private readonly IAuthorzationEvaluator _evaluator;
        private readonly IAuthorizationPl authorizationPl;
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值