Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core
Релиз ASP.NET MVC 5 ознаменовался выходом новой системой авторизации и аутентификации в .NET приложениях под названием ASP.NET Identity. Эта система пришла на смену провайдерам Simple Membership, которые были введены в ASP.NET MVC 4.
Рассмотрим систему авторизации и аутентификации ASP.NET Identity на примере приложения MVC 5. Итак, при создании приложения MVC 5 Visual Studio предлагает нам выбрать один из типов аутентификации:
Нажав на кнопку Change Authentication, мы можем изменить тип аутентификации, выбрав одно из следующих:
No Authentication: ASP.NET Identity и встроенная система аутентификации отсутствует
Individual User Accounts: проект по умолчанию включает систему ASP.NET Identity, которая позволяет авторизовать как пользователей внутри приложения, так и с помощью внешних сервисов, как google, твиттер и т.д.
Organizational Accounts: подходит для сайтов и веб-приложений отдельных компаний и организаций
Windows Authentication: система аутентификации для сетей intranet с помощью учетных записей Windows
Оставим значение по умолчанию, то есть Individual User Accounts и создадим проект.
Созданный проект уже по умолчанию имеет всю необходимую для авторизации инфраструктуру: модели, контроллеры, представления. Если мы заглянем в узел References (Библиотеки), то увидим там ряд ключевых библиотек, которые и содержит необходимые для авторизации и аутентификации классы:
Это ряд библиотек OWIN, которые добавляют функциональность OWIN в проект, а также три библиотеки собственно ASP.NET Identity:
Microsoft.AspNet.Identity.EntityFramework: содержит классы Entity Framework, применяющие ASP.NET Identity и осуществляющие связь с SQL Serveroм
Microsoft.AspNet.Identity.Core: содержит ряд ключевых интерфейсов ASP.NET Identity. Реализация этих интерфейсов позволит выйти за рамки MS SQL Server и использовать в качестве хранилища учетных записей другие СУБД, в том числе системы NoSQL
Microsoft.AspNet.Identity.OWIN: привносит в приложение ASP.NET MVC аутентификацию OWIN с помощью ASP.NET Identity
Поскольку вся инфраструктура уже имеется в проекте, запустим проект, на отобразившейся в браузере странице найдем ссылку Register и нажмем на нее. На открывшейся странице регистрации введем какие-нибудь данные:
После регистрации логин будет отображаться в правом верхнем углу веб-страницы веб-приложения. Осуществив регистрацию, мы можем разлогиниться, нажав на LogOff, и снова войти в систему. Таким образом, мы можем уже начать пользоваться встроенной системой аутентификации в приложении ASP.NET MVC 5. Теперь же рассомотрим ее основные моменты.
Во-первых, где это все хранится? Куда попадают данные зарегистрированных пользователей?
В данном случае используется подход Code First. В файле web.config уже имеется строка подключения по умолчанию, которая задает каталог базы данных. Если мы раскроем папку App_Data, то сможем увидеть созданную базу данных:
Если вдруг в папке база данных не видна, нажмем вверху окна Solution Explorer на кнопку Show All Files (Показать все файлы).
Мы можем открыть эту базу данных в окне Server Explorer и увидеть ее содержимое:
По умолчанию при регистрации первого пользователя создается следующий набор таблиц:
_MigrationHistory: используется EntityFramework для миграций БД
AspNetRoles: содержит определения ролей
AspNetUserClaims: таблица, хранящая набор клеймов (claim). Claim представляет иную модель авторизации по сравнению с ролями. Грубо говоря, claim содержит некоторую информацию о пользователе, например, адрес электронной почты, логин, возраст и т.д. И эта информация позволяет идентифицировать пользователя и наделить его соответствующими правами доступа.
AspNetUserLogins: таблица логинов пользователя
AspNetUserRoles: таблица, устанавливающая для пользователей определенные роли
AspNetUsers: собственно таблица пользователей. Если мы ее откроем, то увидим данные зарегистрированного пользователя
Ключевыми объектами в AspNet Identity являются пользователи и роли. Вся функциональность по созданию, удалению пользователей, взаимодействию с хранилищем пользователей хранится в классе UserManager. Для работы с ролями и их управлением в AspNet Identity определен класс RoleManager. Классы UserManager и RoleManager находятся в библиотеке Microsoft.AspNet.Identity.Core.
Каждый пользователь для UserManager представляет объект интерфейса IUser. А все операции по управлению пользователями производятся через хранилище, представленное объектом IUserStore.
Каждая роль представляет реализацию интерфейса IRole, а управление ролями классом RoleManager происходит через хранилище IRoleStore.
Непосредственную реализацию интерфейсов IUser, IRole, IUserStore и IRoleStore предоставляет пространство имен Microsoft.AspNet.Identity.EntityFramework:
Класс IdentityUser является реализацией интерфейса IUser. А класс хранилища пользователей - UserStore реализует интерфейс IUserStore.
Подобным образом класс IdentityRole реализует интерфейс IRole, а класс хранилища ролей - RoleStore реализует интерфейс IRoleStore.
А для взаимодействия с базой данных в пространстве имен Microsoft.AspNet.Identity.EntityFramework определен класс контекста IdentityDbContext
В приложении ASP.NET MVC мы не будем работать напрямую с классами IdentityUser и IdentityDbContext. По умолчанию в проект в папку Models добавляется файл IdentityModels.cs, который содержит определения классов пользователей и контекста данных:
public class ApplicationUser : IdentityUser { public async Task<ClaimsIdentity> GenerateUserIdentityAsync (UserManager<ApplicationUser> manager) { var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); return userIdentity; } } public class ApplicationDbContext : IdentityDbContext<ApplicationUser> { public ApplicationDbContext() : base("DefaultConnection", throwIfV1Schema: false) { } public static ApplicationDbContext Create() { return new ApplicationDbContext(); } }
В приложении мы не работаем напрямую с классами IdentityUser и IdentityDbContext, а имеем дело с классами-наследниками.
Класс ApplicationUser наследует от IdentityUser все свойства. И кроме того добавляет метод GenerateUserIdentityAsync()
,
в котором с помощью вызова UserManager.CreateIdentityAsync
создается объект ClaimsIdentity. Данный объект содержит информацию
о данном пользователе.
Подобная архитектура позволяет взять уже готовый функционал и при необходимости добавить новый, например, добавить для пользователя новое свойство или добавить новую таблицу в бд.
Я не буду подробно расписывать весь функционал AspNet Identity, который по умолчанию добавляется в проект, обозначу вкратце лишь основные возможности.
Во-первых, чтобы задействовать AspNet Identity, в проект в папку App_Start добавляются два файла. Файл Startup.Auth.cs содержит класс запуска приложения OWIN. Поскольку AspNet Identity использует инфраструктуру OWIN, то данный класс является одним из ключевых и необходимых для работы.
Файл IdentityConfig.cs содержит ряд дополнительных вспомогательных классов: сервисы для двухфакторной валидации
с помощью email и телефона EmailService
и SmsService
, класс менеджера пользователей ApplicationUserManager
, добавляющий к
UserManager ряд дополнительных функций, и класс ApplicationSignInManager
, используемый для входа и выхода с сайта.
Базовая функциональность системы аутентификации и управления учетными записями расположена в двух контроллерах: AccountController
и ManageController
В AccountController определены методы для логина, регистрации, верификации кода, отправленного по email или по смс, сброс пароля, напоминание пароля, вход на сайт с помощью внешних сервисов. Контроллер ManageController используется для управления учетной записью и предполагает возможности по смене пароля и управлению телефонными номерами в системе. Для обоих контроллеров уже по умолчанию генерируются все необходимые представления и специальные модели представлений.
Несмотря на то, что по умолчанию нам уже предоставляется готовый функционал, однако в ряде случаев, например, для отправки смс или электронной почты необходима дополнительная настройка. Теперь рассмотрим основные моменты системы AspNet Identity.