1

I am trying to create a login app that is multi tenant. I am using ASP.NET Core Identity framework.

All I need to do I think is to have a cookie name that is different for each subdomain I access. The domain name is set to ".mydomain.com", if I could have a unique cookie name based on the URL that would be perfect.

I have been reading up on ASP.NET Core Identity but I haven't found the answer so far.

My code looks something like this:

services.ConfigureApplicationCookie(options => 
{
    options.Cookie.Name = "<some name>";
    options.Cookie.Domain "I don't know how to get the domain :-(";
    ...
}
...
services.AddAuthentication();

So assuming this app services https://myauth1 and https://myauth2, if myauth1 is accessed I want to be using the myauth1 cookie and if myauth2 is accessed access myauth2.

My alternative appears to be deploy a separate app for each domain, which feels very wasteful I would like to use multi tenant.

I have also tried in my Configure method and this doesn't work it doesn't get picked up in time:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IOptions<CookieAuthenticationOptions> cookieoptions, IConfiguration configuration) 
{
    app.Use((context, next) =>
    {
        cookieoptions.Value.Cookie.Domain = "my super domain";

        return next.Invoke();
    }
}

So that doesn't work either.

I have narrowed this down to two options:

  1. Either create a custom cookie authentication scheme that uses a httpContextAccessor to name the authentication cookie.
  2. Create some middleware that somehow renames the cookie. I found this https://hanson.io/aspnet-setting-cookies-in-middleware/ but I think option 2 will be very complex.
  3. Set the cookie options in middleware maybe so the cookie name can be set???

Any ideas?

Guru Stron
  • 102,774
  • 10
  • 95
  • 132
Philip Johnson
  • 1,091
  • 10
  • 24

1 Answers1

0

Oh... I think I might have found it. I searched stackoverflow for how to dynamically set a cookie domain. I don't want to set the domain, just the cookie name based on the domain name.

I created a CookieManager that set the cookie name:

using Microsoft.AspNetCore.Authentication.Cookies;

namespace MyNamespace.AuthServer.Ui.Infrastructure.Authentication;

// Code based on https://stackoverflow.com/questions/51874278/is-it-possible-to-support-multiple-cookie-domains-in-net-core?rq=4
// Also I found this for .NET Framework: https://stackoverflow.com/questions/22989920/asp-net-identity-setting-cookiedomain-at-runtime
public class MyCookieManager : ICookieManager
{
    private readonly ICookieManager _cookieManager;

    public MyCookieManager()
    {
        _cookieManager = new ChunkingCookieManager();
    }

    public string GetRequestCookie(HttpContext context, string key)
    {
        key = ModifyKeyIfRequired(context, key);
        return _cookieManager.GetRequestCookie(context, key);
    }

    public void AppendResponseCookie(HttpContext context, string key, string value, CookieOptions options)
    {
        key = ModifyKeyIfRequired(context, key);
        _cookieManager.AppendResponseCookie(context, key, value, options);
    }

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

    private static string ModifyKeyIfRequired(HttpContext context, string key)
    {
        if (key.Contains(".MyNamespace.Auth.Cookies"))
        {
            var host = context.Request.Host.Host;
            var subdomain = GetSubDomain(host);
            key = key + "_" + subdomain;
        }
        return key;
    }

    // https://stackoverflow.com/questions/38549143/how-do-i-get-the-current-subdomain-within-net-core-middleware
    private static string GetSubDomain(string host)
    {
        var subDomain = string.Empty;

        if (!string.IsNullOrWhiteSpace(host))
        {
            subDomain = host.Split('.')[0];
        }

        return subDomain.Trim().ToLower();
    }
}
Philip Johnson
  • 1,091
  • 10
  • 24