Asp.net-Core

asp.net Core Identity 中的 Multiple & SubDomain 的 cookie

  • January 4, 2020

我有一個網頁為同一個應用程序使用多個 URL:

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

因此它將在多個 url 上使用子域。問題是我需要允許使用者在他們登錄的 url 的所有子域上進行身份驗證。

例如,如果他們通過 www.mywebpage.com.au 登錄,則需要為 *.mywebpage.com.au 設置 cookie,或者如果他們通過 www.yourwebpage.com.au 登錄,則 cookie 應為 *.yourwebpage.com。澳大利亞

大多數允許 ASP.NET 核心標識的子域的文件都指向 startup.cs(或 startup.auth.cs)文件並輸入如下內容:`

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

這對我不起作用,因為我不想要一個固定的域,我只想讓所有使用者都可以訪問他們登錄的 url 的所有子域。我顯然可以在登錄時通過請求獲取他們的 url,但此時我需要動態設置 cookiedomain。

我剛開始時沒有意識到 Identity 和 CookieAuthentication 之間的區別。因為我使用的是身份

       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

引用自:https://stackoverflow.com/questions/44227873