Anti-forgery token is used to prevent CSRF (Cross-Site Request Forgery) attacks. Here is how it works in high-level:
These are some of the anti-forgery token related error messages you may see in Event Viewer:
The provided anti-forgery token was meant for a different claims-based user than the current user.
The provided anti-forgery token was meant for user “”, but the current user is “X”.
The anti-forgery cookie token and form field token do not match.
The required anti-forgery cookie “__RequestVerificationToken” is not present.
A sample stack trace:
at System.Web.Helpers.AntiXsrf.TokenValidator.ValidateTokens(HttpContextBase httpContext, IIdentity identity, AntiForgeryToken sessionToken, AntiForgeryToken fieldToken)at System.Web.Helpers.AntiXsrf.AntiForgeryWorker.Validate(HttpContextBase httpContext)at System.Web.Mvc.ControllerActionInvoker.InvokeAuthorizationFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor)
Error messages clearly state the root causes but the solution is not always straightforward. I will try to provide possible solutions in the post.
Long story short: For anti-forgery validation to pass, the security token of the session token must be equal to the security token of the field token.
I saw different names for these cookies in different sources. They can be used interchangeably:
Session token = Cookie token
Field token = Form token
Security token = anti-XSRF Token
Longer story: For validation to pass, form token and session token are correlated (Important: This is not comparison for equivalence. You can’t correlate them by simply comparing them in Fiddler). There is anti-XSRF token inside each of those. The anti-XSRF token is the one that should match precisely. Reference
For the example:
As you see above, the raw tokens are different but extracted anti-XSRF tokens are the same so the validation passes. (There are additional bytes at the end. They are flags. The username was going to be encoded there if it was an authenticated user).
A possible solution to anti-forgery related errors depends on the way how the issue occurs. I would recommend trying to find out the user behavior that causes these errors.
In my case, the clients were using the application in a way that is not supposed to be used. For example:
Informing your users about the points below can significantly reduce the number of anti-forgery errors:
Catching the anti-forgery exceptions in your code and redirecting user to the homepage if they are already authenticated should prevent most of the errors. Here is a sample code block:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
...
}
protected override void OnException(ExceptionContext filterContext)
{
base.OnException(filterContext);
var action = filterContext.RequestContext.RouteData.Values["action"] as string;
var controller = filterContext.RequestContext.RouteData.Values["controller"] as string;
if ((filterContext.Exception is HttpAntiForgeryException) &&
action == "Login" &&
controller == "MyController" &&
filterContext.RequestContext.HttpContext.User != null &&
filterContext.RequestContext.HttpContext.User.Identity.IsAuthenticated)
{
filterContext.ExceptionHandled = true;
// redirect/show error/whatever?
filterContext.Result = new RedirectResult("/homepage");
}
}
It may take time to fine tune this code block. There is no one solution that fits all.
I saw customers not using the anti-forgery validation in the public pages such as login, about, register pages. Anti-forgery token’s main purpose is to prevent attacker using authentication cookie for doing things on behalf of the actual user. Since the user isn’t authenticated yet in the login page, there are customers removing the validation.
The common “possible solutions” to anti-forgery token/cookie related issues are disabling output caching and enabling heuristic checks. I will include the code snippets here.
Disable output caching:
[OutputCache(NoStore = true, Location = System.Web.UI.OutputCacheLocation.None)]
Add “heuristic checks” to the Application_Start method of Global.asax file:
AntiForgeryConfig.SuppressIdentityHeuristicChecks = true;
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.