Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core
Иной подход к авторизации и аутентификации представляют универсальные провайдеры членства и ролей. Хотя в целом они предоставляют все тот же функционал, что и SimpleMembershipProvider и SimpleRolesProvider.
Шаблон Basic для проекта MVC 4 по умолчанию уже включает использование универсальных провайдеров. Если мы создадим новый проект по шаблону Basic, то мы можем увидеть в файле web.config:
<profile defaultProvider="DefaultProfileProvider"> <providers> <add name="DefaultProfileProvider" type="System.Web.Providers.DefaultProfileProvider, System.Web.Providers, Version=1.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=1.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=1.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=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" /> </providers> </sessionState>
Итак, создадим простейший механизм авторизации и аутентификации с помощью универсальных провайдеров на примере проекта с шаблоном Basic. (Нам не обязательно использовать именно шаблон Basic. Мы можем равным образом использовать и шаблоны Empty и Internet Application, только в этом случае нам необходимо будет добавить в проект пакет Microsoft.AspNet.Providers.)
Итак, создадим простейшее приложение по шаблону Basic, назовем его, например, UniversalProvidersApplication. По умолчанию он уже содержит определения применяемых провайдеров членства, профилей и ролей в файле web.config, как было показано выше.
Теперь добавим базу данных в папку App_Data, которая будет использоваться нашим приложением, назвав ее к примеру StoreDB.mdf, и изменим строку подключения в файле web.config:
<connectionStrings> <add name="DefaultConnection" providerName="System.Data.SqlClient" connectionString="Data Source=(LocalDB)\v11.0;AttachDbFilename='|DataDirectory|\StoreDB.mdf';Integrated Security=True" /> </connectionStrings>
Теперь создадим простейшую инфраструктуру для нашего проекта. В начале добавим модели логина и регистрации в папку Models:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.ComponentModel.DataAnnotations; namespace UniversalProvidersApplication.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] [StringLength(100, ErrorMessage = "Пароль должен иметь от 6 до 100 символов", MinimumLength = 6)] [DataType(DataType.Password)] [Display(Name = "Пароль")] public string Password { get; set; } [DataType(DataType.Password)] [Display(Name = "Подтвердить пароль")] [Compare("Password", ErrorMessage = "Пароли не совпадают.")] public string ConfirmPassword { get; set; } } }
Теперь нам нужен контроллер с действиями, который будет обрабатывать ввод пользователя и авторизовывать его, а также представления для ввода данных. Добавим контроллер AccountCotroller со следующим содержимым:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Security; using UniversalProvidersApplication.Models; namespace UniversalProvidersApplication.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 UniversalProvidersApplication.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 UniversalProvidersApplication.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> }
После запуска фреймворк создаст в БД ряд таблиц, предназначенных для хранения учетных записей, ролей и прочей информации, связанной с членством:
Зарегистрируем нового пользователя:
После этого введенная информация попадет в базу данных.