Base solution for your next web application
Open Closed

How to Set Tenant According to Domain or Subdomain? #12594


User avatar
0
sarpayonerliberty created

Greetings AspNetZero Team, Tenant selection won't appear on the login page. We're using unique e-mail login feature.

We want to use same application with two different subdomain system.

For Host: https://host.mycompany.com (this will set host (tenantId: null) with it's logo.

For Tenant (No other tenants) https://www.mycompany.com (this will set a specific tenant (tenantId: 1) with it's logo etc.)

What do you suggest to implement this rule?

Current AspNetZero Version: 15

Markdown is supported
Copy & paste or drag & drop images (max 30 MB per image)

3 Answer(s)
  • User Avatar
    0
    oguzhanagir created
    Support Team

    Hi @sarpayonerliberty

    Since you want to run the same application under two different subdomains with a fixed behavior, the cleanest solution is to implement a custom ITenantResolveContributor and place it at the beginning of the tenant resolution pipeline.

    You can create a custom resolver like below:

    public class FixedSubdomainTenantResolveContributor 
        : ITenantResolveContributor, ITransientDependency
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
    
        public FixedSubdomainTenantResolveContributor(
            IHttpContextAccessor httpContextAccessor)
        {
            _httpContextAccessor = httpContextAccessor;
        }
    
        public int Order => 0; // Ensure this runs before default resolvers
    
        public string Name => "FixedSubdomain";
    
        public Task ResolveAsync(ITenantResolveContext context)
        {
            var httpContext = _httpContextAccessor.HttpContext;
            if (httpContext == null)
            {
                return Task.CompletedTask;
            }
    
            var host = httpContext.Request.Host.Host.ToLowerInvariant();
    
            if (host == "www.mycompany.com")
            {
                // Resolve to a specific tenant
                context.TenantId = 1;
            }
            else if (host == "host.mycompany.com")
            {
                // Host context
                context.TenantId = null;
            }
    
            return Task.CompletedTask;
        }
    }
    

    Then register it in your core module:

    Configuration.MultiTenancy.Resolvers.Insert(
        0,
        typeof(FixedSubdomainTenantResolveContributor)
    );
    

    If you need any assistance after implementing this approach, please do not hesitate to contact us.

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)
  • User Avatar
    0
    sarpayonerliberty created

    Hi Oğuzhan, I think ITenantResolveContext interface does not exist in the AspNetZero project. I saw it in an abp.io document page. With your suggestion, I implemented like below, but the login page could not be loaded.

    public class FixedSubdomainTenantResolveContributor(IHttpContextAccessor httpContextAccessor)
        : ITenantResolveContributor, ITransientDependency
    {
        public int? ResolveTenantId()
        {
            var httpContext = httpContextAccessor.HttpContext;
    
            if (httpContext == null)
            {
                return null;
            }
            
            var host = httpContext.Request.Host.Host.ToLowerInvariant();
            if (host == "localhost")
            {
                // Resolve to a specific tenant
                return 1;
            }
    
            return null;
        }
    }
    
    public override void PreInitialize()
    {
        Configuration.MultiTenancy.Resolvers.Insert(
            0,
            typeof(FixedSubdomainTenantResolveContributor)
        );
    }
    

    When I run the host project, I got the below error on the console. AspNet side does not show any error.

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)
  • User Avatar
    0
    oguzhanagir created
    Support Team

    Hi @sarpayonerliberty

    Yes, you're absolutely right, there's been a slight misunderstanding. In your scenario, it would be much more accurate to overwrite the DomainTenantResolveContributor (File) in the ABP package. Here, you can check the subdomain by verifying the value returned from the IsDomainFormatValid function and perform Tenant Id resolution. You need to register the custom Contributor you created back into the Core module.

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)