Анти-поддельный токен предназначался для другого пользователя на основе требований

Я работаю над функцией выхода из системы в приложении, в котором используется идентификатор входа в ASP.NET. Я могу войти в систему успешно, но когда я выхожу из системы, а затем попробую войти в систему, я получаю следующее сообщение:

The provided anti-forgery token was meant for a different claims-based user than the current user.

Вот мой код выхода:

 public ActionResult Logout()
        {
            SignInManager.Logout();
            return View("Index"); 
        }

**SignInManager.cs**
 public void Logout()
        {
            AuthenticationManager.SignOut(); 
        }

После того, как пользователь нажмет кнопку выхода из системы, он перейдет на экран входа в систему. В url все еще говорится: http://localhost:8544/Login/Logout ". Поскольку мы находимся на экране входа в систему, возможно, он должен просто сказать" http://localhost:8544/Login ".

Ответ 1

Попробуйте следующее:

public ActionResult Logout()
{
    AuthenticationManager.SignOut();
    Session.Abandon();
    return RedirectToAction("Index");
}

Это перезагрузит вашу страницу входа, которая предоставит вам новый токен CSRF.

Ответ 2

Вы возвращаете View, а не вызываете RedirectToAction(). Итак, происходит то, что представление выполняется в контексте запроса на выход, где пользователь все еще зарегистрирован. Они не будут выходить из системы, пока запрос не завершится.

Итак, попробуйте

public ActionResult Logout()
{
    SignInManager.Logout();
    return RedirectToAction("Index", "Home");
}

Ответ 3

То, что работало для меня, заключалось в переключении порядка используемых посредников. Добавьте сначала app.UseAuthentication(), а затем антифрикционный материал. Вот как я это сделал:

app.UseAuthentication();
app.Use(next => ctx =>
        {
            var tokens = antiforgery.GetAndStoreTokens(ctx);

            ctx.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken,
                new CookieOptions() { HttpOnly = false });

            return next(ctx);
});

Выполнение этого наоборот создает маркер, который не предназначен для аутентифицированных пользователей.

Ответ 4

Я получаю ту же ошибку при входе в систему в течение длительного времени, но не смог понять, почему. Наконец я нашел это, поэтому я публикую это здесь (хотя это немного другая причина) на случай, если кто-то еще имеет это.

Это был мой код:

//
// GET: /login
[OutputCache(NoStore = true, Location = System.Web.UI.OutputCacheLocation.None)]
public ActionResult Login()
{
    return View();
}

//
// POST: /login
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
    AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);

    if (!ModelState.IsValid)
    {
        return View(model);
    }
    //etc...

Это работало нормально для 99,99% логинов, но время от времени я получал вышеупомянутую ошибку, хотя до сих пор не мог ее воспроизвести.

Ошибка возникает только тогда, когда кто-то дважды быстро нажимает кнопку входа. Однако, если я AuthenticationManager.SignOut строку AuthenticationManager.SignOut в действии " Login в Login, это нормально. Я не уверен, почему я поставил эту строку там, но это вызывает проблему - и устранение ее устраняет проблему.

Ответ 5

Попробуй это:

 public ActionResult Login(string modelState = null)
    {
        if (modelState != null)
            ModelState.AddModelError("", modelState );

        return View();
    }
 [ValidateAntiForgeryToken]
    public async Task<ActionResult> Login(LoginViewModel model)
    {
        AuthenticationManager.SignOut();

        return RedirectToAction("Login", "Controller", new { modelState = "MSG_USER_NOT_CONFIRMED" });
    }

Ответ 6

Мой случай отличается, я сделал весь этот код, как вы сказали, ребята! но когда я в приложении и закрываю браузер напрямую, вместо этого, если нажать на кнопку выхода из системы.

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

пожалуйста, дайте мне знать, как я могу сделать, чтобы эта ошибка исчезла.

Заранее спасибо. !

Ответ 7

У меня не было команды AuthenticationManager.SignOut, как Шон упоминал в моем методе входа в систему. Мне удалось воспроизвести, нажав на кнопку входа в систему более одного раза, прежде чем hte следующий Просмотр загрузки. Я отключил кнопку входа в систему после первого щелчка, чтобы предотвратить ошибку.

<button type="submit" onclick="this.disabled=true;this.form.submit();"/>

Ответ 8

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

  1. Открытие двух вкладок при входе в систему,
  2. Выйти из одного,
  3. Перезагрузка обоих,
  4. Вход в один,
  5. Попытка войти с другим. Ошибка произошла до входа в действие POST: /Account/Login.

Большинство моих пользователей используют веб-приложение на мобильном устройстве, поэтому имело смысл, что они добавили в закладки страницу входа, подняли ее и отправили, когда у них уже открылась вкладка в фоновом режиме. Я также предположил, что иногда они будет иметь неактивную вкладку, загруженную с формой входа в систему, и просто потяните эту вкладку и отправьте.

Я понимаю, что есть много способов решить эту проблему. Я решил это с двумя изменениями:

  1. Я добавил проверку User.Identity.IsAuthenticated в свое действие "GET: /Account/Login":
if (User.Identity.IsAuthenticated)
{
   try
   {
      return RedirectToLocal(returnUrl);
   }
   catch
   {
      return RedirectToAction("index", "Home");
   }
}
  1. В моем контроллере я создал действие "проверься ли вошел в систему":
[AllowAnonymous]
public JsonResult CheckLogedIn()
{
    try
    {
        return Json(new { logged_in = User.Identity.IsAuthenticated }, JsonRequestBehavior.AllowGet);
    }
    catch
    {
        return Json(new { logged_in = false }, JsonRequestBehavior.AllowGet);
    }
}

И я неоднократно вызывал его, чтобы перенаправить все открытые формы входа со страницы входа, когда уже вошел в систему:

<script type="text/javascript">
    setInterval(function () {
        $.ajax({
                url: '@Url.Action("CheckLogedIn", "Account")',
                type: "GET",
            }).done(function (data) {
                if (data.logged_in) {
                    window.location = '/';
                }
            });
    }, 5000);  
</script>

Это хорошо сработало для меня. Надеюсь, это поможет вам.