1

I have inherited an ASP.NET site (4.5). The site is running on a single server (in a hosted environment) using an automatically generated ViewState encryption key.

Whenever the site is restarted, in spite of users being correctly re-directed to the login page (which is basically an asp:Login control with some text), they will get MAC verification errors until they close their browser.

I would like to know if it is possible/how to ensure that the ViewState is completely culled / cleared whenever a user logs-in to prevent this problem from happening. Do I need to do a brute-force re-direct or something similar?

I note that the login control's DestinationPageUrl is set to a static value, rather than the page in the query string, would this be an issue?

Answers that suggest disabling ViewState validation, generating static keys or implementing persistent ViewState handling will be down-voted. Thanks.

  • Looks like duplicate of http://stackoverflow.com/questions/4693369/validation-of-viewstate-mac-failed-when-on-page-for-20-minutes – nothingisnecessary Oct 25 '13 at 20:03
  • I've had varying degrees of success with solutions to this issue, see one example in my answer below, HTH! – nothingisnecessary Oct 25 '13 at 20:54
  • All the solutions I've found have amounted to disabling ViewState MAC verification/encryption (which is a moronic non-answer as far as I'm concerned). The generation of static keys _should_ be unnecessary, as one would expect that the login process would discard old ViewState; it would seem a VERY strange omission, even for Microsoft... As you might have guessed, I'm new to ASP.NET and really don't (want to) understand the convoluted page life-cycle... – The Real Edward Cullen Oct 28 '13 at 14:19
  • I agree - I never mess with disabling the Viewstate MAC validation stuff. I have deployed the below solution in a real enterprise product with 1000+ organizations. Setting `PostBackUrl` correctly on the button usually does the trick, but the other method is to force a reload of the patch, through one of various methods.. – nothingisnecessary Oct 28 '13 at 16:30

1 Answers1

2

I believe this is well-covered by the SO post linked below, and probably a few others and blogs (googling "viewstate mac validation failed" reveals a number of explanations and fixes.)

Validation of viewstate MAC failed when on page for 20+ minutes

In some cases setting PostBackUrl on the login Button to equal the page name that you will be posting back to will fix the issue.

I had a case where it did not, and I was selling a COTS product and could not always rely on users updating their configuration to avoid this notorious issue. To overcome this issue, I used a little bit of javascript. The solution goes like so:

  1. Create a "splash screen" page which can also function as a screen saver, perhaps it could show a logo and randomly move it around the page every few seconds for a nice effect (I did this). Clicking on or hitting a key on the splash screen page should navigate the user to the login form page URL.
  2. From the Login form, render the value of Session.Timeout (integer in minutes) into javascript.
  3. Write a javascript function that fires on window.load and uses setInterval() or the like to monitor how long the unauthenticated-user has been sitting on your login form. When the session timeout is about to expire, redirect to the splash screen page created in #1.

(Instead of the splash screen method, you could force a refresh of the login form - but if a user leaves their browser on your login form over the weekend this will prevent your ASP.NET app from automatically shutting down due to inactivity (assuming you have a site that has low enough traffic volume to actually shutdown due to inactivity)).

Example code: (put this in your login.aspx)

<script type="text/javascript">
    var sessionTimeout = <%=Session.Timeout.ToString()%>;
    var sessionTimeoutMs = sessionTimeout * 1000;
    var refreshLoginForm = false;
    var redirectToSplashPage = true;
    setTimeout(function()
    {
        if(window.console && window.console.log) { window.console.log("ASP.NET Session expired."); }
        if(refreshLoginForm)
        {
            // method 1: refresh login form to get a fresh viewstate
            window.location.href = window.location.href;
        }
        else if (redirectToSplashPage)
        {
            // method 2: redirect to a splash screen / screen saver page
            // that will link back to login form and request a fresh viewstate.
            window.location.href = "login_splashscreen.html";
        }
    }, sessionTimeoutMs);
</script>
Community
  • 1
  • 1
nothingisnecessary
  • 6,099
  • 36
  • 60