Anti-Forgery Token was meant for a different claims-based user

前端 未结 7 1759
有刺的猬
有刺的猬 2020-12-28 13:41

I am working on a logout feature in the application we are using ASP.NET Identity login. I can login successfully but when I logout and then try to login again I get the fol

相关标签:
7条回答
  • 2020-12-28 14:07

    Try this:

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

    That will reload your login page which will provide you a new CSRF token.

    0 讨论(0)
  • 2020-12-28 14:11

    What worked for me was switching the order of the middlewares used. Add first app.UseAuthentication() and then the antiforgery stuff. This is how I did it:

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

    Doing it the other way around creates a token that is not meant for authenticated users.

    0 讨论(0)
  • 2020-12-28 14:11

    I found that users were experiencing this issue when they would submit the login page when already authenticated. I replicated this error by:

    1. Opening two tabs when logged in,
    2. Logging out from one,
    3. Reloading both,
    4. Logging in to one,
    5. Trying to log in with the other. The error occurred before entry to the POST: /Account/Login action.

    The majority of my users use the web app on a mobile device, so it made sense that they had bookmarked the login page and pulled it up and submitted when they had a tab opened in the background already logged in. I also surmised that sometimes they would have a dormant tab loaded with the login form and just pull that tab up and submit.

    I realize that there are many ways to solve this issue. I solved this with two changes:

    1. I added a check on User.Identity.IsAuthenticated to my "GET: /Account/Login" action:
    if (User.Identity.IsAuthenticated)
    {
       try
       {
          return RedirectToLocal(returnUrl);
       }
       catch
       {
          return RedirectToAction("index", "Home");
       }
    }
    
    1. In my controller I created a "check if logged in" action:
    [AllowAnonymous]
    public JsonResult CheckLogedIn()
    {
        try
        {
            return Json(new { logged_in = User.Identity.IsAuthenticated }, JsonRequestBehavior.AllowGet);
        }
        catch
        {
            return Json(new { logged_in = false }, JsonRequestBehavior.AllowGet);
        }
    }
    

    And I called it repeatedly in the view to redirect all open login forms away from the login page when already logged in:

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

    This worked well for me. Hope it helps you.

    0 讨论(0)
  • 2020-12-28 14:18

    You are returning a View, rather than calling RedirectToAction(). So what is happening is the view is running under the context of the logout request, where the user is still logged in. They won't be logged out until the request finishes.

    So, try

    public ActionResult Logout()
    {
        SignInManager.Logout();
        return RedirectToAction("Index", "Home");
    }
    
    0 讨论(0)
  • 2020-12-28 14:20

    I've been getting this same error on the login for a LONG time now, but haven't been able to work out why. Finally I found it, so I'm posting it here (although it's a slightly different cause) in case someone else has it.

    This was my 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...
    

    This worked fine for 99.99% of the logins, but every now & then I got the above-mentioned error, although I couldn't reproduce it, until now.

    The error only happens when someone clicks the login button twice in quick succession. However, if I remove the AuthenticationManager.SignOut line in the Login action, then it's fine. I'm not sure why I put that line in there, but it's causing the issue - and removing it fixes the problem.

    0 讨论(0)
  • 2020-12-28 14:22

    Try this:

     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" });
        }
    
    0 讨论(0)
提交回复
热议问题