We have a custom cookie auth provider that puts sets the auth cookie to bear a hostname like .domain.com
instead of domain.com
or my.domain.com
. We do it so the cookies work across all subdomains and the domains. It's as simple as shown below.
Issue
On the very FIRST attempt after app cold start, the cookie STILL bears the domain my.domain.com
(our logins are on my.domain.com
) DESPITE setting it to .domain.com
after executing the SubdomainCookieAuthentication
code below (checked with breakpoints). On subsequent login attempts, the cookie hostname is fine.
Question
How can I fix this so it works even on the first attempt?
Code
Custom cookie auth
public class SubdomainCookieAuthentication : CookieAuthenticationProvider
{
public override void ResponseSignIn(CookieResponseSignInContext context)
{
// We need to add a "." in front of the domain name to
// allow the cookie to be used on all sub-domains too
var hostname = context.Request.Uri.Host;
// works for www.google.com => google.com
// will FAIL for www.google.co.uk (gives co.uk) but doesn't apply to us
var dotTrimmedHostname = Regex.Replace(hostname, @"^.*(\.\S+\.\S+)", "$1");
context.Options.CookieDomain = dotTrimmedHostname;
base.ResponseSignIn(context);
}
}
This is initialized inside the Owin startup class as follows
Class: Startup
File: App_start\Startup.Auth.cs
public void ConfigureAuth(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new SubdomainCookieAuthentication()
});
}
I was having the same problem with the Cookie Domain not getting set on the first attempt using the ResponseSignIn method. I was able to resolve this by updating the Owin libraries to 3.x and using the new CookieManager to set the Domain. Found this solution from this post:
How is Owin able to set the Asp.Net Identity authentication cookies after the Application_EndRequest stage?
public class ChunkingCookieManagerWithSubdomains : ICookieManager
{
private readonly ChunkingCookieManager _chunkingCookieManager;
public ChunkingCookieManagerWithSubdomains()
{
_chunkingCookieManager = new ChunkingCookieManager();
}
public string GetRequestCookie(IOwinContext context, string key)
{
return _chunkingCookieManager.GetRequestCookie(context, key);
}
public void AppendResponseCookie(IOwinContext context, string key, string value, CookieOptions options)
{
options.Domain = context.Request.Uri.GetHostWithoutSubDomain();
_chunkingCookieManager.AppendResponseCookie(context, key, value, options);
}
public void DeleteCookie(IOwinContext context, string key, CookieOptions options)
{
options.Domain = context.Request.Uri.GetHostWithoutSubDomain();
_chunkingCookieManager.DeleteCookie(context, key, options);
}
}
public static class UriExtensions
{
public static string GetHostWithoutSubDomain(this Uri url)
{
if (url.HostNameType == UriHostNameType.Dns)
{
string host = url.Host;
if (host.Split('.').Length > 2)
{
int lastIndex = host.LastIndexOf(".");
int index = host.LastIndexOf(".", lastIndex - 1);
return host.Substring(index + 1);
}
else
{
return host;
}
}
return null;
}
}
Then, register it in Startup.Auth.cs
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
...
CookieManager = new ChunkingCookieManagerWithSubdomains(),
...
}
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With