我的情况可能与大多数人相反,我希望允许多个用户同时登录,但仅限于不同类型的用户。
- 用户-拥有自己的区域
- 管理员-拥有自己的区域
问题在于管理员也可以是用户(他们有两个帐户,这主要是为了能够从用户角度检查系统正在运行的情况),并且希望同时登录两个帐户。
使用表单身份验证时,似乎无法做到这一点。所以我不得不“黑客”一下,并担心我可能会忽略某些东西。
计划:
- 每种类型的用户有两个操作过滤器:UserAuthorise和AdminAuthorise
- 每种类型的用户有两个会话cookie
- 根据哪个用户可以访问它,修饰控制器的正确操作过滤器。
代码可能需要进行一些整理。
我还将使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);
}
}
管理员授权:
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,您无法在未登录情况下访问用户类型区域。