尝试注销时,提供的防伪令牌适用于用户“XXXX”,但当前用户为“”

我有一个MVC 4应用程序,并在表单会话到期时遇到问题,然后用户尝试注销。

防爆。 超时设置为5分钟。 用户登录。用户10分钟不做任何事情。 用户单击LogOff链接。 用户收到错误:“提供的防伪令牌适用于用户”XXXX“,但当前用户为”“。

然后用户必须通过一些体操来解决这个问题,以便他们可以重新登录然后重新注销(注销正用于关闭当天的时间卡)。

我想我明白为什么会这样……但不知道如何解决它。

编辑:为什么我认为发生这种情况是因为最初加载页面时,会为当前登录的用户生成AntiForgery令牌。 但是当会话到期并且他们尝试导航到注销页面时,当前用户是“”而不是实际用户。 因此,存在不匹配并且呈现错误。

实际上你可以使用IExceptionFilter处理它,它将重定向到/Account/Login

 public class HandleAntiForgeryError : ActionFilterAttribute, IExceptionFilter { #region IExceptionFilter Members public void OnException(ExceptionContext filterContext) { var exception = filterContext.Exception as HttpAntiForgeryException; if (exception != null) { var routeValues = new RouteValueDictionary(); routeValues["controller"] = "Account"; routeValues["action"] = "Login"; filterContext.Result = new RedirectToRouteResult(routeValues); filterContext.ExceptionHandled = true; } } #endregion } [HandleAntiForgeryError] [ValidateAntiForgeryToken] public ActionResult LogOff() { } 

您也可以使用[HandleError(ExceptionType=typeof(HttpAntiForgeryException)...]但它需要customErrors On。

@cem的答案对我来说真的很有帮助,我添加了一个小小的改动,包括使用antiforgerytoken和expired session的ajax调用的场景。

 public void OnException(ExceptionContext filterContext) { var exception = filterContext.Exception as HttpAntiForgeryException; if (exception == null) return; if (filterContext.HttpContext.Request.IsAjaxRequest()) { filterContext.HttpContext.Response.StatusCode = 403; filterContext.ExceptionHandled = true; } else { var routeValues = new RouteValueDictionary { ["controller"] = "Account", ["action"] = "Login" }; filterContext.Result = new RedirectToRouteResult(routeValues); filterContext.ExceptionHandled = true; } } 

…在客户端,您可以添加全局ajaxerror handling程序以重定向到登录屏幕…

 $.ajaxSetup({ error: function (x) { if (x.status === 403) { window.location = "/Account/Login"; } } });