MVC 4 предоставил маркер защиты от подделки, предназначенный для пользователя "", но текущий пользователь "пользователь"
Недавно я выпустил Live веб-приложение, созданное с использованием MVC 4 и Entity Framework 5. Приложение MVC использует Razor Views.
Используя Elmah, я заметил, что когда пользователи входят в приложение, иногда они получают следующую ошибку
The provided anti-forgery token was meant for user "" but the current user is "user"
Я уже провел небольшое исследование о том, как решить эту проблему, но мне кажется, что ничего не работает. Пожалуйста, смотрите мой вид входа в систему и соответствующие действия контроллера ниже.
Razor View
@if (!HttpContext.Current.User.Identity.IsAuthenticated)
{
using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<div class="formEl_a">
<fieldset>
<legend>Login Information</legend>
<div class="lbl_a">
Email
</div>
<div class="editor-field">
@Html.TextBoxFor(m => m.Email, new { @class = "inpt_a" })<br />
@Html.ValidationMessageFor(m => m.Email)
</div>
<div class="lbl_a">
@Html.LabelFor(m => m.Password)
</div>
<div class="editor-field sepH_b">
@Html.PasswordFor(m => m.Password, new { @class = "inpt_a" })<br />
@Html.ValidationMessageFor(m => m.Password)
</div>
</fieldset>
</div>
<br />
<p>
<input type="submit" value="Log In" class="btn btn_d sepV_a" />
</p>
}
}
контроллер
[AllowAnonymous]
public ActionResult Login()
{
return View();
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
if (ModelState.IsValid && _accountService.Logon(model.Email, model.Password, true))
{
//Validate
}
else
{
// inform of failed login
}
}
Я думал, что все это выглядело хорошо, но ошибка все еще сохраняется. У кого-нибудь есть идеи, как решить эту проблему?
Ваша помощь очень ценится.
Благодарю.
3 ответа
Я полагаю, что это происходит, потому что пользователи дважды щелкают кнопку отправки в форме. По крайней мере, это именно так на моем сайте.
Код проверки, который запускается для AntiForgeryToken, также проверяет, что ваши учетные данные вошедшего в систему пользователя не изменились - они также зашифрованы в файле cookie. Это означает, что если вы вошли в систему или вышли из нее во всплывающем окне или на другой вкладке браузера, отправка формы завершится неудачей со следующим исключением:
System.Web.Mvc.HttpAntiForgeryException (0x80004005):
The provided anti-forgery token was meant for user "", but the current user is "SomeOne".
Вы можете отключить это, поставив AntiForgeryConfig.SuppressIdentityHeuristicChecks = true;
в Application_Start
метод внутри Global.asax
файл.
Если AntiForgeryToken не проверяет ваш сайт, выдается исключение типа System.Web.Mvc.HttpAntiForgeryException
, Вы можете сделать это немного проще, по крайней мере, предоставив пользователю более информативную страницу, нацеленную на эти исключения, перехватив исключение HttpAntiForgeryException.
private void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
if (ex is HttpAntiForgeryException)
{
Response.Clear();
Server.ClearError(); //make sure you log the exception first
Response.Redirect("/error/antiforgery", true);
}
}
Больше информации:
Html.AntiForgeryToken - баланс безопасности с удобством использования
У меня была такая же проблема, когда
- Пользователь входит в систему
- Затем на домашней странице пользователь нажимает кнопку "Назад", чтобы вернуться в систему.
- Пользователь входит в систему как другой пользователь
- Это дало исключение: предоставленный токен защиты от подделки был предназначен для пользователя "", но текущий пользователь - "пользователь"
Я обнаружил, что это происходит только в IE, и я исправил это, выполнив несколько вещей
- Отключено кэширование вывода для страницы входа в систему, потому что в режиме отладки я обнаружил, что нажатие кнопки назад не генерирует новый запрос к странице входа
На странице входа в систему я добавил проверку, чтобы убедиться, что пользователь уже прошел проверку подлинности и, если это так, вышел из системы, а затем снова перенаправлен на страницу входа.
[AllowAnonymous] [OutputCache(NoStore=true, Location=System.Web.UI.OutputCacheLocation.None)] public ActionResult Login) { if (HttpContext.Request.IsAuthenticated) { WebSecurity.Logout(); Session.Abandon(); return RedirectToAction("Login"); } return View(); }