Подтвердить что ты не робот

Где я должен подключить авторизацию в WebPI Asp.net?

Как я вижу, у меня есть 3 возможных места для подключения моих вещей в конвейере

1)     AuthorizationFilters

2)     Action Filters

3)     DelegatingHandler

Наиболее очевидным является AuthorizationFilters, где я могу украсить свои действия/контроллеры своим настраиваемым атрибутом авторизации. скажем, MyCustomAuthorizationAttribute.

Так как обработчики HTTP-сообщений находятся на первом этапе в конвейере обработки. Имеет ли смысл вкладывать его туда?

Авторизация для меня прямо сейчас означает проверку маркера в заголовке, который предоставляется клиенту после аутентификации.

4b9b3361

Ответ 1

Обновление июля 2014 года

Мой первоначальный ответ был посвящен WebApi 1. с помощью WebApi 2 произошли некоторые изменения, то есть теперь есть IAuthenticationFilter, что означает, что вы можете переместить логику аутентификации из DelegatingHandler, которая немного более элегантна.

Существует проект Nuget здесь, который предлагает реализацию IAuthenticationFilter, а также объясняет некоторые предпосылки его введения.

Средство промежуточного ПО OWIN теперь, пожалуй, лучшее место для реализации вашей логики аутентификации - здесь есть пример аутентификации сертификата здесь и базовая аутентификация OWIN Middleware здесь в этот пост в блоге прежний пример является предпочтительным, поскольку он демонстрирует использование базового класса AuthenticationHandler.

Совет по AuthorizationFilters остается практически неизменным.

Окончательное обновление

Как правило,...

Используйте DelegatingHandler для выполнения проверки подлинности... то есть кто-то есть. Используйте это, чтобы установить Принцип контекста темы и пользователя, добавить претензии и т.д. Здесь вы можете разместить логику авторизации, но в достаточно глобальном масштабе. Я бы лично всегда использовал AuthorizationFilters для авторизации.

Используйте AuthorizationFilters, чтобы ограничить контроллеры и действия конкретными людьми. Они используются, когда вы можете экстраполировать их разрешение с информацией в параметрах запроса, принципала, URL-адреса или http-запроса. Фильтр авторизации по умолчанию можно использовать для ограничения доступа к анонимным пользователям или ролям (если они установлены как нечто вроде обработчика делегирования) - очевидно, вы также можете реализовать свои собственные AuthorizationFilters, если вам это нужно.

Иногда используйте ActionFilters, когда вам нужно принять решение о разрешении с использованием содержимого сообщения, например. вам нужен доступ к объекту на сущности, чтобы решить, имеют ли они доступ (очевидно, будьте осторожны с этим (!)).

Примечание:

AuthorizationFilters вызывается до того, как содержимое тела будет прочитано, поэтому они не имеют доступа к телу сообщения для принятия решений о авторизации, поэтому ActionFilters в частности OnActionExecuting используется для случайного повышения ошибок аутентификации.

Так

В вашем сценарии я бы поставил простой DelegatingHandler, чтобы взять ваш заголовок и установить принципал.

public class CustomAuthenticationMessageHandler : DelegatingHandler
{


    public CustomAuthenticationMessageHandler ()
    {

    }

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
                                                           CancellationToken cancellationToken)
    {
        Authenticate(request);

        return base.SendAsync(request, cancellationToken);
    }

    protected virtual void Authenticate(HttpRequestMessage request)
    {

        var authorisationHeader = request.Headers.Authorization;

        if (authorisationHeader == null)
        {
            return;
        }

        //Ensure you are happy with the header contents then

        {
            var principal = new GenericPrincipal(//new Identity , //Roles);
            Thread.CurrentPrincipal = principal;
            HttpContext.Current.User = principal;
        }

    }
}

Затем используйте AuthorizationFilters для ограничения доступа:

    [Authorize]
    public string Get()
    {

    }

    [Authorize(Roles = "Admin")]
    public string GetAdminOnly()
    {

    }

Чтобы зарегистрировать глобальную проверку подлинности

config.MessageHandlers.Add(new CustomAuthenticationMessageHandler());

Это будет означать, что в каждом запросе принципал будет установлен как null, так и действительный идентификатор. Он не будет обрабатывать авторизацию, то есть не откажет в доступе к любым контроллерам или действиям.

Чтобы начать защиту ресурсов

Либо целевые защищенные контроллеры, либо действия со стандартными или пользовательскими атрибутами [Авторизовать]. Или зарегистрируйтесь глобально:

config.Filters.Add(new AuthorizeAttribute());

И только белый список контроллеров и действий, которые вы хотите получить без защиты, используя атрибут [AllowAnonymous].

Если вам нужна только проверка подлинности на некоторых маршрутах

Затем вы можете немного изменить свой DelegatingHandler, чтобы установить InnerHandler на правильный контроллер, например.

public CustomAuthenticationMessageHandler(HttpConfiguration configuration)
{
       InnerHandler = new HttpRoutingDispatcher(configuration);
}

И затем вы можете указать этот обработчик на своих маршрутах так:

config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "myurl",
            defaults: new {},
            constraints: new {},
            handler: new CustomAuthenticationHandler(config)
            );