2

It's quite common topic I think, but I can't resolve my problem. In my application build with ASP.NET MVC 3, I'm using form authentication along with output caching:

<authentication mode="Forms">
  <forms loginUrl="~/Account/LogOn" name=".CMS" protection="All" timeout="43200" cookieless="UseCookies"/>
</authentication>

<caching>
  <outputCacheSettings>
    <outputCacheProfiles>
      <add name="Dynamic" duration="3600" location="Client" varyByParam="id" />
    </outputCacheProfiles>
  </outputCacheSettings>
</caching>

My LogOff action looks folowing:

public ActionResult LogOff()
{
    _formsService.SignOut();
    return RedirectToAction("Index", "Dynamic");
}

this action uses simple SignOut method:

public void SignOut()
{                        
    FormsAuthentication.SignOut();

    HttpContext.Current.Session.Abandon();

    // clean auth cookie
    HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, string.Empty);
    authCookie.Expires = DateTime.Now.AddDays(-1);
    HttpContext.Current.Response.Cookies.Add(authCookie);

    // clean session cookie    
    HttpCookie sessionCookie = new HttpCookie("ASP.NET_SessionId", string.Empty);
    sessionCookie.Expires = DateTime.Now.AddDays(-1);
    HttpContext.Current.Response.Cookies.Add(sessionCookie);
}

But problem is following:

the page http://localhost/app/dynamic/page is protected. I cannot enter this page untill I login. After login, I have access for browsing such page. After logout, and then entering the page again, unfortunately I can still view its content.

How to prevent access to protected pages after logout, when caching is enabled and I was previously visiting such pages ? What I'm doing wrong ? The cookies should be cleaned in another way ?

Regards

jwaliszko
  • 16,942
  • 22
  • 92
  • 158

4 Answers4

3

The page is still cached. You need to add the following response header:

cache-control : no-cache

which doesn't actually prevent caching. The cache-control response header's no-cache directive means that the browser

MUST NOT use the response to satisfy a subsequent request without successful revalidation with the origin server.

If you really want to prevent caching, specify the no-store directive. That tells the browser that it

MUST NOT store any part of either this response or the request that elicited it. This directive applies to both non-shared and shared caches. "MUST NOT store" in this context means that the cache MUST NOT intentionally store the information in non-volatile storage, and MUST make a best-effort attempt to remove the information from volatile storage as promptly as possible after forwarding it.

See the HTTP 1.1 specs for details on cache-control and its directives.

Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135
  • Hello, I've tried to add: HttpContext.Current.Response.CacheControl = "no-cache"; or HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache), but it didn't help. – jwaliszko Feb 17 '11 at 20:31
  • Install Firefox (if you haven't). Install the Firefox plug-in Tamper Data (https://addons.mozilla.org/en-us/firefox/addon/tamper-data/). Start tampering: Tamper Data lets you inspect and tweak the HTTP[S] request/response stream -- you can modify/inject/delete both request and response headers, etc. It's an essential web development tool – Nicholas Carey Feb 18 '11 at 20:42
0

Take a look at this post Asp.Net Mvc Can Not Log Out . I believe it should provide the code snippet needed to logout and clear cache.

Community
  • 1
  • 1
Austin M
  • 594
  • 1
  • 4
  • 19
  • Hello, thanks but unfortunately the code which was ticked to be an answer in the post you have shown me didn't help in my situation. – jwaliszko Feb 17 '11 at 20:38
0

You can't clear then browser cache from the server.

IMO the only right thing to do is invalidating the cookie on the server side(i.e. even if somebody gets to know the cookie he can't use it anymore), and optionally deleting the cookie on the client.

Just deleting the cookie isn't enough IMO.

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
  • Hello, can you just provide me real code example how to solve it. I was trying to make different "hacks" but still I cannot make it working. Have you any good articles for it ? I thaught it should be simple but it is wired. I was trying to invalidating the cookie using code in the post provided by @Austin M, but it is not working. Invalidating means expiration or something else ? Mabye I'm doing all of this in wrong place in my code ? – jwaliszko Feb 17 '11 at 20:45
0

Have you veriifed that browser actually makes request to the page http://localhost/app/dynamic/page (i.e. using Fiddler)?

If page is served from browser's cahce you need to set cache control header on that app/dynamic/page so browser is forced to query the page from server.

If page is retrived from server than see if cookies are still there (your cookie code looks ok, but still something could be wrong) OR if server side caching kicks in.

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
  • Hello, I was watching the process in VS debugger. After login, when I try to visit the page first time, the controler action on the server is invoked. After logout, when I try to visit the page second time, the controller action is not invoked. The page has to be returned from the browser cache. – jwaliszko Feb 17 '11 at 20:35
  • You need to make sure that cache control headers are set properly on your dynamic/page page. Using some sort of tool that shows actual HTTP response is the easiets way to do so (there are plenty of such tools if you don't like Fiddler). Note that you also may be hitting server side cache (your action will not be called in this case either), but it is less likely. – Alexei Levenkov Feb 18 '11 at 19:11