【问题标题】:Custom OWIN CookieAuthenticationProvider fails on 1st/cold boot自定义 OWIN CookieAuthenticationProvider 在第一次/冷启动时失败
【发布时间】:2015-09-09 08:55:39
【问题描述】:

我们有一个自定义 cookie 身份验证提供程序,它将身份验证 cookie 设置为带有类似 .domain.com 的主机名,而不是 domain.commy.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()
    });
}

【问题讨论】:

  • 你解决过这个问题吗?
  • 好像是bug,是时候报告github问题了

标签: c# asp.net authentication cookies owin


【解决方案1】:

我在第一次尝试使用 ResponseSignIn 方法时没有设置 Cookie 域时遇到了同样的问题。我能够通过将 Owin 库更新到 3.x 并使用新的 CookieManager 设置域来解决这个问题。从这篇文章中找到了这个解决方案:

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;
    }
}

然后,在 Startup.Auth.cs 中注册

app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        ...
        CookieManager = new ChunkingCookieManagerWithSubdomains(), 
        ...
    }
);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-02
    • 2011-07-18
    • 2019-06-30
    • 2017-02-24
    • 1970-01-01
    • 2017-03-31
    • 2021-12-23
    • 1970-01-01
    相关资源
    最近更新 更多