- PVSM.RU - https://www.pvsm.ru -
Вы создали WebAPI и теперь хотите контролировать доступ к нему? В этой серии статей мы рассмотрим несколько вариантов защиты WebAPI от неавторизрованых пользователей. Серия будет охватывать обе стороны, и аутентификацию и авторизацию пользователей.
Первая серия статей дает общий обзор аутентификации и авторизации в ASP.NET Web API. Другие статьи описывают общие сценарии аутентификации для WebAPI.
WebAPI предполагает что аутентификацию проводит хост, в котором он размещается. Для веб-хостинга хостом является IIS, который использует HTTP модули для аутентификации. Вы можете сконфигурировать свой проект на использование модулей аутентификации встроенных в IIS или ASP.NET, или же написать собственный модуль HTTP, для выполнения кастомной проверки подлинности.
Когда хост проводит аутентификацию пользователя, он создает объект IPrincipal, который представляет собой контекст безопасности в котором исполняется код. Созданный объект прикрепляет к текущему потоку, и к нему можно обратиться через свойство Thread.CurrentPrincipal. Контекст безопасности содержит связанный с ним объект Identity, с информацией о пользователе. Если пользователь прошел аутентификацию, свойство Identity.IsAuthenticated вернет значение true. Для анонимных запросов свойство вернет false.
Вместо использования хоста, логику аутентификации можно поместить в обработчик HTTP сообщения. В этом случае, обработчик сообщения исследует HTTP запрос и сам задаст контекст безопасности.
Несколько примеров для чего может понадобиться аутентификация в обработчиках сообщений:
В общем, если вы не собираетесь использовать self-хостинг, использование HTTP модулей аутентификации лучший вариант. В противном случае логику стоит вынести в обработчики сообщений.
Если ваше приложение выполняет какую-либо логику связанную с аутентификацией, вы должны задать контекст безопасности в двух свойствах:
Следующий код показывает как задать контекст безопасности:
private void SetPrincipal(IPrincipal principal)
{
Thread.CurrentPrincipal = principal;
if (HttpContext.Current != null)
{
HttpContext.Current.User = principal;
}
}
Для веб-хостинга, вы должны задать контекст безопасности в обоих свойствах, иначе контекст безопасности может стать несогласованным. Для обеспечения независимости вашего кода от способа , следует выставлять проверку на null для свойства HttpContext.Current, как показано в коде. В случае self-хостинга, его значение будет null и задавать контекст безопасности не требуется.
В цепочке обработчиков запроса авторизация находится ближе к контроллеру. Это позволяет проводить тонкую настройку доступа к ресурсам.

WebAPI предоставляет встроенный фильтр авторизации, AuthorizeAttribute, этот фильтр проверяет авторизован ли пользователь. Если нет, фильтр вернет код состояния HTTP 401 (Не авторизован), без вызова метода.
Вы можете применять фильтр как глобально, так и на уровне контроллера или на уровне методов.
Фильтр на глобальном уровне: чтобы ограничить доступ для каждого контроллера WebAPI, добавьте фильтр AuthorizeAttribute в глобальный список фильтров:
public static void Register(HttpConfiguration config)
{
config.Filters.Add(new AuthorizeAttribute());
}
Фильтр на уровне контроллера: для ограничения доступа к конкретному контроллеру, добавьте фильтр в качестве атрибута класса контроллера:
// Require authorization for all actions on the controller.
[Authorize]
public class ValuesController : ApiController
{
public HttpResponseMessage Get(int id) { ... }
public HttpResponseMessage Post() { ... }
}
Фильтр на уровне метода: для ограничения доступа к методу, добавьте к нему атрибут:
public class ValuesController : ApiController
{
public HttpResponseMessage Get() { ... }
// Require authorization for a specific action.
[Authorize]
public HttpResponseMessage Post() { ... }
}
Кроме того, в можете задать ограничение на контроллер, и разрешить анонимный доступ на отдельные методы при помощи атрибута [AllowAnonymous]. В следующем примере, доступ к методу Post ограничен, а метод Get доступен для анонимных вызовов:
[Authorize]
public class ValuesController : ApiController
{
[AllowAnonymous]
public HttpResponseMessage Get() { ... }
public HttpResponseMessage Post() { ... }
}
В предыдущих примерах, фильтр позволял получить доступ любому пользователю прошедшему проверку подлинности, запрещая доступ только анонимным пользователям. Вы также можете предоставить доступ конкретным пользователям или ролям:
// Restrict by user:
[Authorize(Users="Alice,Bob")]
public class ValuesController : ApiController
{
}
// Restrict by role:
[Authorize(Roles="Administrators")]
public class ValuesController : ApiController
{
}
Кастомный фильтр должен быть унаследован от одного из следующих типов:
Следующая диаграмма показывает иерархию классов фильтров:

В некоторых случаях можно разрешить выполнение запроса, но изменить поведение на основе контекста безопасности. Например, результат запроса зависит от роли пользователя. Внутри метода контроллера вы можете получить текущий контекст безопасности обратившись к свойству ApiController.User:
public HttpResponseMessage Get()
{
if (User.IsInRole("Administrators"))
{
// ...
}
}
* Перевод выполнен в вольном стиле, возможно кого-то покоробят англицизмы наподобие 'кастомный', но эти слова стали частью it жаргона, и русский перевод не воспринимается как должно.
Автор: Ogoun
Источник [2]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/net/66447
Ссылки в тексте:
[1] хостинга: https://www.reg.ru/?rlink=reflink-717
[2] Источник: http://habrahabr.ru/post/231807/
Нажмите здесь для печати.