I'm using ELMAH to handle errors in my MVC sites and I've noticed over the past couple of weeks that I'm getting some CryptographicExceptions thrown. The message is:
System.Security.Cryptography.CryptographicException: Padding is invalid and cannot be removed.
System.Web.Mvc.HttpAntiForgeryException: A required anti-forgery token was not supplied or was invalid. ---> System.Web.HttpException: Validation of viewstate MAC failed. If this application is hosted by a Web Farm or cluster, ensure that configuration specifies the same validationKey and validation algorithm. AutoGenerate cannot be used in a cluster. --->
The application is not running in a cluster and I can't seem to reproduce these errors. They look like valid requests -- not a hand-crafted post -- and do contain the __RequestVerificationToken cookie. I do have the required HTML helper on the page, inside the form (my login form).
I haven't had any user complaints, yet, so I'm assuming that eventually it works for whoever is trying to lo开发者_如何学Gogin, but I'm left wondering why this could be happening.
Anyone else seeing this behavior or have any ideas on how to diagnose the exception -- like I said, I can't get it to fail. Deleting the cookie in FF comes up with a different error. Modifying the cookie (changing or removing the contents) also results in a different error, as does modifying the contents of the hidden token input on the page.
I'm not sure if there is a correlation, but after adding a robots.txt file that excludes my login actions, I am no longer seeing these errors. I suspect that it has to do with a crawler hitting the page and trying to invoke the login action.
EDIT: I've also see this issue when receiving old cookies after the application pool has recycled. I've resorted to setting the machineKey explicitly so that changes to the validation/decryption keys on application restarts don't affect old cookies that may be resent.
After updating the site and going to a fixed machineKey I found that I was still getting these errors from people who had cookies from the previous version. As a temporary work around I've added the following Application_Error handler:
public void Application_Error()
{
var exception = Server.GetLastError().GetBaseException();
if (exception is System.Security.Cryptography.CryptographicException)
{
Server.ClearError();
if (Request.IsAuthenticated)
{
var form = new FormsAuthenticationWrapper();
form.SignOut();
Session.Clear();
}
Response.Cookies.Clear();
Response.Redirect( "~" );
}
}
I'm not so sure this has anything specifically to do with the antiforgery system, the inner exception states 'Validation of viewstate MAC failed.', from what I can tell, the default infrastructure for the antiforgery system has a dependency on the viewstate (actually if you take a look here you'll see see the dependency and horror (the CreateFormatterGenerator method at the bottom)).
As for why the viewstate mac is failing on the fake request, I'm not sure- but given the horror that exists in deserializing the antiforgery token (processing an entire fake request), it doesn't suprise me at all..
精彩评论