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?