ASP.NET:Session.IsNewSession在表单超时后为false,但应该为true?

时间:2010-12-09 18:39:51

标签: asp.net session-timeout

我正在努力设置/更正我的会话超时代码,并咨询了许多文章,例如this onethis SO post,以了解如何最好地执行此操作。我继续反复检测会话超时的解决方案是首先检查Session.IsNewSession属性是否为true,如果是,则检查会话cookie是否已存在。我想这里的逻辑是用户已经结束了他们的最后一次会话超时,开始了一个新的会话,但旧的cookie还没有删除。这些检查的代码如下所示:

if (Context.Session != null)
{
    if (Session.IsNewSession)
    {
        string szCookieHeader = Request.Headers["Cookie"];
        if ((null != szCookieHeader) && (szCookieHeader.IndexOf("ASP.NET_SessionId") >= 0))
        {
            Response.Redirect("sessionTimeout.htm"); // or whatever code to handle timeout
        }  
    } 
}

现在我正在使用会话超时值120分钟,并且表单超时值为60分钟。我的web.config文件中的这两行分别在这里:

<sessionState mode="InProc" cookieless="UseDeviceProfile" timeout="120" />
<authentication mode="Forms">
    <forms loginUrl="~/Home/Customer" timeout="60" name=".ASPXAUTH" requireSSL="false" slidingExpiration="true" defaultUrl="~/Home/Index" cookieless="UseDeviceProfile" enableCrossAppRedirects="false"/>
</authentication>

所以在60分钟后(我将其设置为1进行测试),我向服务器发出请求,并且我会自动重定向到/ Home / Customer,我假设由于我的网络中的'loginURL'值。配置行。

问题是会话没有结束,我的所有会话超时检查都在Home / Customer操作中(我使用MVC)。所以我被重定向到Home / Customer,并且我完成了上面的检查,但是当我到达Session.IsNewSession时,它是假的,因为会话仍然存在(我假设因为我仍然在120分钟内设定)。

所以,最后,我的问题。整个会话超时检查方案是否仅在实际会话超时时才有效?或者我可以使它适用于 Forms 超时吗?也许解决方案是将Session会话超时值设置为与Forms超时值相同吗?

2 个答案:

答案 0 :(得分:2)

ASP.NET会话cookie和Forms身份验证cookie实际上是完全不同的cookie - 例如,如果您的应用程序池回收,您的用户将丢失其会话但不会丢失其登录标识(假设您正在使用进程内会话) )。我认为,您的代码被击中的唯一方法是,如果您的会话超时小于表单超时。任何其他方式,您将在您点击会话超时代码之前被重定向到登录页面。

另一种选择是将会话超时代码移动到您的登录页面。

第三种方法是在global.asax中处理检查。

答案 1 :(得分:0)

我刚刚对用户 John Christensen 所说的用户进行了一些测试

  

如果您的会话超时小于表单超时。

<强>的web.config

<system.web>
    <sessionState mode="InProc" timeout="1" />
    <authentication mode="Forms">
      <forms loginUrl="~/Account/Login"  defaultUrl="~/Account/Login" name="MyPortalAuth" timeout="2" />
    </authentication>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />
  </system.web>

似乎它正在起作用。

C#过滤器属性

public class SessionExpireFilterAttribute : ActionFilterAttribute
    {
        public UserManager<ApplicationUser> UserManager { get; private set; }

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var ctx = HttpContext.Current;

            // check if session is supported
            if (ctx.Session != null)
            {
                // check if a new session id was generated
                if (ctx.Session.IsNewSession)
                {
                    // If it says it is a new session, but an existing cookie exists, then it must
                    // have timed out
                    string sessionCookie = ctx.Request.Headers["Cookie"];
                    if ((null != sessionCookie) && (sessionCookie.IndexOf("ASP.NET_SessionId") >= 0))
                    {

                        if (ctx.Request.IsAuthenticated)
                        {
                            FormsAuthentication.SignOut();
                        }
                        RedirectResult rr = new RedirectResult(loginUrl);
                        filterContext.Result = rr;
                        //ctx.Response.Redirect("~/Account/Logon");

                    }
                }                
            }

            base.OnActionExecuting(filterContext);
        }
    }