Пишем код

Заметки о .net разработке

Простая кастомная ASP.Net MVC3-совместимая авторизация

2 комментария

Проблема — есть база пользователей с существующего проекта. Надо — авторизовать пользователей по этой базе из проекта на MVC3. Желательно минимумом усилий, но при этом с получением плюшек типа ограждения определенного функционала атрибутом [Authorize] от незарегистрированных :)

В гугле практически сразу натыкаешься на различные перегрузки MembershipProvider, но все примеры пугают своей монструозностью, обязательным использованием какой-нить-sql-compact и предоставлением возможности регистрации пользователей в придачу.

Если все это не требуется, а БД уже есть, или просто есть два-три пользователя, пароли которых можно просто захардкодить — то хочется получить всё максимально быстро. Этим мы и займемся.

Собственно, секрет прост. Для работы [Authorize] атрибутов по умолчанию используется FormsAuthentication и реализовывать MembershipProvider нам совсем и не нужно. Единственное, что нам потребуется — функция ValidateUser.

    public class MyAuthorizationService
    {
        public virtual bool ValidateUser(string username, string password)
        {
            if (username == "test" && password == "test")
            {
                return true;
            }
            return false;
        } 
    }

Думаю, как добавить в этот код своих юзеров — уже понятно :)
Если авторизационные данные берутся из БД, то можно в конструкторе MyAuthorizationService спокойненько запросить какой-нибудь UserRepository, например.

Чтобы атрибуты тип [Authorize] заработали, нам всё-таки необходимо написать контроллер, который эту авторизацию будет обрабатывать. Заодно мы увидим, как используется наш MyAuthorizationService

    public class AuthorizationModel
    {
        public string Login { get; set; }
        public string Password { get; set; }
        public string ReturnUrl { get; set; }
    }

    public class PartialUserInfo
    {
        public string Name { get; set; }
    }

    public class AccountController : Controller
    {
        private readonly AuthorizationService _authorizationService;

        public AccountController(AuthorizationService authorizationService)
        {
            _authorizationService = authorizationService; // запросили наш сервис авторизации для использования в контроллере
                                                          // я использую инъекцию зависимостей через Unity, при её отсутствии можно написать просто:
                                                          // _authorizationService = new AuthorizationService();
        }

        //
        // GET: /Account/
        [Authorize]  // Этот атрибут позволяет просматривать страничку /Account только авторизованным пользователям
                     // если при обращении к ней вы не авторизованы - вас редиректнет на /Account/LogOn
        public ActionResult Index()
        {
            return View();
        }


        [ChildActionOnly] // этот экшн сгенерит форму логина или покажет приветствие пользователя для уже авторизованных лиц
                          // использовать как @Html.RenderAction<AccountController>(x=>x.LogOnPartial());
        public ActionResult LogOnPartial(AuthorizationModel model = null)
        {
            if (User.Identity.IsAuthenticated)
            {
                return PartialView("PartialUserInfo", new PartialUserInfo { Name = User.Identity.Name });
            }


            return PartialView(model ?? new AuthorizationModel());
        }


        public ActionResult LogOut()
        {
            FormsAuthentication.SignOut(); // разлогиниваем текущего пользователя
            return View();
        }

        [HttpPost]
        public ActionResult LogOn(AuthorizationModel model)
        {
            if (_authorizationService.ValidateUser(model.Login, model.Password)) // валидируем пользователя
            {
                FormsAuthentication.SetAuthCookie(model.Login, true); // выставляем куки для авторизованных лиц
                if (!String.IsNullOrEmpty(model.ReturnUrl))
                {
                    return Redirect(model.ReturnUrl);
                }

                return RedirectToAction("Index");
            }

            ModelState.AddModelError("", "The user name or password provided is incorrect.");

            return View(model);
        }

        public ActionResult LogOn()
        {
            return View(new AuthorizationModel { ReturnUrl = Request.Params["ReturnUrl"] }); //показываем форму авторизации
        }

    }

Важные моменты прокомментированы, отдельно отмечу, что:

  • проверка верности логин\пароля производится с помощью AuthorizationService.ValidateUser(model.Login, model.Password);
  • «сохранение» факта авторизации — через FormsAuthentication.SetAuthCookie(model.Login, true);
  • и, наконец «выход» через FormsAuthentication.SignOut();

Если хочется совсем быстрого старта — можно просто скопипастить этот контроллер в свой проект и вставить в папку Views вашего Mvc проекта содержимое архива Account.zip. В нём хранятся вьюшки для приведенного выше контроллера.

В качестве демонстрации работы этого примера — полный проект сайта на MVC3. Состоит из всего, перечисленного в заметке, соединенного в единое приложение :)

Успехов :)

Опубликовать в Facebook
Опубликовать в Google Plus

Written by Shaddix

Июнь 10th, 2011 at 10:49 пп

Posted in .net,membership,MVC

2 комментария to 'Простая кастомная ASP.Net MVC3-совместимая авторизация'

Subscribe to comments with RSS or TrackBack to 'Простая кастомная ASP.Net MVC3-совместимая авторизация'.

  1. Не работает

    poll

    6 Апр 12 at 22:18

  2. Загрузил рабочий пример со всем, описанным в заметке: http://www.arturdr.ru/wp-content/uploads/2011/06/BasicAuth.zip

    Shaddix

    14 Апр 12 at 14:16

Leave a Reply