С появлением ASP.NET MVC 4 и WebMatrix команда mvc стремиться сделать вещи проще для разработчика. Исходя из отзывов одно из направлений для улучшения была выбрана безопасность asp.net.
ASP.NET MVC 4 шаблон проекта Internet добавил несколько новых очень полезных функций, которые построены с использованием SimpleMembership. SimpleMembership принес простую настройку ролей и пользователей, а также добавил поддержку OAuth. Однако новый провайдер не совместим с существующим ASP.NET Membership Provider.
В этом посте я расскажу о том, что такое SimpleMembership и как его использовать в проекте ASP.NET MVC 4.
Что такое SimpleMembership
- SimpleMembership разработан для замены предыдущей версии ASP.NET Membership Provider (ASP.NET Role)
- SimpleMembership решает те же самые задачи, но делает их проще для разработчика и приспосабливается к современным требованиям обеспечения безопасности
- Контроллер
AccountController
в шаблоне проекта Interner ASP.NET MVC 4 требует SimpleMembership и не совместим с использованем старых версий - Досадная новость в том, что Web Site Administration Tool (WSAT) не совместим с 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=ARCTURUSSQLEXPRESS;Initial Catalog=MembershipDemoDB;Integrated Security=True;Pooling=False" providerName="System.Data.SqlClient" />
</connectionStrings>
И определить инициализацию:
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "Users", "Id", "Name", autoCreateTables: true);
После запуска сайта и обработки атрибута инициализации SimpleMembership сам создат необходимые ему таблицы для работы. В качестве таблицы пользователей будет использоваться наша таблица Users.
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:
- AccountModel.cs описывает базовый аккаунт пользователя и включает атрибуты для базы данных
- InitializeSimpleMembershipAttribute.cs как раз содержит информацию для инициализации провайдера: какую базу данных использовать, какие поля и другие настройки.
- AccountController.cs содержит вызовы WebSecurity класс библиотеки WebMatrix.
WebSecurity работает с любым ExtendedMembershipProvider. По умолчанию используется SimpleMembershipProvider, однако можно реализовать свой.
Настройка SimpleMembership
Добавление SimpleMembership в существующий проект
Хотя этот провайдер работает по умолчанию в проекте с шаблоном ASP.NET MVC 4 Internet, некоторые (и я в том числе) создают проект с пустого шаблона. Необходимо добавить 2 ссылки: WebMatrix.Data и WebMatrix.WebData. Или установить эти библиотеки через NuGet с одноименными идентификаторами).
Теперь необходимо добавить провайдера и указать на использование 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;
if (!roles.RoleExists("Admin"))
{
roles.CreateRole("Admin");
}
if (membership.GetUser("Admin", false) == null)
{
membership.CreateUserAndAccount("Admin", "SuperAdminPassword");
}
if (!roles.GetRolesForUser("Admin").Contains("Admin"))
{
roles.AddUsersToRoles(new[] { "Admin" }, new[] { "Admin" });
}
}
public override void Down()
{
throw new NotImplementedException();
}
}
Или же можно напрямую в редакторе базы данных создать пользователя, роль и назначить пользователю роль.
Ссылки
- SimpleMembership, Membership Providers, Universal Providers and the new ASP.NET 4.5 Web Forms and ASP.NET MVC 4 templates
- Adding ASP.NET SimpleMembership to an existing MVC 4 application
- Using SimpleMembership With ASP.NET WebPages Matthew M. Osborn
- Seeding & Customizing ASP.NET MVC SimpleMembership
- Авторизация ASP.NET MVC (Почему не следует использовать MembershipProvider)
Автор: KLUBS