Open Closed

Multitenant Domain resolver in microservice architecture. #3671


User avatar
0
imranStem created

I have microservice architecture and I followed the multi-tenancy domain resolver document but it's not working in a microservice architecture. Can you please provide some documentation to integrate multi-tenancy domain resolver in a microservice architecture? I have following question.

  1. Do we need to add the following configuration in all microservices and web gateways?
   Configure<AbpTenantResolveOptions>(options =>  
        {
            options.AddDomainTenantResolver("{0}.api.getabp.net:44367");
        });
  1. Do we need to change the configuration in ocelet.json file as below?
{
      "ServiceKey": "Account Service",
      "DownstreamPathTemplate": "/api/account/{everything}",
      "DownstreamScheme": "https",
      "DownstreamHostAndPorts": [
        {
         "Host": "{0}.api.getabp.net", // host name change here
          "Port": 44322
        }
      ],
      "UpstreamPathTemplate": "/api/account/{everything}",
      "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ]
    }

`

  • ABP Framework version: v5.2.1
  • UI type: Angular
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): yes
  • Exception message and stack trace:
  • Steps to reproduce the issue:"

8 Answer(s)
  • User Avatar
    0
    imranStem created

    Anybody is there? Need proper documentation on multi-tenancy domain resolver on microservice architecture

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    I think the Ocelot doesn't support the wildcard feature.

    https://github.com/ThreeMammals/Ocelot/issues/480

  • User Avatar
    0
    imranStem created

    Currently, I am facing the issue of login in with the tenant URL.

    Getting below error when trying to login with tenant login page.

    vendor.js:169503 invalid issuer in discovery document expected: https://red.api.getabp.net:44322 current: http://api.getabp.net:44322

    Configure<IdentityServerOptions>(options =>
            {
                options.IssuerUri = configuration["App:SelfUrl"];
            });
    
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Can you compare the config in the angular example?

    https://github.com/abpframework/abp-samples/blob/master/DomainTenantResolver/NG/angular/src/environments/environment.ts

  • User Avatar
    0
    imranStem created

    I noticed skipIssuerCheck: true. This will help.

    I have one more issue here. Can I have different domains specific tenant configuration as the example below?

    sub1.domain.com as host sub2.domain.com as tenant tenant1.com as tenant tenant2.co.uk as tenant tenant3.net as tenant

    because the tenant may have their own domain instead of the sub-domain of the host domain or they may choose a subdomain as well.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    For mvc you can custom the DomainTenantResolver to make it possible.

    https://github.com/abpframework/abp/blob/dev/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/DomainTenantResolveContributor.cs#L26

  • User Avatar
    0
    imranStem created

    I have created my custom domain tenant resolver class. I have the below configuration in a microservice architecture. I am using the 6.0 preview version.

    Angular Host Domain: abp.mydomain.com Gateway domain: abpapi.mydomain.com AuthServer domain: abpauth.mydomain.com

    Tenant domain: tenant.mydomain.com The gateway and auth server are the same as above.

     Configure<AbpTenantResolveOptions>(options =>
            {
                options.TenantResolvers.Clear();
                options.TenantResolvers.Add(new TenantDomainResolver("{0}.mydomain.com"));
            });
    

    Tenant Domain Resolver

    public class TenantDomainResolver: TenantResolveContributorBase
        {
            public const string ContributorName = "Custom";
    
            public override string Name => ContributorName;
    
            private static readonly string[] ProtocolPrefixes = { "http://", "https://" };
    
            private readonly string _domainFormat;
            public TenantDomainResolver(string domainFormat)
            {
                _domainFormat = domainFormat;
            }
            public override async Task ResolveAsync(ITenantResolveContext context)
            {
                var httpContext = context.GetHttpContext();
    
                var referer = httpContext.Request.Headers["Referer"].ToString();
    
                if (string.IsNullOrEmpty(referer))
                {
                    return;
                }
    
                referer = referer.RemovePreFix(ProtocolPrefixes);
                var extractResult = FormattedStringValueExtracter.Extract(referer, _domainFormat, ignoreCase: true);
                if (extractResult != null && extractResult.IsMatch)
                {
                    if (extractResult.Matches[0].Value != "abp")  // if referer is not host domain
                    {
                        context.Handled = true;
                        context.TenantIdOrName = extractResult.Matches[0].Value;
                    }
                }
    
            }
    

    It's working fine as the host domain 'abp.mydomain.com' from the angular application but when I browse by the 'tenant.mydomain.com' angular application, its calls API 'https://abpapi.mydomain.com/api/abp/multi-tenancy/tenants/by-name/tenant' and throwing an exception as below.

    There is no tenant with the tenant id or name: tenant

    but when I copy the endpoint URL and directly call in the browser, it's showing the tenant data.

    {"success":true,"tenantId":"40cd013e-dfb4-e3e7-e205-3a0653710d75","name":"tenant","isActive":true}

    These are the logs of web gateway.

    2022-09-16 18:24:23.492 +05:30 [INF] Application started. Press Ctrl+C to shut down. 2022-09-16 18:24:23.492 +05:30 [INF] Hosting environment: Production 2022-09-16 18:24:23.492 +05:30 [INF] Content root path: D:\abp\abp6\publish\web
    2022-09-16 18:24:23.516 +05:30 [INF] Request starting HTTP/2 OPTIONS https://abpapi.mydomain.com/api/abp/multi-tenancy/tenants/by-name/tenant - - 2022-09-16 18:24:23.530 +05:30 [INF] CORS policy execution successful. 2022-09-16 18:24:23.541 +05:30 [INF] Request starting HTTP/2 GET https://abpapi.mydomain.com/api/abp/multi-tenancy/tenants/by-name/tenant - - 2022-09-16 18:24:23.542 +05:30 [INF] CORS policy execution successful. 2022-09-16 18:24:23.547 +05:30 [INF] Request finished HTTP/2 OPTIONS https://abpapi.mydomain.com/api/abp/multi-tenancy/tenants/by-name/tenant - - - 204 - - 31.0747ms 2022-09-16 18:24:23.573 +05:30 [INF] Request finished HTTP/2 GET https://abpapi.mydomain.com/api/abp/multi-tenancy/tenants/by-name/tenant - - - 500 - text/html 31.7616ms

  • User Avatar
    0
    imranStem created

    I fixed the issue. I registered a domain resolver on the gateway level. I removed from gateway and registered in administration microservice level.

Made with ❤️ on ABP v9.1.0-preview. Updated on November 11, 2024, 11:11