如何在 ASP.Net Core 中组合/组合授权处理程序?

spo*_*ahn 6 authorization asp.net-core

如何重用来组成两个处理程序的AuthorizationHandlers复合需求?

  • RequirementA与一个处理程序IsAllowedAccessToA : AuthorizationHandler<RequirementA>
  • RequirementB与一个处理程序IsAllowedAccessToB : AuthorizationHandler<RequirementB>
  • RequirementA_OR_B如果在哪里相遇IsAllowedAccessToAIsAllowedAccessToB成功

我拥有只能访问的资源,RequirementA并且对于RequirementB. 我也有 A 或 B 可以使用的资源。

我不知道如何在没有重复IsAllowedAccessToAIsAllowedAccessToB处理程序的情况下做到这一点

本文有所帮助,但并非完全相同的用例。

Mét*_*ule 3

我们假设您的RequirementA_OR_B要求满足这两个要求,例如:

public class RequirementA_OR_B : IAuthorizationRequirement
{
    public RequirementA RequirementA { get; set; }
    public RequirementB RequirementB { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后您可以创建组合处理程序,如下所示:

public class RequirementA_OR_BHandler : AuthorizationHandler<RequirementA_OR_B>
{
    private RequirementAHandler _requirementAHandler;
    private RequirementBHandler _requirementBHandler;

    public RequirementA_OR_BHandler(/* Whatever is needed by either handlers*/)
    {
        // note: the dependency injection framework might directly inject both handlers, but I didn't check
        _requirementAHandler = new RequirementAHandler();
        _requirementBHandler = new RequirementBHandler();
    }

    protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, RequirementA_OR_B requirement)
    {
        // create a dummy context with both requirements
        var requirements = new IAuthorizationRequirement[]
        {
            requirement.RequirementA,
            requirement.RequirementB,
        };

        var dummyContext = new AuthorizationHandlerContext(requirements, context.User, null);
        await _requirementAHandler.HandleAsync(dummyContext);
        await _requirementBHandler.HandleAsync(dummyContext);

        // if either A or B succeeds, the number of pending requirements will decrease
        if (dummyContext.PendingRequirements.Count() < 2)
            context.Succeed(requirement);

        await Task.FromResult(true);
    }
}
Run Code Online (Sandbox Code Playgroud)