多个& asp.net核心身份中的子域名cookie

时间:2017-05-28 13:33:52

标签: asp.net-core asp.net-core-mvc asp.net-identity

我有一个网页,它为同一个应用程序使用多个URL:

例如:    * .MyWebPage.com.au    * .YourWebPage.com.au

因此它将在多个网址上使用子域名。问题是我需要允许用户在他们登录的URL的所有子域上进行身份验证。

例如,如果他们通过www.mywebpage.com.au登录,则需要为* .mywebpage.com.au设置cookie,或者如果他们通过www.yourwebpage.com.au登录,则cookie应为* .yourwebpage .com.au。

允许ASP.NET核心标识子域的大多数文档都指向startup.cs(或startup.auth.cs)文件并输入如下内容:`

app.UseCookieAuthentication(new CookieAuthenticationOptions()
            {
                CookieDomain = "mywebpage.com.au"
            });`

这对我不起作用,因为我不想要一个固定的域名,我只想让所有用户都可以访问他们登录的URL的所有子域名。我可以通过请求显然在登录时获取他们的URL,但我需要动态设置cookiedomain。

4 个答案:

答案 0 :(得分:6)

我开始时没想到的是Identity和CookeieAuthentication之间的区别。 因为我使用的是身份

        app.UseIdentity();

app.UseCookieAuthentication不是解决方案。

我终于通过实施ICookieManager找到了我的解决方案。

这是我的解决方案:

在Startup.cs中:

    services.AddIdentity<ApplicationUser, IdentityRole>(options =>
        {
            options.Password.RequireDigit = false;
            options.Password.RequiredLength = 5;
            options.Password.RequireNonAlphanumeric = false;
            options.Password.RequireLowercase = false;
            options.Password.RequireUppercase = false;
            options.Cookies.ApplicationCookie.CookieManager = new CookieManager(); //Magic happens here
        }).AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();

现在在一个叫做CookieManager.cs的类中:

public class CookieManager : ICookieManager
{
    #region Private Members

    private readonly ICookieManager ConcreteManager;

    #endregion

    #region Prvate Methods

    private string RemoveSubdomain(string host)
    {
        var splitHostname = host.Split('.');
        //if not localhost
        if (splitHostname.Length > 1)
        {
            return string.Join(".", splitHostname.Skip(1));
        }
        else
        {
            return host;
        }
    }

    #endregion

    #region Public Methods

    public CookieManager()
    {
        ConcreteManager = new ChunkingCookieManager();
    }

    public void AppendResponseCookie(HttpContext context, string key, string value, CookieOptions options)
    {

        options.Domain = RemoveSubdomain(context.Request.Host.Host);  //Set the Cookie Domain using the request from host
        ConcreteManager.AppendResponseCookie(context, key, value, options);
    }

    public void DeleteCookie(HttpContext context, string key, CookieOptions options)
    {
        ConcreteManager.DeleteCookie(context, key, options);
    }

    public string GetRequestCookie(HttpContext context, string key)
    {
        return ConcreteManager.GetRequestCookie(context, key);
    }

    #endregion

答案 1 :(得分:3)

除了@ michael的解决方案:

  • ICookieICookie Interfacehttp cookie object之上的抽象层,用于保护data
  • ICookieManagerCookie ManagerICookie Interface之上的抽象层。这会根据<TSource>通用支持Func<TResult>扩展Cookie行为。这由DefaultCookieManager类实现。 ICookie Interface是这门课程的完整之处。
  • CookieManager的用法:

    1. 在启动配置服务中添加CookieManager
    2. 访问CookieManager API。
    3. 源代码可在git Nemi Chand上找到。

答案 2 :(得分:1)

有多少主要域名?如果没有太多,可以添加几个CookieAuthenticationOptions。像这样:

        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationScheme = "mywebpage.com.au",
            CookieDomain = "mywebpage.com.au",
        });
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationScheme = "yourwebpage.com.au",
            CookieDomain = "yourwebpage.com.au",
        });

如果主域名太多,您需要编写自己的cookie提供程序。

答案 3 :(得分:1)

除了@ michael的回答: 如何“处理deletecookie事件,添加options.Domain = RemoveSubdomain(context.Request.Host.Host)”: 只需添加

options.Domain= RemoveSubdomain(context.Request.Host.Host);

    ConcreteManager.DeleteCookie(context, key, options);

in

CookieManager.DeleteCoockie(..){..};

不要忘记在注销时调用CookieManager.DeleteCoockie!

PS此外,如果您需要能够在subdomain.example.com和example.com上同时登录 - 您需要修改AppendResponseCookie(..){..},否则您将只获得TLD(.com) /.ru等)这里