2017-08-05 84 views
2

如何重新使用AuthorizationHandlers來組合兩個處理程序的複合requirement如何在ASP.Net Core中組合/組合授權處理程序?

  • RequirementA一個處理器IsAllowedAccessToA : AuthorizationHandler<RequirementA>
  • RequirementB一個處理器IsAllowedAccessToB : AuthorizationHandler<RequirementB>
  • RequirementA_OR_B它是否符合IsAllowedAccessToAIsAllowedAccessToB它成功,其中

我有隻對RequirementA和相同的可訪問資源爲RequirementB。我也有可用A或B.

我無法弄清楚如何做到這一點,而無需複製IsAllowedAccessToAIsAllowedAccessToB處理

This article幫助,但不完全相同的用例的資源。

回答

1

讓我們假設你的RequirementA_OR_B是由兩方面的要求,如:

public class RequirementA_OR_B : IAuthorizationRequirement 
{ 
    public RequirementA RequirementA { get; set; } 
    public RequirementB RequirementB { get; set; } 
} 

然後,您可以創建相結合的處理程序如下:

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); 
    } 
} 
2

沒有一個超級乾淨的方式將政策表述爲另外兩項政策。

但是你可以寫勢在必行作爲授權針對這兩項政策一個輔助方法,你將無法通過授權來做到這一點,但你可能只是把這種需要的地方:

async Task<bool> IsAllowedAccessToAOrB(ClaimsPrincipal user, IAuthorizationService auth, object resource) { 
     return await auth.AuthorizeAsync(user, resource, "PolicyA") || await auth.AuthorizeAsync(user, resource, "PolicyB") 
} 
+0

[轉貼的GitHub問題(https://github.com/aspnet/Security/issues/1356) – spottedmahn