ClaimsAuthorizationRequirement

ClaimsAuthorizationRequirement

我遇到了一些问题,想问您一些建议,如果这是故意的行为或重大的安全风险。

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

为此,我定义了范围


范围:1
范围: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检测到它不具有scope:1并且DoubleScopePolicy检测到它不具有scope:1和scope: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" })

最佳答案

ClaimsAuthorizationRequirementsource显示AllowedValues属性被视为or操作:

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以便将检查视为and操作。

关于c# - 多个作用域的ASP.NET Core ClaimsAuthorizationRequirement是否无法按预期工作?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56055649/

10-11 06:53