Ролевая авторизация в ASP.NET Web API - как установить роли на принципале?
Я использую рецепт 10-3 в недавно выпущенной книге ASP.NET Web Api 2 Recipes для поддержки базовой аутентификации в моем Web API. Этот рецепт использует стороннюю библиотеку от Thinktecture. Как видно из приведенного ниже кода, я выполняю аутентификацию пользователя по своей учетной записи.
using Thinktecture.IdentityModel.WebApi.Authentication.Handler;
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
...
var authenticationConfiguration = new AuthenticationConfiguration();
var accountService = ServiceLocator.Get<AccountService>();
authenticationConfiguration.AddBasicAuthentication((userName, password) => accountService.Authenticate(userName, password));
config.MessageHandlers.Add(new AuthenticationHandler(authenticationConfiguration));
...
}
}
Теперь я хочу сделать авторизацию на основе ролей в моих контроллерах, используя атрибут Authorize:
[Authorize(Roles="administrator")]
public IHttpActionResult Get()
{
...
}
Моя служба учетных записей, очевидно, знает о пользователях и назначенных им ролях, но эта информация недоступна для авторизации (роли не установлены для принципала).
Как мне это сделать? Можно ли настроить обработчик аутентификации Thinktecture для установки ролей на основном сервере? Или я должен сделать свой собственный атрибут Authorize (производный от атрибута Authorize)? И если да, должен ли я переопределить метод OnAuthorization для создания и настройки принципала с помощью службы моей учетной записи? Или, может быть, переопределить метод IsAuthorized напрямую? Или, может быть, что-то еще...
2 ответа
Я обнаружил, что метод AddBasicAutentication на самом деле имеет перегрузку, которая принимает делегата для предоставления ролей. Это именно то, что я искал. Так что теперь вызов AddBasicAuthentication выглядит так, и все работает как чудо:
authenticationConfiguration.AddBasicAuthentication((userName, password) => accountService.Authenticate(userName, password), (username) => accountService.GetRoles(username));
AuthenticationHandler выполняет только аутентификацию. Вам нужно будет установить роли на отдельном шаге (например, в делегирующем обработчике).
Если вы используете Web API v2 - я бы порекомендовал перейти на базовое промежуточное ПО OWIN для аутентификации
Это дает вам полный контроль над принципалом, который создается.
Также есть нюгет.