Forum OpenACS Development: Cookie handling and IE
What I did was visit http://dotlrn.collaboraid.net/test/, then click to log in as admin on one of test servers.
It works on Opera and Mozilla, but not on IE.
The problem is that dotlrn.collaboraid.net cookies me with an 'ad_session_id' cookie when I visit that page.
Then I click through to http://dotlrn10-test.dotlrn.collaboraid.net/register/admin-login which issues another 'ad_session_id' cookie, this time one that inlucdes user_id info, to record that I'm logged in. It doesn't issue an 'ad_user_login' cookie, because I'm not permanently logged in, only for this session.
Now, the problem with IE is that when I visit the second server, because dotlrn10-test.dotlrn.collaboraid.net is a subdomain of dotlrn.collaboraid.net, it sends *both* 'ad_session_id' cookies.
Our session/security code, however, only finds the first one, which happens to belong to the *other* site. So we issue a new session cookie, which, again, isn't received back. So we keep reissuing new session cookies, and you're never logged in, because the session cookie that contained the user_id info is never found.
Now I know that it's IE that's broken, but IE is also fairly widely deployed, so I think we should probably fix this bug, however uncommon it is to people to experience it in real-life settings.
What can we do about this problem? Three options:
1) search all 'ad_session_id' cookies for one where the session_id is valid. If found, use that. If not, re-issue.
2) embed the server name or host name in the cookie, and seach all 'ad_sesion_id' cookies.
3) embed the server (host) name in the name of the cookie, e.g. 'ad_session_id.openacs.org' (or 'ad_session_id_openacs_org' if dot's aren't allowed), and search for that.
I prefer option 3, because it's clean and simple and doesn't involve scanning all the cookies ... we go straight to the one we care about.
Of course, all cookies will expire as a consequence of this change, but I suppose we can live with that.
I think we should be able to fix this as part of our external authentication work which will start shortly.
Dots are allowed, only semi-colon, comma and white space are not allowed...
After many days crazy, today i have received a great help of C.R. Oldham, who solved another problem related to https and cookies at this thread:
Well, what I discovered was that Mozilla was violating the cookie spec.
It was storing port numbers with the cookie, so that meant if you logged
in with https you were not logged in via http (and could never get
logged in via http) on nonstandard ports. I reported this as a bug to
the Mozilla developers and after much discussion they finally fixed it
in a late 1.1 build I think. But I have not checked this lately, it's
possible they backed out the changes due to user feedback or something.
In our case IE6 run well. It's Mozilla 1.0 and 1.1 who doesn't.
We will try this with the new Mozilla 1.2 an 1.3b, but maybe it's time to revise a little the cookie's thing.
In our case we only want to use non standard ports (8000 and 8443) for a internal little development website.
When we try to use 8443 for the login via https, with the patch from C.R. Oldham for oacs 4.5 and another code from Ybos (acs 4.2) for non-standard ports, we are able to make it work with IE and Opera, but not with Mozilla, due to the non-standard cookies.
Should we embed the port number as well? Since in http, port number is part of the 'virtual' host? It seems we can't rely on browsers figuring this one out on their own.
Number three is definitely the way to go.
to disambiguate the cookies for hosts that share a domain.
We probably want whatever it is we advertise to the outside world as our "real" url (param SystemURL I guess) but it
could just as easily be some constant hashed together with the server secret (which would then just work automatically for clusters with no risk of collisions).
Jeff, if you run openacs.org:8080 and openacs.org, but only use the openacs.org to grab the cookie, you will be stuck with the same problem, you won't know which one to use. The cookies will again have the same name. A unique id or hash would work, assuming they take into account unique information for each user/virtual server. You can't throw away the port number in http, it is part of the hostname (unless you are on default port 80 or 443 for https).
Just in case we'll need to parse it.
In other words "ad_session_id-[ns_conn location]:[ns_conn port]"
[ns_conn location] includes "http://". Do we want to include that, just because it's the simplest?
How about sharing cookies between http and https for the same server?
Or should we rather use [ad_url] (http://openacs.org)?
We *must* be able to share cookies between http and https for the same server. Otherwise if you have a mixed http and https site and require login over https, you will never be logged in (and can never get logged in) on the http side.
The cookie is set via the HTTP session header:
Set-Cookie: NAME=VALUE; expires=DATE; path=PATH; domain=DOMAIN_NAME; secure
If we don't specify the domain= part, which leaves the decision about what host it is for up to the browser. RFC 2109 states the following about how user agents SHOULD interpret missing values:
4.3 User Agent Role 4.3.1 Interpreting Set-Cookie The user agent keeps separate track of state information that arrives via Set-Cookie response headers from each origin server (as distinguished by name or IP address and port). The user agent applies these defaults for optional attributes that are missing: VersionDefaults to "old cookie" behavior as originally specified by Netscape. See the HISTORICAL section. Domain Defaults to the request-host. (Note that there is no dot at the beginning of request-host.) Max-AgeThe default behavior is to discard the cookie when the user agent exits. Path Defaults to the path of the request URL that generated the Set-Cookie response, up to, but not including, the right-most /. Secure If absent, the user agent may send the cookie over an insecure channel.
and here is what it says about matching host names:
Hosts names can be specified either as an IP address or a FQHN string. Sometimes we compare one host name with another. Host A's name domain-matches host B's if * both host names are IP addresses and their host name strings match exactly; or * both host names are FQDN strings and their host name strings match exactly; or * A is a FQDN string and has the form NB, where N is a non-empty name string, B has the form .B', and B' is a FQDN string. (So, x.y.com domain-matches .y.com but not y.com.) Note that domain-match is not a commutative operation: a.b.c.com domain-matches .c.com, but not the reverse.
So leaving Domain blank should leave the fqdn hostname in the string to be matched against (notice where it says "does not start with a period"). If IE is doing something different - eg. dropping the hostname and leaving a domain instead, then that would explain the problem.
in the past I have specified an fqdn hostname for a cookie which appears to work fine. However, the spec for HTTP/1.0 state management says that shouldn't work:
Domain=domain Optional. The Domain attribute specifies the domain for which the cookie is valid. An explicitly specified domain must always start with a dot.
I'm not sure I have helped here... Russell, do you have any comments?