ValidateTokens exception on ASP.NET MVC Login: how to fix How to overcome a ValidateTokens exception that could hinder your login phase in an ASP.NET MVC Web Application form with the Anti-Forgery token feature on

ASP.NET MVC - Aggiungere uno o più percorsi di ricerca predefiniti per le View

Today I had to help one of my developers who was experiencing a strange issue in an ASP.NET MVC Application (based upon .NET Framework 4.8) he was debugging.

The error was happening right after the POST request of the website Login view - which was a standard HTML Form pointing to an [HttpPost] Action method protected with a standard [ValidateAntiForgeryToken] attribute. Once filling up the form and clicking the Login button he was hit by the following exception:

System.Web.WebPages - Void ValidateTokens(System.Web.HttpContextBase, System.Security.Principal.IIdentity, System.Web.Helpers.AntiXsrf.AntiForgeryToken, System.Web.Helpers.AntiXsrf.AntiForgeryToken)

in System.Web.Helpers.AntiXsrf.TokenValidator.ValidateTokens(HttpContextBase httpContext, IIdentity identity, AntiForgeryToken sessionToken, AntiForgeryToken fieldToken)
in System.Web.Helpers.AntiXsrf.AntiForgeryWorker.Validate(HttpContextBase httpContext)
in System.Web.Helpers.AntiForgery.Validate()
in System.Web.Mvc.ValidateAntiForgeryTokenAttribute.OnAuthorization(AuthorizationContext filterContext)
in System.Web.Mvc.ControllerActionInvoker.InvokeAuthorizationFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor)
in System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<BeginInvokeAction>b__19(AsyncCallback asyncCallback, Object asyncState)

Oddly enough, the error was triggered only when the project was executed in debug mode on any developer machine: conversely, on any production server there were no issues and the web application was working just fine. 

The problem

Long story short, it turned out that such exception was caused by a cookie configuration issue, which hindered the ASP.NET anti-forgery token validation. To better clarify that, we need to take a step back and be sure to understand what anti-forgery tokens are and how they are implemented within the ASP.NET MVC Framework.

CSRF attacks

In case you don't know it already, anti-forgery tokens are a security mechanism designed to defend against cross-site request forgery (CSRF) attacks. If you want to read the whole story, we strongly recommend checking out the CSRF Wikipedia page, which contains a great explanation and valid references to better understand such a threat. To briefly summarize it, a CSRF attack happens when someone "steals" (or "rides", or "forges" a copy of) a trusted HTTP session belonging to another unaware user (the victim), and uses it to access and/or alter the data sent and received by the website itself.

Anti-Forgery Tokens

The anti-forgery token concept has been designed to overcome this kind of scenario and works in the following way: when you send a form to the user, you add an extra hidden field that includes one half of a cryptographic token. Additionally, a cookie is set with the other half of the token. When the form is posted to the server, the two halves of the token are verified to check if the request is legit or not.

In our specific scenario, we were getting the exception because the website was configured because our cookie had the Secure flag on (requireSSL=true in the web.config file, as explained here). Such behavior was working fine our production servers since they are configured to only accept HTTPS requests (and to redirect non-HTTPS ones to HTTPS using a dedicated IIS Rewrite rule), but couldn't work on local debugging sessions which are based on IIS Express and a simple HTTP binding

The solution

Once we acknowledged the issue, understanding the fix was easy enough. We just set the requireSSL to FALSE in the web.config file...

...and added the following xdt:Transform feature to the web.Relase.config file:

That fixed our issue for good, allowing us to overcome the exception and properly debug the web application without compromising the security measures of the production build.

If you want to know more about the web.Debug.config file and the web.config transformation feature,  read this official guide from Microsoft Docs
.

Conclusion

That's it, at least for the time being. I hope that this post will help other developers struggling with this nasty issue: see you next time!

About Ryan

IT Project Manager, Web Interface Architect and Lead Developer for many high-traffic web sites & services hosted in Italy and Europe. Since 2010 it's also a lead designer for many App and games for Android, iOS and Windows Phone mobile devices for a number of italian companies. Microsoft MVP for Development Technologies since 2018.

View all posts by Ryan

Leave a Reply

Your email address will not be published. Required fields are marked *


The reCAPTCHA verification period has expired. Please reload the page.

This site uses Akismet to reduce spam. Learn how your comment data is processed.