If an ASP.NET page is embedded in a frameset or an <iframe>, strange things happen to cookies. By default, Internet Explorer rejects them because it treats them as non-trusted “third-party” artifacts. For example, if you try to issue an authentication cookie within a “framed” page, your login will keep running in circles.
Sauron Doesn’t Trust You By Default
In fact, you must’ve seen this before: the Eye of
Sauron in the Internet Explorer status bar (lower right
corner in the image below). If you click it, you arrive at this Privacy
Report dialog:

If you further click “Settings…”, you get an “Internet
Properties” dialog box. Note that this is happening at the Medium level of trust, which is what most users will most likely have by default. As somebody put it, If you’re paranoid enough to set this slider to High, you need to be using a different browser.

Searching for a solution to this problem, I came across this
snippet of wisdom at the ASP.NET Forums:
Q: I have a frameset page which has an HTM
extension, and I found out each frame it contains display a different
session id on the first request. Why?
A:The reason is that your frameset page is an HTM file
instead of an ASPX file.
In normal case, if the frameset is an aspx file, when you
request the page, it will first send the request to the web server, receive an asp.net session cookie (which holds the session id), and then the browser will send individual requests for the frames, and each request will carry the same session id.
However, since your frameset
page is an htm file, the first request comes back without any session
cookie because the page was serviced by ASP and not ASP.NET. Then again your browser sends out individual requests for each frame.
But this time each individual request will NOT carry any session id,
and so each individual frame will create its own new session.
That’s why you will see different session ids in each
frame. The last request that comes
back will win by overwriting the cookie written by the previous two
requests. If you do a refresh, you will see them having the same
session id.
This behaviour is by-design, and the simple solution is to
change your frameset page to .aspx.
The explanation makes sense. The solution doesn’t. Rarely
would you <iframe> your
own site. Most likely, you won’t be able to control who frames you, and won’t be able to insist they convert calling pages to ASP.NET.
P3P To The Rescue
Just when I was ready to give up, a SalesForce consultant
directed me to a
Knowledge Base article (of a sorts) which suggests a
legitimate workaround. This article talks about the Privacy
Preferences Project (P3P), a W3C brainchild.
In a nutshell, to be trusted, you need to publish a privacy
policy (an XML file, of course) where you’d state what kind of
information you collect about online visitors and whether you pass it
on to all kinds of low-life peddlers. I think the only reason P3P has a
place under the sun is that few people know about it (including myself) and even fewer take it seriously. There are enough privacy
policy generators but no mechanism to police whether you
adhere to the stated practices. This is not to say that we, obedient
netizens, have a moral right to abuse it, but you know how it goes in
the real world.
Compact Policies
Instead of creating and uploading privacy policies to your
sites, you can serve a “compact policy,” i.e. a “p3p” HTTP header,
e.g.: “IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT”. A policy generator can produce one instead of an XML file. In ASP.NET it’s a one-liner that you can put into your page base class or master page:
HttpContext.Current.Response.AddHeader (
"p3p",
"CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi
CONi HIS OUR IND CNT\"");
Just make sure to add this line early in the page life cycle.
If your code redirects or throws an exception too early, the “p3p” header will be missing. As an alternative, you can get IIS to send this header at all times, but in this case the header will appear on everything: images, stylesheets, JavaScript files, etc. Those files don’t really need it.
If you want to get into the nitty-gritty of P3P privacy
policies, O’Reilly has a primer for you. If you want to ensure nobody frames your pages, there’s a simple JavaScript trick to address this.