有什么理由说明ASP.NET的会话状态cookie和表单身份验证cookie是两个独立的cookie吗?如果我想把它们“捆绑”在一起怎么办?是否有可能以优雅的方式?
现在,我坚持使用以下解决方案,但仍然很难看:
[Authorize]
public ActionResult SomeAction(SomeModel model)
{
// The following four lines must be included in *every* controller action
// that requires the user to be authenticated, defeating the purpose of
// having the Authorize attribute.
if (SomeStaticClass.WasSessionStateLost/*?*/) {
FormsAuthentication.SignOut();
return RedirectToAction("Login", "Account");
}
// ...
}
@ RPM1984:这就是:
[HttpPost]
public ActionResult Login(LoginModel loginModel)
{
if (/* user ok */)
{
// ...
Session["UserID"] = loginModel.UserID;
Session["Password"] = loginModel.Password;
// ...
}
else
{
return View();
}
}
知道WasSessionStateLost
做什么并不需要太多猜测。
答案 0 :(得分:8)
会话!=身份验证
会话状态cookie在浏览器会话期间跟踪用户的活动。
表单身份验证Cookie会在给定时间段内跟踪用户的经过身份验证的活动,该时间由故障单的到期日期指定,以及您是否已创建持久性Cookie(例如“记住我”复选框) )。
您不应该触及会话cookie本身,它包含的所有内容都是将客户端会话(浏览器)绑定到服务器的标识符。
如果您需要访问会话,请使用HttpContext.Current.Session
。
你到底想要什么“捆绑”在一起?
SomeStaticClass.WasSessionStateLost
做什么?
答案 1 :(得分:2)
我将从解决方案开始,然后是解释,然后是建议。
创建自定义授权属性:
由于您的应用程序定义Authorized
如下:
Session["UserID"]
和Session["Password"]
您需要定义自己的AuthorizationAttribute
public class AuthorizedWithSessionAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if(httpContext.Request.IsAuthenticated &&
Session["UserID"] != null && Session["Password"] != null)
return true;
// sign them out so they can log back in with the Password
if(httpContext.Request.IsAuthenticated)
FormsAuthentication.SignOut();
return false;
}
}
将所有[Authorize]
属性替换为[AuthorizedWithSession]
,您不需要在控制器中添加会话检查代码。
我对您的应用程序了解不多,但在会话中保存密码(更简单的是以纯文本形式保存)并不安全。
此外,正如RPM1984
所述,会话cookie和身份验证cookie是分开的。
<强>解释强>
将会话视为一个信息桶(在服务器端),并在其上显示您的名称。 ASP.NET可以将内容放入该存储桶中。 ASP.NET为您提供了一个名称,您的会话ID,并将其放在存储桶中,以便知道哪一个属于您的。
身份验证cookie告诉ASP.NET您已经过身份验证并将身份验证名称存储在其中。身份验证名称通常由应用程序的开发人员设置,通常是一个唯一的密钥(在数据库中考虑主键),以便将您与其他用户分开。
建议更安全:
在存储密码之前加密密码。这不是完全安全,但它以明文形式存储密码,当然,如果有人要获取加密密钥,他们可以破解密码。
答案 2 :(得分:1)
而不是使用短暂的会话,你可以在System.Web.Cache中缓存。通过此操作,您可以添加在删除条目之前调用的事件,并相应地决定是否应清除缓存。您可以在其上设置更高的超时值,并且您不会在任何地方将明文密码存储在文件或数据库中。另一个好处是你不会受到会话劫持的攻击。</ p>
当然,如果应用程序池循环使用缓存已经消失,并且因为它在内存中负载均衡的计算机将不同步,但Velocity或其他分布式进程外缓存系统将解决该问题。
虽然不完美,但由于缓存压力,条目可能被抛弃,当然你知道这无论如何都是个坏主意,所以我会跳过那个讲座。