zoukankan      html  css  js  c++  java
  • 基于 ASP.NET Core Policy-based authorization 实现博文访问授权

    昨天基于 ASP.NET Core Policy-based authorization 重构了博文访问授权的代码,在这篇随笔中记录一下,ASP.NET Core 中对应的源码实现见 https://github.com/dotnet/aspnetcore/tree/3.0/src/Security/Authorization

    创建 Authorization Requirement

    实现接口 IAuthorizationRequirement 与抽象类 AuthorizationHandler<T> ,实现类是 AccessPermissionAuthorizationRequirement

    public class AccessPermissionAuthorizationRequirement :
        AuthorizationHandler<AccessPermissionAuthorizationRequirement, AccessPermission>, IAuthorizationRequirement
    {
        protected override Task HandleRequirementAsync(
            AuthorizationHandlerContext context,
            AccessPermissionAuthorizationRequirement requirement,
            AccessPermission resource)
        {
            if (context.Resource != null && GetOwnPermission(context).HasFlag(resource))
            {
                context.Succeed(requirement);
            }
    
            return Task.CompletedTask;
        }
    
        private AccessPermission GetOwnPermission(AuthorizationHandlerContext context)
        {
            var claim = context.User.Claims.FirstOrDefault(c => c.Type == BlogClaimTypes.AccessPermission);
            Enum.TryParse(claim.Value, out AccessPermission permission);
            return permission;
        }
    }
    

    博文访问授权就在这个类中完成的,根据当前访问用户的 Claims 与博文的访问权限 context.Resource 判断是否有权限访问当前博文。

    配置 Policy

    在 Policy 中添加之前的 AccessPermissionAuthorizationRequirement ,在 Startup.ConfigureServices 中添加下面的代码。

    services.AddAuthorization(options => options.AddPolicy(
        nameof(AccessPermission),
        builder => builder.AddRequirements(new AccessPermissionAuthorizationRequirement())));
    

    添加 Claim

    根据当前用户所拥有的访问权限,添加对应的 Claim ,我们是在一个 middleware 中添加的。

    var identity = new ClaimsIdentity();
    identity.AddClaim(new Claim(BlogClaimTypes.AccessPermission, accessPermission.ToString()));
    context.User.AddIdentity(identity);
    

    实现 PermissionEvaluator

    实现 PermissionEvaluator 的目的是简化调用方的代码。

    IPermissionEvaluator 接口代码

    public interface IPermissionEvaluator
    {
        Task<PolicyAuthorizationResult> AuthorizeAsync(HttpContext context, AccessPermission permision);
    }
    

    PermissionEvaluator 实现代码

    public class PermissionEvaluator : IPermissionEvaluator
    {
        private readonly IAuthorizationPolicyProvider _policyProvider;
        private readonly IPolicyEvaluator _policyEvaluator;
    
        public PermissionEvaluator(
            IAuthorizationPolicyProvider policyProvider,
            IPolicyEvaluator policyEvaluator)
        {
            _policyProvider = policyProvider;
            _policyEvaluator = policyEvaluator;
        }
    
        public async Task<PolicyAuthorizationResult> AuthorizeAsync(HttpContext context, AccessPermission permision)
        {
            var policy = await _policyProvider.GetPolicyAsync(nameof(AccessPermission));
            var authenticateResult = await _policyEvaluator.AuthenticateAsync(policy, context);
            var authorizeResult = await _policyEvaluator.AuthorizeAsync(policy, authenticateResult, context, resource: permision);
            return authorizeResult;
        }
    }
    

    调用 IPermissionEvaluator 获取博文访问授权结果

    在 Controller 中注入 IPermissionEvaluator ,在 Action 中添加如下的代码获取博文访问授权结果。

    var requiredPermission = await _permissionService.DetermineAccessPermission(blogpost);
    var authorizationResult = await _permissionEvaluator.AuthorizeAsync(HttpContext, requiredPermission);
    if (!authorizationResult.Succeeded)
    {
        return authorizationResult.Challenged ? Challenge() : Forbid() as IActionResult;
    }
    
  • 相关阅读:
    实现页面切换(动画效果实现,不用ViewPager)
    “仅仅生一个娃”--设计模式中的单例模式
    ZOJ
    【J2SE高速进阶】——多线程之synchronized
    [LeetCode] Search a 2D Matrix II
    leetCode 58.Length of Last Word (最后单词的长度) 解题思路和方法
    [CentOS]怎样解决gcc版本号冲突?
    从0开始学习 GITHUB 系列之「GITHUB 常见的几种操作」【转】
    从0开始学习 GITHUB 系列之「向GITHUB 提交代码」【转】
    从0开始学习 GITHUB 系列之「GIT 速成」【转】
  • 原文地址:https://www.cnblogs.com/dudu/p/13197545.html
Copyright © 2011-2022 走看看