Anti Forgery Token and Machine Key (by DrunkCoding.Net)

If working on ASP.NET MVC, you will know the anti-forgery token that helps to protect our website against cross-site request forgery.

To use this feature, call the AntiForgeryToken method from a form and add the ValidateAntiForgeryToken attribute to the action method that you want to protect.

How Does It Work?

When calling the AntiForgeryToken method inside a form, the AspNet will generate an encrypted AntiForgeryToken, pub into a hidden field and then send to the browser. When the browser submits the form back to the server, the token will be decrypted and validated to ensure that the request is genuine before executing the destination action method as long as the action method had been marked by ValidateAntiForgeryTokenAttribute.

The generated token looks like this:

<form action="Create" method="post">
    <input name="__RequestVerificationToken"
ZaHGSnYeEKoTa9fbMUOFx0" />

What is the Issue?

When deploying the website into an environment that has multi servers that are load balancing together (web farm), you may be faced with the below issue when clicking the submit button.

The anti-forgery token could not be decrypted. If this application is hosted by a Web Farm or cluster, ensure that all machines are running the same version of ASP.NET Web Pages and that the configuration specifies explicit encryption and validation keys. AutoGenerate cannot be used in a cluster.

Why Did This Issue Happen?

Assume that the environment has 2 servers that are load balancing as shown in the below diagram:

Farm servers diagram

Internally, the AspNet will use 2 keys (decryptionKey and validationKey) for token encryption/decryption and validation token. By default, these keys will be randomly generated when website starts.

So, look at the diagram above – there are 2 instances of the website that are hosting on different web servers in the single web farm so that when both of them start, a set of keys will be generated for each instance that are different.

Now, a request from user A had been redirected to server 1 by the load balancer, the website response is a view with an encrypted AntiForgeryToken. Later on, user A submits the form back to the load balancer and hopefully that form will be captured and processed by server 1.

Unfortunately, the load balancer now redirects that request to server 2 instead and definitely, the token that had been encrypted by server 1 can’t be decrypted on server 2 because the keys are different. So the error was thrown.

The idea to fix this issue is ensuring all instances of the website are using the same set of keys for the encryption/decryption and validation in the single web farm.

  • The keys should be different on each website on the same server. So if you have multi websites hosting on the same server, the keys should be unique.
  • The keys should be different on each environment for the same website. So if your website is hosting in multi-environments, ensure that the keys on each environment are different as well.

The Solution for IIS

When hosting an AspNet MVC website on IIS, you can generate a set of keys by following the below steps:

  1. Click on the website on IIS
  2. Double click on Machine Key
  3. Uncheck all checkboxes and click Generate button at the right side and then click apply.

  4. The keys will be saved into the web.config file of the website.
  5. Open the web.config file, copy that key and apply across to all website instances on the single farm.
    <machineKey decryptionKey="13C9825F6B5ABB0622CF09B6C7F949F83D113B3CC2351438"

Now, try to submit to your website again. The issue should be resolved.

Thanks for reading!

This article has also been posted here.

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir