MVC 4 предоставил токен анти-подделки для пользователя ", но текущий пользователь является" пользователем",

Недавно я установил Live web-приложение, которое было создано с использованием MVC 4 и Entity Framework 5. Приложение MVC использует Razor Views.

Я заметил использование Elmah, когда пользователи регистрируются в приложении, иногда они получают следующую ошибку

The provided anti-forgery token was meant for user "" but the current user is "user"

Я уже немного поработал над тем, как исправить эту проблему, но ничего не работает для меня. См. Мой Вход в систему и соответствующие Действия с контроллером ниже.

Просмотр бритвы

@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
      }

}

Я думал, все это выглядит нормально, но ошибка сохраняется. Есть ли идеи о том, как исправить эту проблему?

Ваша помощь с благодарностью.

Спасибо.

Ответ 2

Код проверки, который работает с 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 - Балансировка безопасности с удобством использования

Ответ 3

У меня была та же проблема, когда

  • Пользователь регистрируется в
  • Затем на домашней странице Пользователь нажимает кнопку "Назад", чтобы вернуться в "Вход"
  • Пользователь регистрируется как другой пользователь
  • Это дало исключение: предоставленный токен анти-подделки предназначался для пользователя ", но текущий пользователь" пользователь"

Я обнаружил, что это происходит только в 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();
    }