Friday, December 2, 2016

[HttpException (0x80004005): Unable to validate data.] when changing FormsAuthentication machineKey encryption

A new feature on our website required us to use a different encryption algorithm for our Forms Authentication cookie.

Simple change; just update one line in the web.config.  However we read data from that cookie on every web request.  And so as soon as we changed that algorithm, anyone who had previously visited our site would get an ASP.NET yellow screen of death.

"Unable to validate data." ASP.NET error message screen


No problem, I thought.  I can just delete that cookie instead of reading it.  That turns out not to be so easy to do.  The best I could do was set an expiration on the cookie in the client response.  And then I also deleted the cookie in the server request.

// Remove the cookie from the server request
contextBase.Request.Cookies.Remove(FormsAuthentication.FormsCookieName);
                            
// Expire the cookie on the client
authCookie.Expires = DateTime.Now.AddDays(-1d);
Response.Cookies.Remove(authCookie.Name);
Response.Cookies.Add(authCookie);

This got me past some errors, but somewhere deep in someone else's DLL the problem still lingered.  I tried a different approach.  I resorted to using a base Forms Authentication method, SignOut().  That worked perfect!  Here is the code I ended up with.  It was placed in the Global.asax Application_PostAuthenticateRequest() event.

protected void Application_PostAuthenticateRequest(object sender, EventArgs e)
{
    var contextBase = ServiceLocator.Current.GetInstance();
    var authCookie = contextBase.Request.Cookies[FormsAuthentication.FormsCookieName];
    if (authCookie != null)
    {
        var encodedTicket = authCookie.Value;
        if (!String.IsNullOrEmpty(encodedTicket))
        {
            FormsAuthenticationTicket ticket = null;
            try
            {
                ticket = FormsAuthentication.Decrypt(encodedTicket);
            }
            catch(HttpException hex) 
            {
                if(hex.Message == "Unable to validate data.")
                {
                    // Clean up any AUTH cookies with 
                    // a different encryption
                    FormsAuthentication.SignOut();
                    return;
                }
            }
            // Unimportant company stuff happens here
        }
    }
}

No comments:

Post a Comment