Мой сценарий, вероятно, противоположен большинству, я хочу РАЗРЕШИТЬ несколько одновременных входов в систему, но только для разных типов пользователей.
- Пользователь - имеет свою собственную область
- Администратор -Имеет свою собственную область
Проблема возникает из-за того, что администратор может быть также и пользователем (у них есть две учетные записи, это в основном так, что они могут проверить, как система работает от пользователя PoV) и хотятчтобы войти в оба одновременно.
При проверке подлинности с помощью форм это не представляется возможным.Поэтому мне пришлось немного «взломать» его и беспокоиться, что я мог что-то упустить.
План:
- Два фильтра действий для каждого типа пользователя: UserAuthorise & AdminAuthorise
- Наличие двух файлов cookie сеанса для каждого типа пользователя.
- Украсьте контроллеры, для которых правильный фильтр действий основан на том, какой пользователь может получить к нему доступ.
Код может нуждаться в некоторой очисткеup.
Я также сделаю имена файлов cookie более уникальными.
Исключены такие вещи, как Представления / Маршруты, поскольку они не кажутся релевантными.
Оставление пароля на выборке / хэширование образцов и привязка к тестовым значениям.
UserAuthorise:
public class UserAuthorize : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var authCookie = filterContext.RequestContext.HttpContext.Request.Cookies["User"];
if (authCookie == null || authCookie.Value == "")
{
filterContext.HttpContext.Response.Redirect("/login");
base.OnActionExecuting(filterContext);
return;
}
FormsAuthenticationTicket authTicket;
try
{
authTicket = FormsAuthentication.Decrypt(authCookie.Value);
}
catch
{
filterContext.HttpContext.Response.Redirect("/login");
base.OnActionExecuting(filterContext);
return;
}
if (authTicket.Expired || authTicket.Expiration <= DateTime.Now)
{
filterContext.HttpContext.Response.Redirect("/login");
}
base.OnActionExecuting(filterContext);
}
}
AdminAuthorise:
public class AdminAuthorise : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var authCookie = filterContext.RequestContext.HttpContext.Request.Cookies["Admin"];
if (authCookie == null || authCookie.Value == "")
{
filterContext.HttpContext.Response.Redirect("/admin/login");
base.OnActionExecuting(filterContext);
return;
}
FormsAuthenticationTicket authTicket;
try
{
authTicket = FormsAuthentication.Decrypt(authCookie.Value);
}
catch
{
filterContext.HttpContext.Response.Redirect("/admin/login");
base.OnActionExecuting(filterContext);
return;
}
if (authTicket.Expired || authTicket.Expiration <= DateTime.Now)
{
filterContext.HttpContext.Response.Redirect("/admin/login");
}
base.OnActionExecuting(filterContext);
}
}
Действие контроллера входа пользователя:
[HttpPost]
public virtual ActionResult Login(FormCollection form)
{
if (form["username"] == "admin" && form["password"] == "pass")
{
var authTicket = new FormsAuthenticationTicket(
1, // version
form["username"], // user name
DateTime.Now, // created
DateTime.Now.AddMinutes(20), // expires
false, // persistent?
"" // can be used to store roles
);
string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
var authCookie = new HttpCookie("User", encryptedTicket);
Response.Cookies.Add(authCookie);
// Redirect back to the page you were trying to access
return RedirectToAction(MVC.Home.Index());
}
else
{
ModelState.AddModelError("", "Bad info mate");
}
return View();
}
Действие контроллера входа администратора:
[HttpPost]
public virtual ActionResult Login(FormCollection form)
{
if (form["username"] == "admin" && form["password"] == "pass")
{
var authTicket = new FormsAuthenticationTicket(
1, // version
form["username"], // user name
DateTime.Now, // created
DateTime.Now.AddMinutes(20), // expires
false, // persistent?
"" // can be used to store roles
);
string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
var authCookie = new HttpCookie("Admin", encryptedTicket);
Response.Cookies.Add(authCookie);
// Redirect back to the page you were trying to access
return RedirectToAction(MVC.Admin.Home.Index());
}
else
{
ModelState.AddModelError("", "Bad info mate");
}
return View();
}
Все это кажетсяразумно и безопасно?
Просматривая в окне «Информация о странице» FireFox файлы cookie, я вижу, что каждый тип пользователя имеет свой собственный файл cookie, и вы не можете получить доступ к области типа пользователя без входа в систему.