多个作用域的ASP.NET Core ClaimsAuthorizationRequirement是否无法按预期工作?

时间:2019-05-09 08:51:06

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

我碰到了一些东西,想问问您这是否是故意的行为或重大的安全风险。

我打算做的是用不同的策略授权两个API控制器操作。一种策略需要一个范围,另一种策略需要两个范围。

为此,我定义了范围

  • scope:1
  • scope:2

我打算授权的控制器及其执行方式如下:

  [ApiController]
  [Route("api/v1/[controller]")]
  //intentionally no authorize here
  public class TestContoller : ControllerBase 
  {

    [HttpGet("single")]
    [Authorize(AuthenticationSchemes = "Bearer", Policy = nameof(SingleScopePolicy))]
    public IActionResult GetSingle() { return Ok("success"); }

    [HttpGet("double")]
    [Authorize(AuthenticationSchemes = "Bearer", Policy = nameof(DoubleScopePolicy))]
    public IActionResult GetDouble() { return Ok("success"); }

  }

预期的行为(据我现在所了解)是,当SingleScopePolicy检测到它不具有范围:1并且DoubleScopePolicy检测到它不具有范围:1 AND 范围:2时,它返回禁止的行为。 。 AND是相关部分!

在Startup.cs中,我配置了授权并添加了如下范围(故意没有默认的测试策略)

public void ConfigureService(IServiceCollection service) 
  {
    // ...

    services.AddAuthorization
    (
      options =>
      {
        options.AddPolicy(nameof(SingleScopePolicy), new SingleScopePolicy());
        options.AddPolicy(nameof(DoubleScopePolicy), new DoubleScopePolicy());
      }
    );

    // ...
  }

然后我通过代码定义了两个策略:

  public class SingleScopePolicy : AuthorizationPolicy
  {
    public SingleScopePolicy() : base 
    (
      new IAuthorizationRequirement[]
      {
        new ClaimsAuthorizationRequirement("scope", new string[] { "scope:1 })
      },
      new string[] { "Bearer" }
    ) { }
  }

  public class DoubleScopePolicy : AuthorizationPolicy
  {
    public DoubleScopePolicy() : base 
    (
      new IAuthorizationRequirement[]
      {

        // does not work (never returns forbid)
        //new ClaimsAuthorizationRequirement("scope", new string[] { "scope:1", "scope:2" }) 

        // works
        new ClaimsAuthorizationRequirement("scope", new string[] { "scope:1" }),
        new ClaimsAuthorizationRequirement("scope", new string[] { "scope:2" }),
      },
      new string[] { "Bearer" }
    ) { }
  }

我的问题是现在应该在DoubleScopePolicy工作中要求授权要求,还是打算不起作用?

使用下面的行实际上从不禁止返回,并且始终允许访问。这种方式令我感到惊讶,因为它为您提供了一个string [],我会理解为“嘿,给我两个,然后我会检查两个都存在”。如果我将其分别定义为两行,则按我的预期工作。

new ClaimsAuthorizationRequirement("scope", new string[] { "scope:1", "scope:2" }) 

1 个答案:

答案 0 :(得分:2)

ClaimsAuthorizationRequirement的{​​{3}}表明AllowedValues属性被视为操作:

found = context.User.Claims.Any(
    c => string.Equals(c.Type, requirement.ClaimType, StringComparison.OrdinalIgnoreCase)
          && requirement.AllowedValues.Contains(c.Value, StringComparer.Ordinal));

// ...

if (found)
{
    context.Succeed(requirement);
}

如上所述,您可以添加多个ClaimsAuthorizationRequirement以便将检查视为操作。