我正在努力设置/更正我的会话超时代码,并咨询了许多文章,例如this one和this 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超时值相同吗?
答案 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);
}
}