自定义OWIN CookieAuthenticationProvider在首次启动/冷启动时失败
本文关键字:冷启动 失败 启动 OWIN CookieAuthenticationProvider 自定义 | 更新日期: 2023-09-27 18:02:38
我们有一个自定义cookie验证提供程序,它设置验证cookie以承担主机名,如.domain.com
而不是domain.com
或my.domain.com
。我们这样做,以便cookie跨所有子域和域工作。它如下所示简单。
在应用程序冷启动后的第一次尝试,cookie仍然承受域my.domain.com
(我们的登录是在my.domain.com
上),尽管在执行下面的SubdomainCookieAuthentication
代码后将其设置为.domain.com
(用断点检查)。在随后的登录尝试中,cookie主机名没有问题。
我怎么能解决这个问题,使它工作,甚至在第一次尝试?
代码自定义cookie验证
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);
}
}
在Owin启动类中初始化,如下所示
分类:Startup
文件: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()
});
}
我在使用ResponseSignIn方法的第一次尝试上没有设置Cookie域时遇到同样的问题。我能够通过将Owin库更新到3来解决这个问题。并使用新的CookieManager来设置Domain。从这个帖子找到了这个解决方案:
Owin如何设置Asp ?Net身份验证cookie后的Application_EndRequest阶段?
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;
}
}
然后在Startup.Auth.cs
中注册app.UseCookieAuthentication(new CookieAuthenticationOptions
{
...
CookieManager = new ChunkingCookieManagerWithSubdomains(),
...
}
);