Авторизация и аутентификация — первое, что требуется наладить практически во всех веб-приложениях, а значит, от этого будет отталкиваться и весь остальной функционал разрабатываемой системы. Уделить этому особое внимание не будет лишним. Данная статья посвящена встроенной системе авторизации и аутентификации в ASP.NET Core Identity, также называемой Identity 3.0.
Введение
Но, прежде чем приступить к основной теме, разберемся с терминологией. Глобально предоставление доступа к ограниченным ресурсам в веб-приложениях проходит в три этапа: идентификации, аутентификации и авторизации.
Идентификация — процесс распознавания субъекта (пользователя, программы, процесса) на основе его идентификатора (имени, логина, номера телефона). Если предоставленный идентификатор существует в системе, идентификация прошла успешно, переходим к аутентификации.
Аутентификация — процедура проверки подлинности. Пользователь, предоставивший логин, должен подтвердить, что он тот, за кого себя принимает, например, с помощью пароля.
И третий этап — авторизация — заключается в проверке прав доступа аутентифицированного субъекта к ресурсу. Субъект считается авторизованным, если ему предоставлены соответствующие права доступа к объектам системы.
Начало
Вся эта функциональность уже реализована для ASP.NET Core — проект с открытым исходным кодом под названием Identity 3.0. Для настройки окружения вам понадобится установить:
- Visual Studio 2015;
- Update 3 для VS 2015;
- .NET Core tools for Visual Studio.
Инструкцию по установке и ссылки можно найти здесь.
Для включения функционала Identity создадим проект ASP.NET Core Web Application по шаблону Web Application и в качестве типа аутентификации выберем Individual User Accounts.
В проект будет добавлен пакет Microsoft.AspNetCore.Identity.EntityFrameworkCore, который будет сохранять данные и схемы в SQL Server для Entity Framework Core.
Также этот пакет можно добавить через NuGet Package Manager.
Или же дописав соответствующие зависимости в файле project.json в узлах dependencies и tools.
После сохранения файла в проект автоматически будут добавлены указанные пакеты. Но в этом случае для работы приложения необходимо будет самому настроить строку подключения и работу с базой данных.
Как это работает
В ходе нехитрых манипуляций по созданию проекта мы получили полностью рабочую систему аутентификации и авторизации. Приложение готово к работе и можно уже зарегистрировать нового пользователя и войти под ним в систему.
В ASP.NET Core за настройку обработки запросов отвечает метод Configure класса Startup. При создании проекта с использованием шаблона по умолчанию в этот метод добавится строка app.UseIdentity () ;
отвечающая за аутентификацию для потока запросов, основанную на куки.
Также в метод ConfigureServices этого же класса Startup будут добавлены Identity сервисы.
Это позволит использовать их в приложении с помощью встроенной системы внедрения зависимостей.
Теперь при обработке каждого запроса будет проводиться аутентификация пользователя. А авторизацию будет контролировать атрибут Authorize, который можно добавить перед контроллером и отдельным методом в MVC фреймворке.
ASP.NET Core был сильно изменен по сравнению с прошлыми версиями, не остался в стороне и Identity 3.0. Структура БД для Identity 3.0 имеет следующий вид:
Появились две новые таблицы: AspNetRoleClaims и AspNetUserTokens. Пользователи и роли, как и ранее, представлены классами IdentityUser и IdentityRole соответственно. Но теперь они не наследуются от интерфейсов для пользователей и ролей, что очень удобно. Также появились новые инструменты авторизации — политики.
Политика — это одно или несколько требований, необходимых пройти пользователю для авторизации.
Пример
Пусть для доступа к некоторому ресурсу в приложении пользователь должен иметь российское гражданство. Для начала зарегистрируем политику RussianСitizenship в ConfigureService файла startup.cs:
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddMvc();
services.AddAuthorization(options =>
{
options.AddPolicy("RussianСitizenship",
policy => policy.Requirements.Add(new RussianСitizenshipRequirement("Russian Federation")));
});
// Add application services.
services.AddTransient<IEmailSender, AuthMessageSender>();
services.AddTransient<ISmsSender, AuthMessageSender>();
}
Для регистрации политики мы использовали RussianСitizenshipRequirement в качестве авторизационного требования — параметры данных, которые использует политика для оценки текущего пользователя. В нашем случае есть лишь один параметр — гражданство. Для создания требования нужно реализовать интерфейс IAuthorizationRequirement:
public class RussianСitizenshipRequirement : IAuthorizationRequirement
{
public RussianСitizenshipRequirement(string citizenship)
{
Сitizenship = citizenship;
}
public string Сitizenship { get; }
}
Далее создадим обработчик авторизации, который и будет оценивать свойства требования для принятия решения об авторизации:
public class RussianСitizenshipHandler : AuthorizationHandler<RussianСitizenshipRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RussianСitizenshipRequirement requirement)
{
if (!context.User.HasClaim(c => c.Type == ClaimTypes.Country))
{
return Task.FromResult(0);
}
var citizenship = context.User.FindFirst(
c => c.Type == ClaimTypes.Country).Value;
if (citizenship == requirement.Сitizenship)
{
context.Succeed(requirement);
}
return Task.CompletedTask;
}
}
Добавим в HomeController метод RussianPage () c атрибутом Authorize:
[Authorize(Policy = "RussianСitizenship")]
public IActionResult RussianPage()
{
return View();
}
Готово, доступ к этому методу получат лишь пользователи, удовлетворяющие требованиям данной политики.
Выводы
Это была обзорная статья, из которой видно, что Identity 3.0 является мощным инструментом, , который поддерживает:
- авторизацию на основе ролей,
- Claim-Based авторизацию,
- аутентификацию через соцсети,
- двухфакторную аутентификацию с подтверждением по смс или по электронной почте и др.
Для большинства сайтов этого достаточно для полноценной работы.
В следующей статье я постараюсь немного кастомизировать Identity и адаптировать его для использования в приложении с многослойной архитектурой.