Руководство SimpleMembership в ASP.NET MVC 4

Что такое SimpleMembership

Система ASP.NET Membership System была представлена в 2005 году. Она была разработана для решения общих задач, таких как регистрации на сайте с использованием связки логина и пароля, хранения профиля в базе данных SQL Server. Также были добавлены механизмы расширения, позволяющие переопределить стандартную логику работы MembershipProvider и RoleProvider. 8 лет назад этот механизм справлялся со своей задачей, но сегодня это неудобный инструмент. Если профилю пользователя требуются дополнительные поля, то все они хранятся в одной колонке и для доступа требуют вызовов API соответствующего провайдера.

В ASP.NET WebPages и WebMatrix по новому представлены многие вещи, например движок представлений Razor и SimpleMembership.

Почему использование ASP.NET Membership не рекомендуется

Стандартный провайдер прекрасно работает, если выполняются следующие условия: вся информация будет храниться в полной версии базы данных SQL Server и то, что все необходимые данны представлены в виде набора атрибутов (UserName, Password, IsApproved, CreationDate…) и другая информация будет предоставлена используя Profile Provider. 

Требуется полный SQL Server по умолчанию

Большинство полнофункциональных провайдеров ASP.NET требуют полную версию SQL Server (т.к. опираются на работу хранимых процедур, на кеш SQL Server и другие возможности сервера). Кроме того, провайдеры по умолчанию не будут работать на SQL Azure.

Трудности работы с другой базой данных

Для работы с базой данных отличной от SQL Server необходимо переопределить набор методов провайдера, которые сильно ориентированы на хранение данных в реляционной базе данных. Во-первых это большой объем работы по переопределению этих методов, а во-вторых скорее всего останется множество неопределенных методов, содержащих System.NotImplementedException, что не красит код.

Ориентация на модель Пользователь > Роль

Существующие поставщики данных строго ориентированы на эту модель, в которой пользователь имеет логин и пароль. Конечно, дополнительные сведения могут быть добавлены через API, но такая модель не подходит для OAuth (там пользователь не имеет пароля). 

Система ориентирована на роли не всегда будет уместна, бывает удобнее использовать модель прав доступа к отдельным объектам или действиям (Claims)

Также требуется жестка схема базы данных с большим количеством blob колонок.

SimpleMembership улучшенная система пользователей

SimpleMembership был разработан как раз для решения проблем, озвученных выше. 

Matthew Osborn в своей записи Using SimpleMembership With ASP.NET WebPages объясняет, что SimpleMembership разработан, чтобы легко интегрироваться с вашей базой данных.

SimpleMembership требует, чтобы было 2 колонки в таблице пользователей: “ID” и “UserName”. Важная часть здесь, что эти колонки могут иметь любые названия.

Схема таблицы пользователи

 Теперь необходимо рассказать об этом SimpleMembership: добавить строку подключения к базе данных.

<connectionStrings>
    <add name=“DefaultConnection” connectionString=“Data Source=ARCTURUS\SQLEXPRESS;Initial Catalog=MembershipDemoDB;Integrated Security=True;Pooling=False” providerName=“System.Data.SqlClient” />
  </connectionStrings>

 И определить инициализацию:

WebSecurity.InitializeDatabaseConnection(“DefaultConnection”, “Users”, “Id”, “Name”, autoCreateTables: true);

После запуска сайта и обработки атрибута инициализации SimpleMembership сам создат необходимые ему таблицы для работы. В качестве таблицы пользователей будет использоваться наша таблица Users.

SimpleMembership создал таблицы

SimpleMembership работает со всей линейкой SQL Server (SQL Azure, SQL Server CE, SQL Server Express и LocalDB). Все реализовано как вызовы SQL, что здесь гораздо лучше, чем использование хранимых процедур.

Использование EntityFramework с Code First

Проблема с ASP.NET Membership в том, что она хранит дополнительную информацию об аккаунте сама. Это значит, что нельзя напрямую получить доступ к данным профиля. В том время как SimpleMembership все равно, в какой таблице и как хранятся данные пользователя. Можно легко изменить таблицу с пользователями, например добавить адрес.

[Table(“Users”)]
public class UserProfile
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public string Name { get; set; }

public string Address { get; set; }

}

Теперь можно легко получить доступ к этому полю не используя сам провайдер, а напрямую из базы данных. Это позволяет принимать SimpleMembership как прослойку между базой данных и системой ASP.NET Membership.

Как он реализован я опущу, можно посмотреть в оригинальной записи SimpleMembership. Важно знать, что SimpleMembership унаследован от ExtendedMembershipProvider.

ASP.NET MVC 4 Internet template

В шаблоне по умолчанию реализован следующий механизм работы с SimpleMembership:

ASP.NET MVC 4 Internet template

WebSecurity работает с любым ExtendedMembershipProvider. По умолчанию используется SimpleMembershipProvider, однако можно реализовать свой.

Настройка SimpleMembership

Добавление SimpleMembership в существующий проект

Хотя этот провайдер работает по умолчанию в проекте с шаблоном ASP.NET MVC 4 Internet, некоторые (и я в том числе) создают проект с пустого шаблона. Необходимо добавить 2 ссылки: WebMatrix.Data и WebMatrix.WebData. Или установить эти библиотеки через NuGet с одноименными идентификаторами).

WebMatrix data

 

Теперь необходимо добавить провайдера и указать на использование WebMatrix

    <roleManager enabled=“true” defaultProvider=“SimpleRoleProvider”>
      <providers>
        <clear />
        <add name=“SimpleRoleProvider” type=“WebMatrix.WebData.SimpleRoleProvider,WebMatrix.WebData” />
      </providers>
    </roleManager>
    <membership defaultProvider=“SimpleMembershipProvider”>
      <providers>
        <clear />
        <add name=“SimpleMembershipProvider” type=“WebMatrix.WebData.SimpleMembershipProvider, WebMatrix.WebData” />
      </providers>
    </membership>

Так как WSAT использовать не получится, есть 2 способа создания пользователей и ролей. Если используется модель EntityFramework Code First, удобно будет добавить Micragion с созданием пользователей по умолчанию:

public partial class AddDefaultUser : DbMigration
{
    public override void Up()
    {
        if (!WebSecurity.Initialized)
        {
            WebSecurity.InitializeDatabaseConnection(“DefaultConnection”, “Users”, “Id”, “UserName”,
                autoCreateTables:
                    true);
        }

    var roles = (SimpleRoleProvider)Roles.Provider;
    var membership = (SimpleMembershipProvider)Membership.Provider;

    <span class="keyword">if</span> (!roles.RoleExists(<span class="string">"Admin"</span>))
    {
        roles.CreateRole("Admin");
    }
    <span class="keyword">if</span> (membership.GetUser(<span class="string">"Admin"</span>, <span class="built_in">false</span>) == null)
    {
        membership.CreateUserAndAccount("Admin", <span class="string">"SuperAdminPassword"</span>);
    }
    <span class="keyword">if</span> (!roles.GetRolesForUser(<span class="string">"Admin"</span>).Contains(<span class="string">"Admin"</span>))
    {
        roles.AddUsersToRoles(new[] { "Admin" }, new[] { "Admin" });
    }

}

public override void Down()
{
    throw new NotImplementedException();
}

}

Или же можно напрямую в редакторе базы данных создать пользователя, роль и назначить пользователю роль.

Ссылки

Комментарии

comments powered by Disqus