This post originated from an RSS feed registered with .NET Buzz
by Scott Hanselman.
Original Post: CSI: ASP.NET - The one where a double HTTP GET from Internet Explorer (IE) causes problems with...
Feed Title: Scott Hanselman's ComputerZen.com
Feed URL: http://radio-weblogs.com/0106747/rss.xml
Feed Description: Scott Hanselman's ComputerZen.com is a .NET/WebServices/XML Weblog. I offer details of obscurities (internals of ASP.NET, WebServices, XML, etc) and best practices from real world scenarios.
Here's a weird one from the CSI:
ASP.NET files...this is the weirdest DOUBLE HTTP GET bug, since, well, the
last one.
Scenario:
On Brian's local machine as a user moves through an enrollment process in an ASP.NET
Application, everything works fine.
The user receives a valid ASP.NET SessionID, moves from page to page, logs in
to Forms Authentication and receives a Forms Auth Cookie.
All is right with the world.
Problem Arises:
When the ASP.NET Application is deployed to a Dev machine (not Brian's machine) the
whole process doesn't work. It seems that the user is getting a new, fresh Session
each page view. The Forms Authentication Cookie never shows up, and the ASP.NET Session
ID is always new.
Note: ASP.NET Session IS enabled on both machines, no cookie blocking or domain
specific security exists.
Forensics:
I hear about this and Brian and I load up Jonas
Blunck's ieHttpHeaders (I donated US$10 to him after this experience) to
see what's really happening.
Opinion: I'm not a fan of Programming
by Coincidence where you move code around at the highest level of abstraction,
basically creating all sorts of invalid states so the system "mostly works" without
ever finding out what the Root Cause is. A lot of the stuff I do at Corillian is Root
Cause Analysis in the most informal sense. I can troubleshoot a problem for
you and also use QEMM386 to load your device drivers into the UMB giving you up to
610k of main memory! These are the skills we pick up. :)
We load up the HTTP Headers on Brian's (working) local machine and see something like:
GET /myapp/login.aspx HTTP/1.1
200 OK
Set-Cookie: ASPSessionID=1234...
GET /
403 Forbidden
GET /myapp/nextstep.aspx
200 OK
Set-Cookie: ASPSessionID=1234...
Set-Cookie: FormsAuth=mzxa...
GET /
403 Forbidden
What the heck are those 403 Forbiddens? We are only requesting two pages. Why are
we seeing two extra GETs?
So, we think:
Spyware - nope, we ran SpyBot. Clean.
GoogleToolbar - nope, it doesn't do that.
JavaScript - none on these pages that would change location.href
We then run HTTP Headers on the Dev (NON-working) machine and see this:
GET /login.aspx HTTP/1.1
200 OK
Set-Cookie: ASPSessionID=1234...
GET /
200 OK
Set-Cookie: ASPSessionID=4567...
GET /nextstep.aspx
200 OK
Set-Cookie: ASPSessionID=1234...
Set-Cookie: FormsAuth=mzxa...
GET /
200 OK
Set-Cookie: ASPSessionID=7890...
Set-Cookie: FormsAuth=""
Oy! The Session and Cookie are getting blown away by this mystery HTTP GET.
What's different on the Dev machine?
The ASP.NET Application is in the root directory, rather than in /myapp as on Brian's
machine.
The ASP.NET Application allows anonymous users to access the root "/", while Brian's
machine doesn't. It allows anonymous users to access /myapp.
The Default Document is set to /login.aspx on the Dev machine, while Brian's machine
has no default document. When / is asked for on the Dev machine, /login.aspx will
be retrieved.
What does an HTTP GET to /login.aspx do?
if (!IsPostBack)
{
Session.Abandon(); //Clean up personal info from the session
FormsAuthentication.SignOut(); //Fresh cookies for a fresh login
}
So, yes, requesting / from the Dev machine will execute /login.aspx which will
blow away their session and FormsAuth cookie, but why is the HTTP GET
/ happening on every page?
What is the only thing that is shared between pages? The Footer.ascx page.
What's on that page? A bunch of tables, and some spacer images.
Spacer images you say? Oy, you mean 1-pixel gifs.
Ah! You WISH I meant 1-pixel gifs. I mean <img
src="" width="1" height="1">