web-dev-qa-db-fra.com

Le jeton anti-contrefaçon était destiné à un autre utilisateur basé sur des revendications

Je travaille sur une fonctionnalité de déconnexion dans l'application que nous utilisons pour la connexion à l'identité ASP.NET. Je peux me connecter avec succès mais lorsque je me déconnecte puis que je tente de me connecter à nouveau, le message suivant s'affiche: 

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

Voici mon code de déconnexion: 

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

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

Une fois que l'utilisateur a appuyé sur le bouton de déconnexion, il est amené à l'écran de connexion. L’URL indique toujours " http: // localhost: 8544/Login/Logout ". Puisque nous sommes sur l’écran de connexion, nous devrions peut-être simplement dire " http: // localhost: 8544/Login ". 

18
john doe

Essaye ça:

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

Cela rechargera votre page de connexion qui vous fournira un nouveau jeton CSRF.

4
univ

Vous retournez une View au lieu d'appeler RedirectToAction(). La vue est donc en cours d'exécution dans le contexte de la demande de déconnexion, où l'utilisateur est toujours connecté. Ils ne le seront pas avant la fin de la demande.

Alors, essaye

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

Ce qui a fonctionné pour moi a été de changer l'ordre des middlewares utilisés. Ajoutez d'abord app.UseAuthentication(), puis l'antiforgery. Voici comment je l'ai fait: 

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);
});

Faire l'inverse crée un jeton qui n'est pas destiné aux utilisateurs authentifiés. 

6
Arturo Moreno

Cela fait très longtemps que je reçois cette même erreur sur le login, mais je n'ai pas pu comprendre pourquoi. Finalement, je l’ai trouvé, donc je l’affiche ici (bien que ce soit une cause légèrement différente) au cas où quelqu'un le posséderait.

C'était mon code:

//
// 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...

Cela a bien fonctionné pour 99,99% des connexions, mais de temps en temps, j'ai eu l'erreur mentionnée ci-dessus, bien que je ne puisse pas la reproduire, jusqu'à présent. 

L'erreur ne se produit que lorsque quelqu'un clique deux fois rapidement sur le bouton de connexion. Cependant, si je supprime la ligne AuthenticationManager.SignOut dans l'action Login, tout va bien. Je ne suis pas sûr de la raison pour laquelle j'ai ajouté cette ligne, mais cela cause le problème - et le supprimer corrige le problème.

4
Sean

Essaye ça:

 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" });
    }