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, и я исправил это, выполнив несколько вещей

  1. Отключено кэширование вывода для страницы входа в систему, потому что в режиме отладки я обнаружил, что нажатие кнопки назад не генерирует новый запрос к странице входа
  2. На странице входа в систему я добавил проверку, чтобы убедиться, что пользователь уже прошел проверку подлинности и, если это так, вышел из системы, а затем снова перенаправлен на страницу входа.

    [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();
    }
    
Другие вопросы по тегам