Проблема — есть база пользователей с существующего проекта. Надо — авторизовать пользователей по этой базе из проекта на 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. Состоит из всего, перечисленного в заметке, соединенного в единое приложение :)
Успехов :)
Не работает
Загрузил рабочий пример со всем, описанным в заметке: http://www.arturdr.ru/wp-content/uploads/2011/06/BasicAuth.zip