2017-05-28 52 views
5

Mam stronę, która używa wielu adresów URL do tego samego wniosku:Multiple & Cookie subdomenę w Tożsamości asp.net podstawowej

na przykład: * .MyWebPage.com.au * .YourWebPage.com.au

Wykorzystuje poddomeny na wielu adresach URL. Problem polega na tym, że muszę umożliwić uwierzytelnienie użytkownika we wszystkich subdomenach adresu URL, do którego się zalogował.

Na przykład, jeśli logują się za pośrednictwem witryny www.mywebpage.com.au, plik cookie musi być ustawiony na * .mywebpage.com.au lub jeśli logują się przez www.yourwebpage.com.au plik cookie powinien być *. yourwebpage.com.au.

Większość dokumentacji, pozwalając subdomen dla ASP.NET punktów identyfikacyjnych rdzeń do startup.cs (lub startup.auth.cs) pliku i wprowadzając coś takiego: `

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

to nie będzie działać dla mnie, ponieważ nie chcę stałej domeny, chcę tylko umożliwić wszystkim użytkownikom dostęp do wszystkich subdomen dla adresu URL, w którym się zalogowali. Mogę oczywiście uzyskać ich adres URL w momencie logowania przez żądanie, ale muszę dynamicznie ustawić cookiedomain w tym momencie.

+0

Nie jestem absolutnie pewien; ale w przypadku tego rodzaju spraw - jestem prawie pewien, że będziesz musiał czerpać z niego lub tworzyć własne oprogramowanie pośredniczące do plików cookie. – Svek

+0

Ten pomysł wykorzystania SaasKit do umożliwienia współdzielenia wielu rdzeni ASP.NET Core może być możliwym rozwiązaniem http://benfoster.io/blog/aspnet-core-multi-tenant-middleware-pipelines – Svek

Odpowiedz

4

To, czego nie zdawałem sobie sprawy, kiedy zaczynałem, to różnica między tożsamością a uwierzytelnianiem CookeieAuthentication. Ponieważ używałem tożsamości

 app.UseIdentity(); 

app.UseCookieAuthentication nie było rozwiązaniem.

W końcu znalazłem swoje rozwiązanie, wdrażając ICookieManager.

Oto moje rozwiązanie:

w 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(); 

teraz w klasie nazwałem 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

Dla każdego, kto implementuje htis, będzie również musiał obsługiwać zdarzenie deletecookie, dodając options.Domain = RemoveSubdomain (context.Request.Host.Host) – michael

1

Ile jest głównych domen? Jeśli nie ma ich zbyt wiele, możesz dodać kilka CookieAuthenticationOptions. W ten sposób:

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

Jeśli istnieje zbyt wiele domen głównych, musisz napisać własnego dostawcę plików cookie.

1

oprócz @ rozwiązania Michaela:

  • ICookie: ICookie Interface to warstwa abstrakcji na wierzchu http cookie object, która zabezpiecza data.
  • ICookieManager: Cookie Manager to warstwa abstrakcji na wierzchu ICookie Interface. To rozszerza zachowanie Cookie pod względem ogólnej obsługi <TSource>. Jest to realizowane przez klasę DefaultCookieManager. ICookie Interface jest depedenacją tej klasy.
  • Wykorzystanie CookieManager:

    1. Dodaj CookieManager w startowego Konfiguracja usługi.
    2. Dostęp do interfejsu API CookieManager.
    3. Kod źródłowy jest dostępny pod numerem git przez Nemi Chand.
0

Dodawanie do @ odpowiedź Michaela: Jak "obsłużyć zdarzenia DeleteCookie, dodając options.Domain = RemoveSubdomain (context.Request.Host.Host)": wystarczy dodać

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

przed

ConcreteManager.DeleteCookie(context, key, options); 

w

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

I nie zapomnij zadzwonić do CookieManager.DeleteCoockie przy wylogowaniu!

PS Jeśli musisz mieć możliwość zalogowania się zarówno na subdomena.example.com, jak i na example.com - musisz zmodyfikować AppendResponseCookie (..) {..}, lub dostaniesz tylko domenę TLD (. com/.ru itp.) tutaj