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

Cha*_*son 18 c# asp.net-mvc

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

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

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

我想我明白为什么会发生这种情况......但不知道如何解决这个问题.

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

cem*_*cem 25

实际上你可以处理它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() 
{
}
Run Code Online (Sandbox Code Playgroud)

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


Jav*_*ier 5

@cem 的答案对我真的很有帮助,我添加了一个小的更改,以包括使用 antiforgerytoken 和过期会话的 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

...在客户端,您可以添加一个全局 ajax 错误处理程序以重定向到登录屏幕...

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