Question

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.

Was it helpful?

Solution

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>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top