Как создать основную политику авторизации ASP.NET, содержащую 2x логических правила? - PullRequest
0 голосов
/ 26 сентября 2018

Учитывая API-маршрут, который извлекает данные о пользователях из базы данных:

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

Я пытаюсь добавить некоторую логику безопасности на месте, чтобы убедиться, что при хотя бы один Следующие правила проверены, некоторые данные будут возвращены, когда:

  • Auth'd пользователь получает доступ к своей собственной записи.например, Auth'd userId == 1, / users / 1
  • Auth'd пользователь имеет утверждение 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 { }

и использовать это в некотором коде ... (это в контроллере или(в этом примере) обработчик медиатора):

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

    ....
}

Ссылки:

1 Ответ

0 голосов
/ 26 сентября 2018

Авторизация на основе политики видит, что это два разных требования.A UserIdRequirement и ClaimsAuthorizationRequirement.

При просмотре примера в базе данных Policy Документация для логики ИЛИ необходимо выполнить одно требование.Затем вы можете иметь несколько обработчиков для одного и того же требования или добавить всю логику к одному обработчику.

В примере из блога также есть одно требование: 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;
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...