Base solution for your next web application
Open Closed

Access host side with host.domain.com #9668


User avatar
0
ignasiclos created

Hello,

we'd like to use our domain "domain.com" as the public webpage for our product, "host.domain.com" for accessing the host features, and the rest of subdomains for the different tenants.

I've seen that the tenant resolver is inside ABP and I couldn't find a way to replace this resolver with a custom one that can handle the special "host" tenant name.

How can we achieve this? Thanks


2 Answer(s)
  • User Avatar
    0
    mk2software created

    Hey, we've done this many times in our projects.

    So we create a MyDomainTenantResolveContributor.cs in the root folder of the *.Web.Core project, with the following content:

    public class MyDomainTenantResolveContributor : ITenantResolveContributor, ITransientDependency
    {
    private readonly IHttpContextAccessor _httpContextAccessor;
    private readonly IWebMultiTenancyConfiguration _multiTenancyConfiguration;
    private readonly ITenantStore _tenantStore;
    private readonly ILocalizationManager _localizationManager;
    public MyDomainTenantResolveContributor(
    IHttpContextAccessor httpContextAccessor,
    IWebMultiTenancyConfiguration multiTenancyConfiguration,
    ITenantStore tenantStore,
    ILocalizationManager localizationManager)
    {
    _httpContextAccessor = httpContextAccessor;
    _multiTenancyConfiguration = multiTenancyConfiguration;
    _tenantStore = tenantStore;
    _localizationManager = localizationManager;
    }
    public int? ResolveTenantId()
    {
        if (_multiTenancyConfiguration.DomainFormat.IsNullOrEmpty())
        {
            return null;
        }
    
        var httpContext = _httpContextAccessor.HttpContext;
        if (httpContext == null)
        {
            return null;
        }
    
        var hostName = httpContext.Request.Host.Host.RemovePreFix("http://", "https://").RemovePostFix("/");
        var domainFormat = _multiTenancyConfiguration.DomainFormat.RemovePreFix("http://", "https://").Split(':')[0].RemovePostFix("/");
        var result = new FormattedStringValueExtracter().Extract(hostName, domainFormat, true, '/');
    
        var tenancyName = result.Matches[0].Value;
    
        if (string.Equals(tenancyName, "host", StringComparison.OrdinalIgnoreCase))
        {
            return null;
        }
    
        var tenantInfo = _tenantStore.Find(tenancyName);
        if (tenantInfo == null)
        {
            var noTenantFound = _localizationManager.GetString(AppConsts.LocalizationSourceName, "NoTenantFound");
            var noTenantFoundDetail = _localizationManager.GetString(AppConsts.LocalizationSourceName, "NoTenantFoundDetail");
            throw new UserFriendlyException(noTenantFound, noTenantFoundDetail);
        }
    
        return tenantInfo.Id;
    }
    
    }
    

    And then we add a reference to it in our PreInitialize method of the *WebMvcModule.cs: if (!_env.IsDevelopment() && !_env.IsStaging()) { Configuration.MultiTenancy.Resolvers.Insert(0, typeof(MyDomainTenantResolveContributor)); }

    We also added the same line in the PreInitialize method of the *WebCoreModule.cs, but not sure if that is needed though.

  • User Avatar
    0
    ignasiclos created

    Thanks a lot