Search code examples
c#asp.net-coreantiforgerytoken

AntiforgeryValidationException when trying to login by two different tabs


The steps: The login page is opened in two different tabs.

  1. User A logs from Tab 1 (No issues)
  2. Without refreshing the tab 2, user B tries to log in. Redirects to 400 page.

(Exception: Microsoft.AspNetCore.Antiforgery.AntiforgeryValidationException: The provided antiforgery token was meant for a different claims-based user than the current user.)

Any solution to handle this?


Solution

  • I agree with @matt-shepherd that this is the correct behavior of the anti-forgery token validation. Tab B is in an expired state because the token in Tab B does not reflect that we have already logged in in Tab A the anti forgery token includes the username.

    I am posting another answer here because in my app (.Net Core 2.2 using asp.net core identity and razor pages) System.Web.Helpers.AntiForgery.Validate() is not available.So I wasn't able to validate the token in the controller action as suggested by @matt-shepherd.

    Instead I have created a filter inheriting from IAsyncAlwaysRunResultFilter thanks to Patrick Westerhoff's pull request that was merged to ASP.NET Core 2.2 code base :

    public class RedirectAntiforgeryValidationFailedResultFilter : IAsyncAlwaysRunResultFilter
      {
        public Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
        {
          if (context.Result is AntiforgeryValidationFailedResult)
          {
            context.Result = new RedirectToPageResult("/AntiForgeryError");
          }
    
          return next();
        }
      }
    

    I have created a razor page named AntiForgeryError.

    At last, I have configured my app to use the RedirectAntiforgeryValidationFailedResultFilter in Startup.cs:

    services.AddMvc(options => options.Filters.Add<RedirectAntiforgeryValidationFailedResultFilter>())
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);