zoukankan      html  css  js  c++  java
  • abp vnext 中多权限满足其中一个即可调用的功能实现

    主要参考了微软官方 IAuthorizationPolicyProvider 的自定义授权策略的方式,创建的权限模块。(https://docs.microsoft.com/zh-cn/aspnet/core/security/authorization/iauthorizationpolicyprovider?view=aspnetcore-3.1) 

    模块包含代码:

     

     AuthorizationModule.cs 代码:

    using Microsoft.Extensions.DependencyInjection;
    using System;
    using Microsoft.AspNetCore.Authorization;
    using Volo.Abp.Modularity;
    
    namespace WebSystem.Authorization
    {
        public class AuthorizationModule : AbpModule
        {
            public override void ConfigureServices(ServiceConfigurationContext context)
            {
                context.Services.AddSingleton<IAuthorizationPolicyProvider, WebPolicyProvider>();
                context.Services.AddSingleton<IAuthorizationHandler, WebAuthorizationHandler>();
               
            }
        }
    }

    IWebPermissionCheck.cs 代码:

    using System;
    using System.Collections.Generic;
    using System.Security.Claims;
    using System.Text;
    
    namespace WebSystem.Authorization
    {
      public  interface IWebPermissionCheck
      {
           bool IsGranted(string[] needPermissions, ClaimsPrincipal user);
      }
    }

    NullWebPermissionChecker.cs 代码:

    using System;
    using System.Collections.Generic;
    using System.Security.Claims;
    using System.Text;
    using Volo.Abp.DependencyInjection;
    
    namespace WebSystem.Authorization
    {
        [Dependency(TryRegister = true)]
        public class NullWebPermissionChecker : IWebPermissionCheck, ITransientDependency
        {
         
            public bool IsGranted(string[] needPermissions, ClaimsPrincipal user)
            {
                return true;
            }
        }
    }

    WebAuthorizationHandler.cs 代码:

    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Linq;
    using System.Security.Claims;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.Extensions.Logging;
    using Volo.Abp.DependencyInjection;
    
    namespace WebSystem.Authorization
    {
        public class WebAuthorizationHandler : AuthorizationHandler<WebRequirement>
        {
            private readonly ILogger<WebAuthorizationHandler> _logger;
            protected readonly IWebPermissionCheck _webPermissionCheck;
    
            public WebAuthorizationHandler(ILogger<WebAuthorizationHandler> logger, IWebPermissionCheck webPermissionCheck)
            {
                _logger = logger;
                _webPermissionCheck = webPermissionCheck;
            }
    
            // Check whether a given MinimumAgeRequirement is satisfied or not for a particular context
            protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, WebRequirement requirement)
            {
                if (_webPermissionCheck.IsGranted(requirement.Permissions, context.User))
                {
                    context.Succeed(requirement);
                }
                else
                {
                    _logger.LogInformation("No Permissions");
                }
    
                return Task.CompletedTask;
            }
        }
    }

    WebAuthorizeAttribute.cs 代码:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text.RegularExpressions;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Authorization;
    
    namespace WebSystem.Authorization
    {
    
        public static class WebAutjorizeExtend
        {
            public static string[] GetPermissions(string currencyValue)
            {
                string pattern = @"[(?<content>.*?)]";
    
    
                var text = Regex.Match(currencyValue, pattern).Groups["content"].Value;
    
                return text.Split(",", StringSplitOptions.RemoveEmptyEntries).ToArray();
    
            }
        }
    
        public class WebAuthorizeAttribute : AuthorizeAttribute
        {
           
            const string POLICY_PREFIX = "NeedPermissions:[0]";
    
            public WebAuthorizeAttribute(params string[] permissions) => Permissions = permissions;
    
            // Get or set the Age property by manipulating the underlying Policy property
            public string[] Permissions
            {
                get
                {
                    var permissions = WebAutjorizeExtend.GetPermissions(Policy);
                    return permissions;
    
                }
                set
                {
                    Policy = POLICY_PREFIX.Replace("[0]", $"[{string.Join(',', value)}]");
                }
            }
        }
    }

    WebPolicyProvider.cs 代码:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.Extensions.Options;
    using Volo.Abp.DependencyInjection;
    
    namespace WebSystem.Authorization
    {
        public class WebPolicyProvider : IAuthorizationPolicyProvider
        {
            const string POLICY_PREFIX = "NeedPermissions:";
            public DefaultAuthorizationPolicyProvider FallbackPolicyProvider { get; }
    
            public WebPolicyProvider(IOptions<AuthorizationOptions> options)
            {
    
                FallbackPolicyProvider = new DefaultAuthorizationPolicyProvider(options);
            }
    
            public Task<AuthorizationPolicy> GetDefaultPolicyAsync() => FallbackPolicyProvider.GetDefaultPolicyAsync();
    
            public Task<AuthorizationPolicy> GetFallbackPolicyAsync() => FallbackPolicyProvider.GetFallbackPolicyAsync();
    
    
            public Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
            {
                if (policyName.StartsWith(POLICY_PREFIX, StringComparison.OrdinalIgnoreCase))
                {
                    var permissionsArray = WebAutjorizeExtend.GetPermissions(policyName);
                    if (permissionsArray.Length > 0)
                    {
                        var policy = new AuthorizationPolicyBuilder();
                        policy.AddRequirements(new WebRequirement(permissionsArray));
                        return Task.FromResult(policy.Build());
                    }
                }
                return FallbackPolicyProvider.GetPolicyAsync(policyName);
            }
        }
    }

    WebRequirement.cs 代码:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Authorization;
    
    namespace WebSystem.Authorization
    {
        public class WebRequirement: IAuthorizationRequirement
        {
           public string[] Permissions { get; private set; }
    
            public WebRequirement(params string[] permissions) { Permissions = permissions; }
        }
    }

    使用方式:

    1. 在需要的项目中添加模块依赖

     2.  实现IWebPermissionCheck 中的方法替换默认的 NullWebPermissionChecker 实现,NullWebPermissionChecker 默认所有操作都是可以的,这里自己实现是指根据权限名和数据库中保存的对比,判断是否具有相应权限

    在 ConfigureServices 中进行替换默认的NullWebPermissionChecker 

      context.Services.Replace(
                    ServiceDescriptor.Transient<IWebPermissionCheck, MyWebPermissionCheck>()
                );

    附我自己的MyWebPermissionCheck实现方式:

    using Microsoft.Extensions.Localization;
    using Microsoft.Extensions.Logging;
    using Microsoft.Extensions.Logging.Abstractions;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Security.Claims;
    using System.Threading.Tasks;
    using Volo.Abp.Authorization.Permissions;
    using Volo.Abp.DependencyInjection;
    using Volo.Abp.Users;
    using WebSystem.Authorization;
    using WebSystem.Localization;
    using WebSystem.Shared.Enums;
    
    namespace WebSystem
    {
        public class MyWebPermissionCheck : IWebPermissionCheck, ITransientDependency
        {
    
            public ILogger<MyWebPermissionCheck> Logger { get; set; }
            protected IPermissionDefinitionManager PermissionDefinitionManager { get; }
            private readonly IStringLocalizer<WebSystemLoaclizationResource> _localizer;
            private readonly ICurrentUser _currentUser;
            private readonly IFreeSql _orm;
            public MyWebPermissionCheck(IPermissionDefinitionManager permissionDefinitionManager, IStringLocalizer<WebSystemLoaclizationResource> stringLocalizer, ICurrentUser currentUser, IFreeSql orm)
            {
                Logger = NullLogger<MyWebPermissionCheck>.Instance;
                PermissionDefinitionManager = permissionDefinitionManager;
                _localizer = stringLocalizer;
                _currentUser = currentUser;
                _orm = orm;
            }
            public bool IsGranted(string[] needPermissions, ClaimsPrincipal user)
            {
    
                var claims = _currentUser.GetAllClaims();
                var userIdClaim = claims?.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier);
                long? userId = null;
                string role = string.Empty;
                if (!string.IsNullOrEmpty(userIdClaim?.Value))
                {
                    userId = long.Parse(userIdClaim.Value);
                }
                else
                {
                    return false;
                }
    
                var userRoleIdClaim = claims?.FirstOrDefault(c => c.Type == ClaimTypes.Role);
                if (!string.IsNullOrEmpty(userRoleIdClaim?.Value))
                {
                    role = userRoleIdClaim.Value;
                }
                if (role == RoleEnum.Admin.ToString())
                {
                    return true;
                }
    
                var permissions = PermissionDefinitionManager.GetPermissions();
                if (role == RoleEnum.Agent.ToString())
                {
                    var agentPermissions = permissions.Where(m => (m.MultiTenancySide == Volo.Abp.MultiTenancy.MultiTenancySides.Both || m.MultiTenancySide == Volo.Abp.MultiTenancy.MultiTenancySides.Tenant) && m.IsEnabled == true);
                    if (agentPermissions.Any(m => needPermissions.Contains(m.Name)))
                    {
                        return true;
                    }
                }
                var isAny = _orm.Select<Models.Permission>().Where(m => m.Uid == userId && needPermissions.Contains(m.Name)).Any();
                if (isAny)
                {
                    return true;
                }
                return false;
            }
        }
    }

    3.具体使用多个权限之间使用英文逗号隔开

  • 相关阅读:
    第十六周项目5-为动态数组扩容
    Remoting
    C# 调用https服务
    12306
    Byte[]和Stream相互转换
    SQL Server之数据库语句优化
    前端框架VUE学习
    Oracle连接字符串总结
    .net 操作Oracle 海量数据
    新建一个Windows Service的方法
  • 原文地址:https://www.cnblogs.com/lkd3063601/p/15386903.html
Copyright © 2011-2022 走看看