2017-05-28 34 views
5

我有一个使用多个网址为同一应用程序的网页:多和子站点在asp.net核心身份饼干

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

所以它会在多个URL上使用子域名。问题是我需要允许用户在他们登录到的url的所有子域上进行身份验证。

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

大多数文件中允许ASP.NET核心身份分子域的startup.cs(或startup.auth.cs)文件,并进入这样的:`

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

这是不行的对于我来说,因为我不想要一个固定的域名,我只想让所有用户都可以访问他们已登录的网址的所有子域名。我明显可以在登录时通过请求获取它们的URL,但是我需要在此时动态设置cookiedomain。

+0

我不是绝对肯定的;但是,对于这种情况 - 我几乎肯定您必须从中派生出来,或者创建自己的Cookie中间件。 – Svek

+0

使用SaasKit来允许多租户ASP.NET Core管道的想法可能是一种可行的解决方案http://benfoster.io/blog/aspnet-core-multi-tenant-middleware-pipelines – Svek

回答

4

我刚开始时没有意识到的是Identity和CookeieAuthentication之间的区别。 由于我使用Identity

 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 
+0

对于任何实施htis的人,您还需要处理deletecookie事件,添加options.Domain = RemoveSubdomain(context.Request.Host.Host) – michael

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提供程序。

1

除了@迈克尔的解决方案:

  • ICookieICookie Interfacehttp cookie object之上的抽象层,它保护了data
  • ICookieManagerCookie Manager是位于ICookie Interface之上的抽象层。这扩展了Cookie的行为方面,<TSource>通用支持,Func<TResult>。这是通过DefaultCookieManager类实现的。 ICookie Interface是这个班的同仁。
  • CookieManager用法:

    1. 添加CookieManager在启动配置服务。
    2. 访问CookieManager API。
    3. 源代码可在git之前Nemi Chand
0

加成@迈克尔的回答是: 如何 “处理deletecookie事件,加入options.Domain = RemoveSubdomain(context.Request.Host.Host)”: 只需添加

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

ConcreteManager.DeleteCookie(context, key, options); 

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

并且不要忘记在注销时调用CookieManager.DeleteCoockie!另外,如果您需要能够在subdomain.example.com和example.com上登录 - 您需要修改AppendResponseCookie(..){..},否则您将只获得TLD(。)。 com/.ru等)这里