5 марта 2011 г.

Интеграция Asp.Net MVC приложения с Membership

Если честно, то я никогда не понимал, почему многие так ругают ASP.Net Membership.

Мне эта штука нравится. Удобно и практично. Сегодня мы займемся тем, чтобы интегрировать механизмы мембершипа в наш проект. Тоесть, нам нужно связать нашу базу данных, с мембершипом, и обеспечить нормальное функционирование системы авторизации пользователей.

Для начала, нам понадобится пустой проект (с заранее созданной фабрикой контроллеров), простенькая база данных, и немного свободного времени. Итак, поехали...

Создадим минимальную базу данных theproject (в дальнейшем, мы будем ее частенько использовать), которая будет содержать всего 1 таблицу Persons, которая будет содержать дополнительные данные о пользователе (те, которые не входят в таблицы membership-а):

 Стоит заметить, что здесь, для ID пользователя, нужно использовать именно уникальный идентификатор, а не значение int с инкрементом. Почему так? Рассмотрим это попозже.

Сам по себе, Membership представляет собой набор связанных таблиц, которые и обеспечивают работу с пользователями и их ролями. Тоесть, все эти таблицы нам нужны в нашей базе данных. Самый простой способ создать все необходимые для работы с мембершипом таблицы, это чудесное средство aspnet_regsql, входящее в состав Framework 2.0.
Найти aspnet_regsql.exe можно приблизительно по такому пути: "C:\Windows\Microsoft.NET\Framework\v2.0.50727\aspnet_regsql.exe". После запуска необходимо проследовать нескольким, простым шагам.



Напомню, что данные действия приведут к созданию в нашей базе данных служебных таблиц, необходимых для работы с ASP.Net Membership. Результат можно посмотреть в management studio:

Для полноценной работы нам необходимо связать таблицы Persons и aspnet_Usres по полю ID. Вот именно здесь всплывает наш уникальный идентификатор. Дело в том, что в системной таблице aspnet_Users, поле UserID имеет тип уникального идентификатора, поэтому, для успешной связи, мы и сделали наше поле PersonID таким же.
Итак, создаем связь:


В принципе, с базой данных мы закончили. Дальше необходимо подключить ее к текущему проекту через web.config, прописав строку соединения. Поле этого наша система уже готова, и мы можем успешно создавать роли и новых пользователей через ASP.NET Configuration.

Мы пойдем немного дальше, и расширим функционал нашего приложения. Сделаем так, чтобы при попадании на страницу, пользователю выводились его личные данные. Причем, страница будет доступна только пользователям роли "Admin".

Начнем с того, что создадим новый файл LINQtoSQL:


Добавим в него 2, нужные нам, связанные таблицы:


Теперь схема данных готова, и нам осталось реализовать саму логику. А что же нам нужно? Нам нужно создать репозитий Person, в котором реализовать метод получения текущего пользователя. Затем, мы должны передать из контроллера в представление полученного пользователя в качестве модели данных. И последнее - отображаем данные на странице.

Класс PersonRepository:
public class PersonRepository
    {

        private theprojectDataContext m_DataContext;
        public PersonRepository(theprojectDataContext dataContext)
        {
            m_DataContext = dataContext;
        }

        public Person CurrentPerson()
        {
            return m_DataContext.Persons.SingleOrDefault(p => p.aspnet_User.UserName == Membership.GetUser().UserName);
        }

    }


В заранее созданном AdminController-е реализовываем экшн Index и доступ к контроллеру только пользователям роли "Admin":

[HandleError]
    [Authorize(Roles = "Admin")]
    public class AdminController : Controller
    {
        private readonly DataManager m_DataManager;
        public AdminController(DataManager dataManager)
        {
            m_DataManager = dataManager;
        }

        public ActionResult Index()
        {
            var p = m_DataManager.Persons.CurrentPerson();
           
            return View(p);
        }

    }


Ну и последний штрих - отображение данных модели в представлении Admin\Index:
    User login:
    <%= Model.aspnet_User.UserName %><br />
    Name:
    <%= Model.FirstName + " " + Model.LastName %><br />
    Age:
    <%= Model.Age %><br />
    From:
    <%=Model.Location %><br />


Вот и все. Можно запускать все это дело, и смотреть результат.

После запуска видим в меню вкладку "Admin".


Это та самая ссылка на закрытую от других страницу. Если мы попытаемся перейти по ней не залогинившись, то asp.net перебросит нас на страницу авторизации. После успешного входа в систему мы увидим свои личные данные:


Стоит заметить, что так как таблицы Persons и aspnetUsers связаны, то наша модель содержит данные из обеих таблиц. В данном примере, поле User Login взято из таблицы aspnetUsers.

_____
Скачать исходники(без базы данных) можно отсюда.