基於 ASP.NET Core Policy-based authorization 實現博文訪問授權


1昨天基於 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;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM