Универсальные провайдеры в MVC 5

Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core

Последнее обновление: 31.10.2015

Кроме стандартной системы ASP.NET Identity в MVC 5 также можно использовать и более традиционную для предыдущих версий систему аутентификации и авторизации - универсальные провайдеры. Универсальные провайдеры представляют собой провайдеры членства, ролей, профилей, сессии, которые имеют определенную реализацию по умолчанию. Но при желании мы можем их переопределить.

В проектах MVC 5 универсальные провайдеры по умолчанию отсутствуют, поэтому их надо добавлять через NuGet менеджер. Итак, создадим проект MVC 5 без аутентификации и добавим через NuGet пакет Microsoft.AspNet.Providers:

Универсальные провайдеры в ASP NET MVC 5

После установки в проекте в файле 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>
}

После запуска фреймворк создаст в БД ряд таблиц, предназначенных для хранения учетных записей, ролей и прочей информации, связанной с членством:

Зарегистрируем нового пользователя:

После этого введенная информация попадет в базу данных.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850