Можно ли запустить все обработчики для политики в строке, а не с атрибутом? - PullRequest
8 голосов
/ 12 февраля 2020

В большинстве моих API я просто делаю авторизацию следующим образом:

[Authorize(Policy = "Foo")]
public MyApi()

Я получаю эту политику из NuGet и не могу ее изменить.

Для некоторых моих API я не всегда хочу иметь эту политику. Это нужно выяснить во время выполнения, основываясь на некоторой конфигурации. Я хотел бы как-нибудь запустить этот in-line и убедиться, что все обработчики, которые запускаются при установке, запускаются.

После долгих поисков я обнаружил, что создаю IAuthorizationService и использую его для звоните AuthorizeAsync. Кажется, это то, что я хочу, но проблема, с которой я сейчас сталкиваюсь, заключается в том, что все обработчики полагаются на AuthorizationFilterContext в качестве ресурса в контексте. Кажется, это происходит автоматически, когда авторизация выполняется через атрибут, а не через вызов AuthorizeAsyn c. В этом случае его необходимо передать вручную. Мой код сейчас выглядит следующим образом:

public MyApi()
{
    var allowed = await _authorizationService.AuthorizeAsync(User, null, "Foo").ConfigureAwait(false);
}

Кажется, что go корректно проходит через все мои обработчики, но они не работают из-за отсутствия AuthorizationFilterContext.

1) Это правильный подход для начала, или есть какой-то другой способ сделать это in-line? Я предполагаю, что, возможно, есть какой-то способ создать мою собственную политику, которая обернет это, и я могу проверить конфигурацию там, но если есть простой встроенный подход, я бы предпочел это.

2) Если это способ действителен, есть ли хороший способ получить AuthorizationFilterContext? Я пытался создать его вручную, но боюсь, что это на самом деле не правильно без передачи большего количества данных из контекста, но я не могу найти хороших примеров / do c:

new AuthorizationFilterContext(new ActionContext(HttpContext, HttpContext.GetRouteData(), new ActionDescriptor()), new IFilterMetadata[] { });

Ответы [ 3 ]

0 голосов
/ 24 февраля 2020

Разве вы не можете создать свой собственный атрибут Authorize, который унаследует текущий атрибут и разрешит политику внутренне? Или еще лучше попробуйте использовать IAuthorizationPolicyProvider

class MyPolicyProvider : IAuthorizationPolicyProvider
{
    private DefaultAuthorizationPolicyProvider BackupPolicyProvider { get; }

    public MyPolicyProvider()
    {
        BackupPolicyProvider = new DefaultAuthorizationPolicyProvider(options);
    }

    public Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
    {
        if (policyName.Equals("Foo"))
        {
            bool myConditionToAvoidPolicy = true;
            if (myConditionToAvoidPolicy)
            {
                return Task.FromResult<AuthorizationPolicy>(null);
            }
        }

        return BackupPolicyProvider.GetPolicyAsync(policyName);
    }
}

Это не проверено, но вы можете найти больше об этом здесь .

0 голосов
/ 25 февраля 2020

Ваше условие проверки похоже на то, что оно происходит позже, что я не думаю, что это хорошая идея. Ваш метод API уязвим и по-прежнему открыт, так как проверка выполняется на более позднем этапе. Но с помощью атрибута вы можете захватить его на более раннем уровне и все же можете применить собственный лог c. В конце концов, все, что он решает, это либо «да, у вас есть доступ», либо «нет, у вас нет доступа !!» Ниже не проверено, но вы должны начать:

public class CustomAuthorize : AuthorizeAttribute
{
    private readonly PermissionAction[] permissionActions;

    public CustomAuthorize(PermissionItem item, params PermissionAction[] permissionActions)
    {
        this.permissionActions = permissionActions;
    }

    public override void OnAuthorization(HttpActionContext actionContext)
    {
        var currentIdentity = System.Threading.Thread.CurrentPrincipal.Identity;
        if (!currentIdentity.IsAuthenticated) {
            // no access
        }

        bool myCondition = "money" == "happiness"; 
        if(myCondition){
           // do your magic here...
        }
        else{
          // another magic...
       }           
    }
}
0 голосов
/ 21 февраля 2020

Не будет AuthorizationFilterContext, когда вы находитесь вне конвейера авторизации. Поэтому вам не следует обрабатывать аутентификацию, встроенную в IAuthorizationService.

. Это похоже на go во всех моих обработчиках, но они не работают из-за отсутствия AuthorizationFilterContext. * 1007. *

Похоже, у вас есть контроль над обработчиками аутентификации. Вы пробовали аутентификацию короткого замыкания внутри обработчика, если она не требуется?

Обработчик может получать сервисы через DI, чтобы вы могли выставить необходимую конфигурацию времени выполнения через IOptions или IHttpContextAccessor и все такое.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...