ASP.NET authentication cookie disappears, only in IE, only from specific locations - asp.net

Internet explorer is not keeping my authentication cookie after one page redirect.
Here is the situation:
I have an ASP.NET 2.0 web application running on a shared iis7 hosting. The application uses forms authentication to handle login and user identity and writing a cookie (.ASPXFORMSAUTH) on the client machine for that purpose.
in IE (checked with version 8, 9), from some locations, the authentication cookie is not being kept after the first page. The observed behavior is:
User name and password are submitted in login form
User is succesfuly redirected to the first-after-login page (and fiddler shows that the .ASPXFORMSAUTH cookie exists)
After clicking another link or hitting F5 for refresh, the user is credirected to login, and the authentication cookie (according to fiddler) doesn't exist anymore.
at the refresh / click, the authentication cookie is missing in the request headers.
This doesn't happen in Chrome / FF, and even in IE, it seems to be dependent on the location from which I am connected.
also, locally (using the internal dev server in VS2008), all works fine and reflects fine in fiddler as well.
I am banging my head at it for a few days now. Thought it may be some kind of a strange firewall problem, but couldn't determine anything conclusive.
Ideas will be appreciated.

IE suffers from a weird bug - for some reasons, if there are non-alphanumeric characters in the domain's name, IE won't persist cookies... and hence you'll have no persistent session between different calls.
Check if your domain has non-alphanumeric characters in it, such as test_domain or test-domain or the likes. Unfortunately, I don't know any fixes for this short of aliasing the incriminated domain or accessing it directly via the IP. The reason you've got no problems locally is that you're pointing to http://localhost, which is fine. As soon as you deploy to a non IE compliant domain you'll witness the problem.
Happened to me and it took hours to find out why. Hope this helps. Another reason to kill IE with fire.

My solution has been a combination of other solutions:
IE not saving asp.net authentication token / cookies
http://connect.microsoft.com/VisualStudio/feedback/details/662275/asp-net-user-agent-sniffing-and-ie10-internet-explorer-10
upgrade to .NET 4.0 adding the tag ticketCompatibilityMode="Framework40" in the web.xml: http://msdn.microsoft.com/en-us/library/1d3t3c61.aspx
Note that the real final solution was the 3rd.
Last but not least: once I set this flag above I had to change the logout method in the code behind because the old one did not logout any more:
protected void LoginStatusLink_LoggedOut(object sender, EventArgs e) {
// remove the authenticatation cookies from the browser
FormsAuthentication.SignOut();
// force a new 'expired' auth cookie
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName);
cookie.Expires = DateTime.Now.AddMonths(-1);
Response.Cookies.Add(cookie);
// delete roles cookie
Roles.DeleteCookie();
// clear and abandon session
Session.Clear();
Session.Abandon();
// this line just to leave (forget) the current page
this.Response.Redirect("~/");
}

1.try to create a persistant cookie
2.check your cookie settings for IE

Check the server's date. I had a situation where the server was 1 day behind the browser and so the authentication cookie essentially expired immediately. This affected IE, but not FF.

Related

ASP.NET session lost after redirect but only with IE

