我有一个带有
Windows身份验证的MVC4应用程序.用户可以键入10个视图中任意一个的URL来加载应用程序.没有特定的主页
如果用户闲置超过一分钟,我需要重定向到会话超时视图.我将配置文件中的会话超时值保持为一分钟.我创建了一个动作过滤器来检查一个特定的会话值.此特定会话值在Global.asax的Session_Start中设置.
但是,当超时时间结束时,请求再次命中Session_Start并分配该值.因此我的动作过滤器不会重定向到错误视图.
有什么可能的解决方案来克服这个问题?
Web.Config中
<system.web> <!--Impersonate--> <identity impersonate="true"/> <!--Session Mode and Timeout--> <sessionState mode="InProc" timeout="1" /> <authentication mode="Windows"> </authentication> <authorization> <allow users="?" /> </authorization> </system.web>
动作过滤器
[AttributeUsage(AttributeTargets.Method,Inherited = true,AllowMultiple = false)] public class SessionCheckAttribute : ActionFilterAttribute { public override void OnActionExecuting(System.Web.Mvc.ActionExecutingContext filterContext) { string controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName.ToLower(); HttpSessionStateBase session = filterContext.HttpContext.Session; var activeSession = session["IsActiveSession"]; if (activeSession == null) { //Redirect var url = new UrlHelper(filterContext.RequestContext); var loginUrl = url.Content("~/Error/SessionTimeout"); filterContext.HttpContext.Response.Redirect(loginUrl,true); } } }
Global.asax中
protected void Session_Start(object sender,EventArgs e) { Session["IsActiveSession"] = DateTime.Now; }
解决方法
不要在动作过滤器中设置会话值并检查它,只需检查HttpContext.Current.Session.IsNewSession以查看是否为当前请求创建了新会话.修改你的动作过滤器,你最终会得到这样的结果:
[AttributeUsage(AttributeTargets.Method,AllowMultiple = false)] public class SessionCheckAttribute : ActionFilterAttribute { public override void OnActionExecuting(System.Web.Mvc.ActionExecutingContext filterContext) { string controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName.ToLower(); HttpSessionStateBase session = filterContext.HttpContext.Session; if (session.IsNewSession) { //Redirect var url = new UrlHelper(filterContext.RequestContext); var loginUrl = url.Content("~/Error/SessionTimeout"); filterContext.HttpContext.Response.Redirect(loginUrl,true); } } }
如果你想得到想象并确保他们在为此请求创建的新会话之前有一个先前的会话,你可以更新if语句以检查是否与请求一起发送了旧的会话cookie:
string cookieHeader = filterContext.HttpContext.Request.Headers["Cookie"]; if (session.IsNewSession && cookieHeader != null && cookieHeader.IndexOf("ASP.NET_SessionId") >= 0) { ... }
但由于看起来你正在将它们发送到登录页面,这可能不是你在这里需要担心的事情.如果您使用此检查,请注意此代码采用默认的“ASP.NET_SessionId”cookie名称;这可以在web.config中更改,在这种情况下,您需要使用新的cookie名称或get the cookie name programmatically更新IndexOf参数.