验证cookie和会话状态cookie是两个单独的cookie有什么好的理由吗?

时间:2011-05-20 01:19:57

标签: asp.net asp.net-mvc forms-authentication session-state

有什么理由说明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做什么并不需要太多猜测。

3 个答案:

答案 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或其他分布式进程外缓存系统将解决该问题。

虽然不完美,但由于缓存压力,条目可能被抛弃,当然你知道这无论如何都是个坏主意,所以我会跳过那个讲座。