Everything in italics is the original post, edits below are non-italicized
I am writing in C# using ASP.NET 4.0.
I am authenticating user credentials via SQL lookup and if valid I am storing the username in a session variable then redirecting the user back to the main page. Pretty simple.
if (!db.isValidLogin(userName, passWord))
{
//invalid login, show it!
//just some code to tell the user invalid credentials
}
else
{
//show login successful!
//update some items on the screen
Session["username"] = userName.ToUpper();
Response.Redirect("/");
}
This is not yet over SSL as it's internal development at this point.
When I use Chrome Version "25.0.1364.172 m" I am properly redirected and I am "logged in". My screen is representative of that by showing me my user name and allowing me access to features that authentication allows.
When I use (32-bit) IE 9 Version "9.0.8112.16421" with the same server side code and procedure... When I do the redirect my session variable "username" is gone. In fact the session has a count of 0 for items. BEFORE the redirect the session variable is set and it is correct.
I have the same results on a Windows Server 2008 R2 64-bit box and a Windows 7 64-bit box.
I am using a single server hosting both IIS and SQL. I am not using a session server.
I have traced it out... the code is running exactly as desired up until the redirect. Receiving credentials, executing my stored procedure to validate... setting the session variable before redirecting (I can see the session and the variable and the value is correct).. and then redirecting... and as stated, with Chrome it works EXACTLY as desired... with IE the session is lost on redirect.
I have tried this as well with no success:
Response.Redirect("/", false);
So I'm convinced that something IE is doing, maybe with setting cookies on the client, that is causing a mismatch between the browser and the server session.
Should I not be doing a response.redirect??? And if I do a response.redirect, how do I keep the session from resetting? Once again, keep in mind this doesn't happen when I use Chrome.
Frustrating...
Thanks for any help!
NEW INFO
After attempting to turn off IE caching per an answer... I decided to output the sessionID to the browser so I could see what it was.
The behavior is more direct that the login and redirect...
In IE simply refreshing the browser with F5 causes a new session to be created on the server. Each refresh I receive a NEW session ID.
Testing this with Chrome I do not get a new session ID unless I call session.abandon, timing out my session or closing and restarting the browser.
I was only calling session.abandon when the user clicked log out, but have commented out that code (just in case) to ensure that I'm not abandoning it on accident.
Somewhere between actual page refreshes IE is presenting itself to the server for a new session... ARGH.
For example:
Chrome:
Before login: myjuzrmccerk1t4eakcliq14
After login: myjuzrmccerk1t4eakcliq14
IE:
Before login: unyebuc2ikac12xnhpssy0em
After login: unyebuc2ikac12xnhpssy0em
Refreshes with F5 or Ctrl-R:
one: ptjt42fjwzgdreyyyo3cmvrs
two: s1hd5aatl5yexeuc125aqhst
three: kbpflurcdcxubux3scmdm4k5
Update 2
I have changed the site to use "State Server" for the session and started the appropriate service... There is no change in behavior.
ANSWER
Since my rep is low.. .this won't let me answer my own question for another 3 hours... but here it is..
I found a fix... through trial and error.
InProc and StateServer in sessionstate both had the same results until I added "cookieless=true"
<sessionState mode="StateServer" cookieless="true" />
This causes the session state to be consistent in both Chrome and in IE (where the problems was) and my session ID no longer changes between page refreshes. I was unable to determine WHY this happens, but it is fixed nonetheless.. Thanks Mike and antinescience for your help!
InProc and StateServer in sessionstate both had the same results until I added "cookieless=true"
This causes the session state to be consistent in both Chrome and in IE (where the problems was) and my session ID no longer changes between page refreshes. I was unable to determine WHY this happens, but it is fixed nonetheless.. Thanks Mike and antinescience for your help!
There are some other reports that indicate that IE's caching mechanism (which is widely regarded as, well, not great) may be to blame here. Can you try appending the following to your page:
// Stop Caching in IE
Response.Cache.SetCacheability(System.Web.HttpCacheability.NoCache);
// Stop Caching in Firefox
Response.Cache.SetNoStore();
...and see if that has any effect? The other alternative is you could do:
int randomNumber = new Random().Next(1, 1000);
Response.Redirect("/?nocache=" + randomNumber);
...just for testing. Heck, you could slap the date as numeric in to test as well.
i had the same problem for couple of days now and finally i knew the reason why the session was changed each refresh, first after using the Response.Redirect( URL ,false) method i realized that i was entering the URL as AbspoluteURI as "http:// ServerIP/File/Page.aspx" , i used the AbsolutePath method instead as "~/File/Page.aspx", and my problem was solved!! the IE thinks that the server was changed when you write AbsoluteURL instead of AbsolutePath, i wish this could help
I had the same problem with a webpage which was hosted inside an IFrame. Troubleshooting showed that the ASP.NET Session cookie was lost along the way, and it only happened when using Internet Explorer. When I opened up my webpage in a separate tab in IE everything worked fine.
The problem was caused by security in Internet Explorer. It will not persist cookies unless there is a P3P HTTP header. You can see the blocked URLs by going to IE->View->Webpage privacy report..., and there choose to show "Restricted websites".
I solved the problem by adding a dummy P3P header with every request. The header looks like this;
P3P:"Bogus P3P header because Internet Explorer requires one"
This is the same approach as facebook.com uses. Their p3p header looks like this;
p3p:CP="Facebook does not have a P3P policy. Learn why here: http://(...)/p3p"
See also Cookie blocked/not saved in IFRAME in Internet Explorer
I had this issue too, this SO response solved my problem. If your hostname has underscores (which seems to be invalid), IE seems to drop the session (!).

