tags:

views:

931

answers:

6

I can't find any post regarding the cache on logout so I'm going to ask this question. If there is a similar question. Please let me know.

I have a Logout page that basically call FormAuthentications signout method then redirect the user to the login page. It work fine but the problem is user can click on the browser's back button and get the cached page. I tried to set the no-cache header on my master page but that doesn't work.

Can someone point me to a article or tutorial or post some tips on how you handle this situation?

thank

A: 

There's no foolproof way to accomplish this. The user ultimately has control over the cache settings and no-cache headers can't override these.

Is there a particular concern you are trying to address here (security?), or are you just trying to ensure that users aren't seeing stale data?

Chris Pebble
I just don't want user to access any stale data.
Jack
I've seem website that once you have log out. You will not get back to the previous page with the back button. You will either get a session timeout error page or it just keep putting you on the logout page.
Jack
A: 

This is a hard problem to tackle. You can create a base page and in the constructor you can check that if the person is logged in or not. If the person is not logged in that simply redirect to the login page. This base page will be inherited by all the other ASP.NET pages.

azamsharp
If the page is cached, the constructor won't be run though, right?
Greg
If the page is cached client-side, the web server won't even get a request, so there won't be any code that redirects in this case at all.
Lasse V. Karlsen
+2  A: 

Depending on your requirements a possible solution might be to set the Cache-Control header to "no-cache" on every authenticated page. This will prevent pages from being cached downstream. It could be achieved by writing a custom HttpModule that will set the header:

// Prevent the browser from caching the ASPX page
Response.Cache.SetNoStore();

You can also set this in your page's HEAD section by adding the following line of code:

<meta http-equiv="Cache-Control" content="no-cache" />

By doing that if a user clicks the Back button once he's been signed out, he will be redirected to the login form instead of seeing a cached version of his last page which could be a problem if he is using a public computer.

Darin Dimitrov
+1  A: 

If you're using forms authentication, make sure the forms authentication cookie is deleted when the user logs out. As soon as the user goes to do anything on the cached page (the page they pressed the back button to get to), the site will ask the user to re-login, and then redirect them back to the original page, with fresh data. Viola!

Additionally, regarding caching of pages, you need to set a pretty good number of headers to turn the caching mechanism in the browser and proxy servers off:

  • "Expires" - set to some date in the past
  • "Last-Modified" - set to the current date/time
  • "Cache-Control" - set to "no-cache, must-revalidate"
  • "Pragma" - set to "no-cache"

That should just about make the page uncacheable. The date/times need to be in RFC1123 format (format specifier "R" in .net e.g. "Mon, 17 Apr 2006 21:22:48 GMT"). You would implement this as:

Response.AddHeader("Expires", new DateTime(1940, 1, 1).ToString("R"));
Response.AddHeader("Last-Modified", DateTime.Now.ToString("R"));
Response.AddHeader("Cache-Control", "no-cache, must-revalidate");
Response.AddHeader("Pragma", "no-cache");

Or something similar, depending on where you want to add all of the headers. I have had good success with this across many browsers and proxy servers, but nothing is fool-proof where page caching is concerned.

Robert C. Barth
A: 

IE6 seems to ignore some cache headers.

Another technique ontop of cache headers would be some clientside javascript to check for the authentication cookie and use history.Forward() if its not there.

FlySwat
A: 

Add this to global.asax and it will set the no-cache headers for all pages in the web application. Be sure that disabling caching is really what you want to do however - because caching is a performance benefit.

You can of course, also apply the same Response.Cache commands to pages individually.

This works in FireFox 3, IE7, and somewhat in Opera 9.6. (In Opera, it will work if you don't to any post requests. If you do, the page will still be accessible from the back button the first time, but not afterwards.)

   protected void Application_PreSendRequestHeaders(object sender, EventArgs e)
    {
        if (!Request.Path.Contains("/Content/")) //We WANT images, css, javascripts to be cached!
        {
            //Otherwise, all of our pages contain sensitive information, and we don't want them cached.
            Response.Cache.SetCacheability(HttpCacheability.NoCache);
            Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches); //for Opera. May only work on https sites
            Response.Cache.SetNoStore();
        }
    }
Nathan