如何创建包含2x逻辑规则的ASP.NET Core授权策略?

时间:2018-09-26 09:58:28

标签: c# asp.net authentication asp.net-core

给出一个从数据库检索用户数据的API路由:

/users/{userId}  // e.g.  /users/1

我正在尝试添加一些安全性逻辑,以确保在检查至少一个以下规则时,在以下情况下会返回一些数据:

  • 授权用户正在访问他们自己的记录。例如验证的userId == 1,/ users / 1
  • 授权用户拥有版权声明CanAccessAnyUser

要在一个简单的ASP.NET Core应用程序中执行此操作,我将利用基于Policy的授权。

注意我怎么说“ 至少一个?这就是我坚持的一点。

目前我已经知道我可以使用Resource Based Authorization做第一条规则。

第二条规则可以通过简单的.RequireClaims策略检查来完成。

但是我不确定如何在startup.cs中设置它们?这是一些代码来解释。

services.AddAuthorization(options =>
{
    options.AddPolicy("pewpew", policy => ??? );

    // This is logical 'AND' logic checks. Not a logic 'OR' check :(
    options.AddPolicy("CanAccessAUser", policy =>
        policy.Requirements.Add(new UserIdRequirement())
              .RequiresClaim("CanAccessAnyUser");
}


public class CanAccessAUserHandler : AuthorizationHandler<SameUserIdRequirement, string>
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
                                                   SameUserIdRequirement requirement,
                                                   string resource)
    {
        if (context.User != null &&
            context.User.UserId().Equals(resource, StringComparison.OrdinalIgnoreCase))
        {
            context.Succeed(requirement);
        }

        return Task.CompletedTask;
    }
}

public class SameUserIdRequirement : IAuthorizationRequirement { }

并在某些代码中使用它...(在控制器或Mediatr的处理程序中(在此示例中):

public async Task<Response> Handle(Command request, CancellationToken cancellationToken)
{
    // Security check.
    var authorizationResult = await _authorizationService.AuthorizeAsync(
        request.ClaimsPrincipal,
        request.UserId,
        "CanAccessAnyUser");

    ....
}

参考文献:

1 个答案:

答案 0 :(得分:0)

基于策略的授权会看到这是两个不同的要求。 UserIdRequirementClaimsAuthorizationRequirement

在策略基础授权documentation中的OR逻辑示例中,您需要有一项要求。然后,您可以具有多个处理程序来满足相同的要求,或者将所有逻辑添加到一个处理程序中。

博客文章中的示例也有一个要求AssesrtionRequirement

这很可能不是您想要的。

或者,检查AuthorizationResult.Fail.FailedRequirements以查看是否所有要求都失败了。

或者,您可以更改处理程序以授权每个要求。您需要将IAuthorizationPolicyProvider注入处理程序,然后执行以下操作:

AuthorizationPolicy authorisationPolicy = _authorizationPolicyProvider.GetPol.GetPolicyAsync(policy);
foreach (IAuthorizationRequirement authorisationPolicyRequirement in authorisationPolicy.Requirements)
        {
            var result _authorizationService.AuthorizeAsync(principal, userId, authorisationPolicyRequirement);
            if (result.Succeeded) return true;
        }