IE8 Won't Always Edit Cookie Value

I've run into a problem where login on my site is not working consistently in IE8. It works fine in Firefox/Chrome/Safari but not IE8.
On first login everything is fine. After logging out and trying to log back in it usually fails for a while. It will end up redirecting to the login page against after authentication.
So the authentication is successful, it returns true, but it seems IE8 is not accepting the new value for the session id which we set by returning:
Set-Cookie SESSIONID=........; Path=/
in the response header. But obviously this works with a clear cache and I can get in fine. But after its already there it fails to reset, so after authenticating and attempting to go to a new page it sees this is an old session id being sent from the browser and redirects to the login page.
I haven't found anything here or elsewhere that really solves this (besides clearing the cache). Most references to IE8 cookie problems are language/framework specific and don't answer this problem.
Is there something special I might need to do with the set-cookie to make this work?
UPDATE:
I've set IE8 to prompt before accepting any cookie. When the login works fine it prompts as expected. When it does not work there isn't even a prompt to except the cookie..
UPDATE 2:
I should have mentioned that the cookie is expected to be set after an ajax call:
$.get(authenticate_url, ....)
The url it requests a response from returns the header that sets the session id, then in the callback function the user is redirected to the main page -- assuming login is successful.
Is it a first party cookie or a 3rd party cookie. If the latter, ensure you're sending a P3P header.
Are you setting the HTTPOnly attribute?
Are you sure that the domain for the cookie is always the same? E.g. if you set the cookie when visiting "example.com" and tried to change it from "www.example.com" then you'll encounter problems.
I've hit similar symptoms when I have cookies set for both www.example.com and example.com. If there's no domain explicitly set, then session cookies get set for both.
However, higher-level domain cookies take precedence over the lower domian. So, if www.example.com tries to set a cookie, but example.com already has, then the example.com cookie stays in place and continues to apply for www.example.com.
There are two ways to approach this problem. One is not to allow access both with and without the www subdomain. Redirect one to the other. The second is to explicitly set the cookie domain, so that there aren't two versions lying around.
Of course, that might not actually be your issue. Experiment and find out :)

how can I share an asp.net session between http and https

I read that a page which runs under an https connection cannot share an InProc Session (based on cookies) with another page (or the same for that matter) running under regular http. My site is running on Server 2003, IIS 6 and .Net 2.0.
After some experiments it appears that a page which stores data in session while being connected through https CAN subsequently access the data even if running under plain http.
So, is it possible or should I go over and look for flaws in the SSL configuration?
From MSDN:
When a user moves back and forth
between secure and public areas, the
ASP.NET-generated session cookie (or
URL if you have enabled cookie-less
session state) moves with them in
plaintext, but the authentication
cookie is never passed over
unencrypted HTTP connections as long
as the Secure cookie property is set.
So basically, the cookie can be passed over both HTTP and HTTPS if the Secure property is set to false.
I have avoided this issue by adding this to my Global.asax file:
void Session_Start(object sender, EventArgs e)
{
if (Request.IsSecureConnection) Response.Cookies["ASP.NET_SessionID"].Secure = false;
}
This means that if the Session cookie is created over HTTP, it will only be accessible over HTTPS.
IIS setting
In the IIS properties window, under the ASP tab –> Session Properties, there is a setting for “New ID on Secure Connections”
I fixed this intermittent issue for myself by setting this to false.
Searching for the problem doesn't turn up much chatter about it so far, still looking.
Edit: okay finding some stuff now.
Right it seems that it will work fine if both sets of pages are in the same application/website.
So I'd go ahead and carry on, feeling reassured.
If any of the above solution does not work try this. I have cracked this out after doing research of a couple of days.
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
...
...
CookieSecure = CookieSecureOption.Never
});

