При попытке выхода из системы, предоставленный токен анти-подделки предназначен для пользователя "XXXX", но текущий пользователь ""
У меня есть приложение MVC 4 и возникают проблемы, когда сеанс форм заканчивается, а затем пользователь пытается выйти из системы.
Ex.
таймаут установлен на 5 мин.
Пользователь входит в систему.
Пользователь ничего не делает в течение 10 минут.
Пользователь нажимает на ссылку LogOff.
Пользователь получает ошибку: "Предоставленный токен анти-подделки предназначен для пользователя" XXXX ", но текущий пользователь" ".
Затем пользователю пришлось пройти через какую-то гимнастику, чтобы обойти это, чтобы они могли снова войти в систему, а затем снова выйти из системы (выход из системы закрывается на время).
Я думаю, я понимаю, почему это происходит... но не уверен, как это исправить.
EDIT:
Почему я думаю, что это происходит потому, что изначально, когда страница загружается, токен AntiForgery создается для текущего пользователя. Но тогда, когда сессия истекает, и они пытаются перейти на страницу выхода из системы, текущий пользователь "вместо" фактического пользователя. Таким образом, существует несоответствие и ошибка отображается.
Ответы
Ответ 1
На самом деле вы можете обрабатывать его с помощью 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.
Ответ 2
Ответ @cem был действительно полезен для меня, и я добавил небольшое изменение, чтобы включить сценарий аякс-вызовов с antiforgerytoken и истекшим сеансом.
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;
}
}
... и на стороне клиента вы можете добавить глобальный обработчик ошибок ajax для перенаправления на экран входа...
$.ajaxSetup({
error: function (x) {
if (x.status === 403) {
window.location = "/Account/Login";
}
}
});