Open Closed

Issues with Multi-Tenancy Configuration - Invalid Issuer in Discovery Document #7297


User avatar
0
anurag.tyagi created

Hello,

  • ABP Framework version: v8.0.2
  • UI Type: Angular
  • Database System: EF Core (MySQL)
  • Auth Server Separated (for Angular): no
  • Exception message and full stack trace: invalid issuer in discovery document expected: https://tenant.api.mydomain.com current: https://api.mydomain.com/
  • Steps to reproduce the issue: Enable multytenancy in abp using official documentation (https://docs.abp.io/en/abp/latest/Multi-Tenancy#domain-subdomain-tenant-resolver) try to login

I have enabled multitenancy in my project using the documentation provided at ABP Multi-Tenancy Guide.

However, I'm encountering an issue. When I try to open the URL tenant.mydomain.com, I am redirected to tenant.api.mydomain.com, and I get the following console log error in the browser:

invalid issuer in discovery document expected: https://tenant.api.mydomain.com current: https://api.mydomain.com/

When I check the https://api.mydomain.com/.well-known/openid-configuration endpoint, I see the following configuration:

{
  "issuer": "https://api.mydomain.com",
  "authorization_endpoint": "https://tenant.api.mydomain.com/connect/authorize",
  "token_endpoint": "https://tenant.api.mydomain.com/connect/token",
  "introspection_endpoint": "https://tenant.api.mydomain.com/connect/introspect",
  "end_session_endpoint": "https://tenant.api.mydomain.com/connect/logout"
}

It seems like the issuer doesn't include the tenant name in the subdomain. Could you please guide me on what additional steps I need to take to ensure that the issuer includes the tenant name in the subdomain and that the tenant domain resolver works correctly?

P.S. if you know any better or complete documentation please let me know

Thanks in advance


12 Answer(s)
  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    There is an example: https://github.com/abpframework/abp-samples/tree/master/DomainTenantResolver

  • User Avatar
    0
    anurag.tyagi created

    Hi,

    Thanks for your quick response.

    I also found that example and based on my comparison, it seems like I have a similar setup (nevertheless the the example version I below my current version).

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    You can check it. It still works.

  • User Avatar
    0
    anurag.tyagi created

    I checked it and tried to include changes from https://github.com/abpframework/abp-samples/blob/master/DomainTenantResolver/OpenIddict/NG/aspnet-core/src/BookStore.HttpApi.Host/BookStoreHttpApiHostModule.cs to my project, however, I still get the same result and the issuer is still wrong. from the commit history, I don't see if there are more changes to be done, maybe you can give a hint about which files to look?

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Did you change the Angular project? https://github.com/abpframework/abp-samples/blob/master/DomainTenantResolver/OpenIddict/NG/angular/src/environments/environment.ts#L13

  • User Avatar
    0
    anurag.tyagi created

    Yes, I changed that file as well, but I am still encountering the same error. Can you please point out the configuration that will allow OpenIddict to hook the issuer from the subdomain?

    From the documentation, it seems like this should achieve that:

    // using Volo.Abp.OpenIddict.WildcardDomains
    
    PreConfigure<AbpOpenIddictWildcardDomainOptions>(options => 
    {
        options.EnableWildcardDomainSupport = true;
        options.WildcardDomainsFormat.Add("https://{0}.api.mydomain.com");
    });
    

    I have included this configuration as well, but the issuer still defaults to the main domain of the backend (api.mydomain.com) instead of the subdomain (tenant.api.mydomain.com).

    Is there any other setting or configuration that I might be missing to ensure the issuer includes the tenant name in the subdomain?

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    It looks like no problem.

    If you use this example locally, will it work as expected? https://github.com/abpframework/abp-samples/tree/master/DomainTenantResolver/OpenIddict/NG

  • User Avatar
    0
    anurag.tyagi created

    I added the code from that example to my project (v8.0.2) and deployed the version to an environment with an actual domain/subdomain, but it did not work. It has the issue that I described in the initial question.

    can you maybe give some hints and ideas, on what could I check, and where I could have an issue?

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    I don't know yet.

    Could you try this?

    Configure<OpenIddictServerOptions>(options =>
    {
        options.TokenValidationParameters.IssuerValidator = TokenWildcardIssuerValidator.IssuerValidator;
        options.TokenValidationParameters.ValidIssuers = new[]
        {
            "https://api.mydomain.com/",
            "https://{0}.api.mydomain.com/"
        };
    });
    

    If still not working, could you share an example project with me via email? I will check it. My email is shiwei.liang@volosoft.com thanks.

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    It works for me:

    I made some changes and sent the file back to you. You can check it.

    • run the dbmigrator to create db
    • change the host file to add govgpt host
    • run the httpapi.host project
    • run the angular project : yarn start --host govgpt --disable-host-check
  • User Avatar
    0
    anurag.tyagi created

    Hi, thanks for the help. It got us quite far. I believe we only have one last issue before subdomains work for us:

    we have a frontend angular method that establishes a connection to the backend but it reads the backend url from the appsettings and hence also contains the {0}, which is not resolved and not recognized by the backend.

    private createConnection(): void {
        this.hubConnection = new HubConnectionBuilder()
          .withUrl(environment.apis.default.url + '/hubroute', { accessTokenFactory: () => localStorage.getItem('access_token') })
          .withAutomaticReconnect()
          .build();
      }
    

    is there an out of the box way to get the resolved tenant url in the frontend?

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    This is signalR native code, you need to replace the URL yourself

Made with ❤️ on ABP v9.1.0-preview. Updated on December 10, 2024, 06:38