Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core
Кроме стандартной системы ASP.NET Identity в MVC 5 также можно использовать и более традиционную для предыдущих версий систему аутентификации и авторизации - универсальные провайдеры. Универсальные провайдеры представляют собой провайдеры членства, ролей, профилей, сессии, которые имеют определенную реализацию по умолчанию. Но при желании мы можем их переопределить.
В проектах MVC 5 универсальные провайдеры по умолчанию отсутствуют, поэтому их надо добавлять через NuGet менеджер. Итак, создадим проект MVC 5 без аутентификации и добавим через NuGet пакет Microsoft.AspNet.Providers:
После установки в проекте в файле web.config произойдет несколько изменений. Во-первых, будут добавлены определения провайдеров в узле system.web
:
<profile defaultProvider="DefaultProfileProvider"> <providers> <add name="DefaultProfileProvider" type="System.Web.Providers.DefaultProfileProvider, System.Web.Providers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" /> </providers> </profile> <membership defaultProvider="DefaultMembershipProvider"> <providers> <add name="DefaultMembershipProvider" type="System.Web.Providers.DefaultMembershipProvider, System.Web.Providers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" /> </providers> </membership> <roleManager defaultProvider="DefaultRoleProvider"> <providers> <add name="DefaultRoleProvider" type="System.Web.Providers.DefaultRoleProvider, System.Web.Providers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" /> </providers> </roleManager> <sessionState mode="InProc" customProvider="DefaultSessionProvider"> <providers> <add name="DefaultSessionProvider" type="System.Web.Providers.DefaultSessionStateProvider, System.Web.Providers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" /> </providers> </sessionState>
Также будет добавлена строка подключения. И кроме того, чтобы задействовать универсальные провайдеры, нам надо добавить в узел system.web
поддержку аутентификации форм:
<authentication mode="Forms"> <forms name="cookies" loginUrl="~/Account/Login" /> </authentication>
И теперь за аутентификацию и авторизацию будут отвечать универсальные провайдеры. Теперь добавим инфраструктуру для нашего проекта. В начале добавим модели логина и регистрации в папку Models:
public class LogOnModel { [Required] [Display(Name = "Логин")] public string UserName { get; set; } [Required] [DataType(DataType.Password)] [Display(Name = "Пароль")] public string Password { get; set; } [Display(Name = "Запомнить")] public bool RememberMe { get; set; } } public class RegisterModel { [Required] [Display(Name = "Логин")] public string UserName { get; set; } [Required] [DataType(DataType.EmailAddress)] [Display(Name = "Электронная почта")] public string Email { get; set; } [Required] [DataType(DataType.Password)] [Display(Name = "Пароль")] public string Password { get; set; } [DataType(DataType.Password)] [Display(Name = "Подтвердить пароль")] [Compare("Password", ErrorMessage = "Пароли не совпадают.")] public string ConfirmPassword { get; set; } }
Также добавим в папку Controllers контроллер AccountCotroller со следующим содержимым:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Security; using UniversalProviderApp.Models; namespace UniversalProviderApp.Controllers { [AllowAnonymous] public class AccountController : Controller { public ActionResult Login() { return View(); } [HttpPost] public ActionResult Login(LogOnModel model, string returnUrl) { if (ModelState.IsValid) { if (Membership.ValidateUser(model.UserName, model.Password)) { FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe); if (Url.IsLocalUrl(returnUrl)) { return Redirect(returnUrl); } else { return RedirectToAction("Index", "Home"); } } else { ModelState.AddModelError("", "Неправильный пароль или логин"); } } return View(model); } public ActionResult LogOff() { FormsAuthentication.SignOut(); return RedirectToAction("Login", "Account"); } public ActionResult Register() { return View(); } [HttpPost] public ActionResult Register(RegisterModel model) { if (ModelState.IsValid) { MembershipCreateStatus createStatus; Membership.CreateUser(model.UserName, model.Password, model.Email, passwordQuestion: null, passwordAnswer: null, isApproved: true, providerUserKey: null, status: out createStatus); if (createStatus == MembershipCreateStatus.Success) { FormsAuthentication.SetAuthCookie(model.UserName, false); return RedirectToAction("Index", "Home"); } else { ModelState.AddModelError("","Ошибка при регистрации"); } } return View(model); } } }
При регистрации пользователя с помощью метода Membership.CreateUser
новый пользователь добавляется в БД,
а затем осуществляем вход с помощью метода FormsAuthentication.SetAuthCookie()
, который устанавливает куки.
При логине метод Membership.ValidateUser
проверяет, имеется ли в базе данных пользователь с введенными логином и паролем в системе.
Теперь создадим необходимые представления. Представление регистрации Register.cshtml:
@model UniversalProviderApp.Models.RegisterModel @{ ViewBag.Title = "Регистрация"; } <h2>Регистрация</h2> @using (Html.BeginForm()) { @Html.ValidationSummary(true) <fieldset> <legend>Введите данные</legend> <div class="editor-label"> @Html.LabelFor(model => model.UserName) </div> <div class="editor-field"> @Html.EditorFor(model => model.UserName) @Html.ValidationMessageFor(model => model.UserName) </div> <div class="editor-label"> @Html.LabelFor(model => model.Email) </div> <div class="editor-field"> @Html.EditorFor(model => model.Email) @Html.ValidationMessageFor(model => model.Email) </div> <div class="editor-label"> @Html.LabelFor(model => model.Password) </div> <div class="editor-field"> @Html.EditorFor(model => model.Password) @Html.ValidationMessageFor(model => model.Password) </div> <div class="editor-label"> @Html.LabelFor(model => model.ConfirmPassword) </div> <div class="editor-field"> @Html.EditorFor(model => model.ConfirmPassword) @Html.ValidationMessageFor(model => model.ConfirmPassword) </div> <p> <input type="submit" value="Зарегистрировать" /> </p> </fieldset> }
И представление логина Login.cshtml:
@model UniversalProviderApp.Models.LogOnModel @{ ViewBag.Title = "Вход в систему"; } <h2>Вход в систему</h2> @using (Html.BeginForm()) { @Html.ValidationSummary(true) <fieldset> <legend>Введите логин и пароль</legend> <div class="editor-label"> @Html.LabelFor(model => model.UserName) </div> <div class="editor-field"> @Html.EditorFor(model => model.UserName) @Html.ValidationMessageFor(model => model.UserName) </div> <div class="editor-label"> @Html.LabelFor(model => model.Password) </div> <div class="editor-field"> @Html.EditorFor(model => model.Password) @Html.ValidationMessageFor(model => model.Password) </div> <div class="editor-label"> @Html.LabelFor(model => model.RememberMe) </div> <div class="editor-field"> @Html.EditorFor(model => model.RememberMe) @Html.ValidationMessageFor(model => model.RememberMe) </div> <p> <input type="submit" value="Войти" /> </p> </fieldset> }
После запуска фреймворк создаст в БД ряд таблиц, предназначенных для хранения учетных записей, ролей и прочей информации, связанной с членством:
Зарегистрируем нового пользователя:
После этого введенная информация попадет в базу данных.