session lost on redirect

I have a web app that is being hit by facebook. The login page retrieves the keys that I need and sets some session variables. When the server then redirects the user to the next page, the session information is lost. I’m running the IIS engine on vista ultimate at the moment, the app pools don’t matter because I’m using a state service and I’m still losing the session state. I’ve tried both the overloaded method of the response.redirect function and also adding a header to the page to force the redirect and none of this seems to work. Does anyone have any ideas of what I’m missing?
I’ve tried both of these:
Response.Headers.Add("refresh", "3;url=Dashboard.aspx")
And
Response.Redirect("Dashboard.aspx", False)
[EDIT]
So i just did a little experiment and well it turns out that when I hit the url directly from the facebook page I get the problem, but when i copy the url for the IFrame into a new browser window and try it it works fine.
[EDIT]
So I found an article on this and after addin gthe header the problem was solved (for now)
http://support.microsoft.com/kb/323752
Response.AddHeader("P3P: CP", "CAO PSA OUR")
when I hit the url directly from the facebook page I get the problem, but when i copy the url for the IFrame into a new browser window and try it it works fine.
If you're in an iframe, any cookies you set are “third-party cookies”. Third-party cookies may be subject to more stringent conditions than the normal “first-party” cookies you are setting when the user is directly on your site. This can be due to different browser default cookie handling or because the user has deliberately configured it like that. (And for good reason: many third-parties are unpleasant privacy-invading advertisers.)
In particular, in IE6+ with the default settings, you cannot set a third-party cookie unless you write a P3P policy promising that you will be a good boy and not flog your users' data to the nearest identify thief.
(In practice of course P3P is a dead loss, since there's nothing stopping the site owner from just lying. Another worthless complication that provides no actual security. Yay.)
I'd try running Fiddler and see if your session cookie is being sent properly with the response when interacting with your app via Facebook.
The session depends also on cookie support by the client. When you say the app "is being hit by facebook" are you sure that by what ever means they are "hitting" you they are supporting cookies?
Response.Redirect and refresh don't carry session. Server.Transfer() can but loses the ability to transfer to other servers/sites.

Session cookie lost with IE7

I have an ASP.NET 2.0 application. The login page redirects twice when the login is successful. This works OK on all test environment and production servers except one. We can see with Fiddler that the login redirects to the second page and it redirects to the third. When getting to the third page the authentication cookie is lost, and the page redirects back to the login.
As mentioned this happens only on one production server with IE7.
It works fine if we try IE7 from the server itself. It only fails from other client machines.
It works perfectly well if I just try the same from FireFox. I can see clearly of fiddler, that in this case the cookie is not lost.
Any ideas?
This is a longshot, but does the servername have an underscore in it? A while back, there was an IE bug where it couldn't save cookies from a servername/URL that had an underscore in it, so if I accessed the server by http://server_name, I couldn't save a cookie, but accessing it via http://intranetdnsalias would work just fine.
Are you setting a cookie with a domain name set? When browsing, does your URL contain the domain name?
"localhost" cookies don't really work like domain-set cookies and can often disappear.
HttpCookie contains the domain parameter to set.
This sounds like an IIS config problem. Have you tried to recreate the website on that server with defaults?
The dates are consistant? e.g. 10.09.2008 == 09.10.2008 if the locale is wrong. So if you set a specific expiry it might be interpreting it as en-US but you need en-NZ or something.
Or you could be setting it as a UTC date but the ie computer is UTC+8 so it appears to expire quickly?

Resources