Использование универсальных провайдеров

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

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

Иной подход к авторизации и аутентификации представляют универсальные провайдеры членства и ролей. Хотя в целом они предоставляют все тот же функционал, что и 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>
}

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

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

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

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