Browser occasionally losing HttpCookie for authentication after postback and redirect
This has been a nagging issue for some time, but very sporadic and difficult to isolate.
From time to time, browsers that have authenticated on a web application, have been open for a while, have logged in and out of the same web application multiple times, have multiple tabs, are pretty much any browser (Chrome, IE, Firefox, Safari), and seemingly at random, lose their ability to retain an AuthCookie after being set and followed by a redirect. Closing the browser and starting a new session resolves the issue, as does opening up a different browser and attempting to authenticate.
Our team uses forms authentication for all of our websites and web application. This is a pretty typical setup where a login form is displayed, the user enters credentials and a cookie is set on the click event of the postback, then a redirect occurs to the same page where the cookie is then referenced and used to complete authentication.
In this situation
FormsAuthentication.FormsCookieName = ".WebAuth"
Within Event:
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, Username, DateTime.Now, DateTime.Now.AddMinutes(SessionTimeout), false, Username);
HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(authTicket));
Response.Cookies.Add(faCookie);
Response.Redirect(Request.RawUrl, true);
After the redirect, on PreInit:
HttpCookie authCookie = Request.Cookies[cookieName];
At this point, the authCookie variable is typically not null, but in these isolated circumstances that I've outlined above, the cookie comes back null after the redirect.
This happens very randomly, sometimes weeks before affecting one of our developers. As I said, restarting the browser resolves the issue.
Today I had it happen on our dev server while using Chrome. I had logged into the application, allowed the application to session timeout, and then attempted to login again. The attempted login then failed to set the cookie. I remotely attached Visual Studio to the process on the server to begin debugging. The entire time I could step through my code, even deploy new code versions to the server with updates, restart the app, restart IIS on the server, attach and reattach to the project, and the issue persisted in Chrome. In Firefox, I was able to authenticate without issue.
From Chrome, the login would validate, attempt to set a Response Cookie as outlined above. Prior to redirect, I could see the properly set Response Cookie, as well as its counterpart in the Request Cookies. However, on each redirect after a seemingly successful login, the Response and Request Cookie are gone.
I enabled Trace on the application to view the cookie collection:
There is a .WebAuth in the Request Cookies Collection, as well as ASP.NET_SessionId and several ASPSESSIONIDxxxxxxxx, but when the page loads, only the ASP.NET_SessionId and ASPSESSIONIDxxxxxxxx cookies are available in the Request.Cookies scope, no sign of the .WebAuth. However, in the page's Tr开发者_如何学JAVAace information after render, there multiple .WebAuth cookies listed, it is just that the page seems to have no access to them.
Primarily, on a working version after authentication there is both a .WebAuth Response and Request Cookie in the page's Trace info. But on a non functioning browser window, the Response Cookie is absent.
Has anyone else had any experience with this? It is such a nagging issue, and so sporadic, but I would love to be able to resolve it. My concern is that it may be affecting users and we would have no knowledge since the description of the issue is so convoluted.
Based on your scenario you may be running into browser's restrictions on number of cookies per domain/total. The limits are relatively high, but exist (spec: http://www.ietf.org/rfc/rfc2109.txt, section 6.3 , some recent information - http://www.nczonline.net/blog/2008/05/17/browser-cookie-restrictions/)
If you get it happening again try to look at actual server responses (i.e. using Fiddler) to see if cookies are send to the browser. Check what cookies are set for the domain and current page (depending on browser there are different ways of doing it, in all browsers you can see some cookies by running following in address bar javascript:alert(document.cookie)
)
This is a non-persistent cookie issue. Session simply times out.
Try changing false
to true
in this line:
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, Username, DateTime.Now, DateTime.Now.AddMinutes(SessionTimeout), true, Username);
Also add
faCookie.Expires = DateTime.Now.AddMinutes(SessionTimeout);
I have fall in similar situation, things was certain as you described. But, later the reason have been found.
ASP.NET and IIS understood MyApplication and myapplication as one equal, but browsers undertood them as different. So, when we set auth cookies for /MyApplication, they were not sent to the server, when we go to /myapplication.
The fix is next:
protected void Application_BeginRequest(object sender, EventArgs e)
{
string url = HttpContext.Current.Request.Url.PathAndQuery;
string application = HttpContext.Current.Request.ApplicationPath;
if (!url.StartsWith(application))
{
HttpContext.Current.Response.Redirect(application + url.Substring(application.Length));
Response.End();
return;
}
}
精彩评论