ASP.NET Core ClaimsAuthorizationRequirement для нескольких областей не работает должным образом? - PullRequest
2 голосов
/ 09 мая 2019

Я наткнулся на что-то и хотел бы попросить вас совета, если это предполагаемое поведение или серьезная угроза безопасности.

Я намеревался разрешить два действия контроллера 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 обнаруживает, что он не имеетобласть действия: 1, и DoubleScopePolicy обнаруживает, что у нее нет области действия: 1 И область действия: 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 или предполагается, что это не работает.

Использование строки ниже фактически НИКОГДАвозврат запрещен и всегда разрешает доступ.Этот вид заставляет меня удивляться, потому что он предлагает вам строку [], которую я бы понял как «эй, дай мне два, и я проверю, есть ли оба».Если я определю его отдельно в две строки, он будет работать как задумано (мной).

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

1 Ответ

2 голосов
/ 09 мая 2019

Источник для ClaimsAuthorizationRequirement показывает, что свойство 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 s, чтобы обработать проверку как операции и .

...