I have a web app can be installed on lots of domains and paths.
So:
- client1Name.{mySite.com}
- client2Name.{mySite.com}
- demo.{mySite.com}/prospect1Name
- demo.{mySite.com}/prospect2Name
- demo.{mySite.com}/prospect3Name
All separate application instances of the same code.
The problem is that if a client logs in to client1Name.{mySite.com} then visits one of the other sites their browser will send the authentication cookie.
In all cases FormsAuthentication.SetAuthCookie doesn't set either the Path or the Domain.
What I would expect is:
- client1Name.{mySite.com} -
Domain= client1Name.{mySite.com}Path= / - client2Name.{mySite.com} -
Domain= client2Name.{mySite.com}Path= / - demo.{mySite.com}/prospect1Name -
Domain= demo.{mySite.com}Path= /prospect1Name - demo.{mySite.com}/prospect2Name -
Domain= demo.{mySite.com}Path= /prospect2Name - demo.{mySite.com}/prospect3Name -
Domain= demo.{mySite.com}Path= /prospect3Name
I can manually override .Net's behaviour to explicitly set these, but I'm not sure why I should need to - sure this should be the default behaviour when setting an authentication cookie or at least an option that can be set without re-writing big chunks of it.
Am I missing something? Is there some way to make FormsAuthentication.SetAuthCookie set the Path and Domain?
If not what is the best way to dynamically read the best Path and Domain? The same code has to run on all sites and I don't want to add a further configuration key.
Update
Here is my current solution:
// replacement for FormsAuthentication.SetAuthCookie(user.UserName, false);
// as that fails to limit the cookie by domain & path and fails.
var cookie = FormsAuthentication.GetAuthCookie(username, false);
cookie.HttpOnly = true;
cookie.Path = this.Request.ApplicationPath;
cookie.Secure = string.Equals("https", this.Request.Url.Scheme, StringComparison.OrdinalIgnoreCase);
// the browser will ignore the cookie if there are fewer than two dots
// see cookie spec - http://curl.haxx.se/rfc/cookie_spec.html
if (this.Request.Url.Host.Split('.').Length > 2)
{
// by default the domain will be the host, so www.site.com will get site.com
// this may be a problem if we have clientA.site.com and clientB.site.com
// the following line will force the full domain name
cookie.Domain = this.Request.Url.Host;
}
this.Response.Cookies.Add(cookie);
However, that seems like a lot of workaround for something FormsAuthentication.SetAuthCookie should be able to do. Is this really the best way?