3

We have a SaaS platform in which we are on a process to migrate it to a Multi-Tenants architecture. We have multiple micro-services and one Identity server which uses IdentityServer4.

In each service in the Startup.cs we have the following code:

services.AddAuthentication("Bearer")
        .AddIdentityServerAuthentication(options =>
        {
            options.Authority = Configuration["URLs:IdentityServer"];
            options.RequireHttpsMetadata = false;

            options.ApiName = "apiInternal";
        });

We are using subdomains to distinguish between tenants and each tenant has its own database.

The only problem we are facing is with the IdentityServer.

Our goal is that we will have a different Identity service for each tenant. But we could not figure out how to replace the authority at runtime based on the subdomain (tenant).

Actually, we tried this approach:

How can I set the Authority on OpenIdConnect middleware options dynamically?

After some changes it worked with only one problem, the authority is changing only on the first request, meaning, if the first request was from tenant1.example.com it will use the tenant1 identity authority, but any other request will "change" the authority but will use tenant1 authority.

For example, if the second request is from tenat2.example.com we will see the code that changes the authority kick in, but in actual, it is not replacing the authority.

What I suspect that happens is that the authority has changed, but it does not initialize the IdentityServer data.

If that is actually the problem, I have a couple of questions:

How do I solve it?

What do you think the performance impact will be given the fact that on each request, we will have to get the IdentityServer data for token validation?

Any other ideas what would be a best practice for having idenityserver4 with a multi-tenants approach?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Shaul Zuarets
  • 839
  • 2
  • 10
  • 20
  • 2
    Perhaps the answer [here](https://stackoverflow.com/questions/51231697/asp-net-core-2-enable-multi-tenancy-using-identity-server-4) can help you. –  Oct 06 '19 at 10:29
  • The problem with that approach is that someone can get a token from tenant1-identity and use it in tenant2-service – Shaul Zuarets Oct 06 '19 at 11:26
  • 1
    You can include a tenant url or id as claim (if not already the case) and use that to validate against the current subdomain in JwtBearerEvents.OnTokenValidated. If it doesn't match you can deny access. –  Oct 06 '19 at 11:34
  • That actually worked. I've left with one problem now, on the OnTokenValidated, if the tenant do not match the token issuer, I'm throwing an exception, the problem is that instead of returning 401, it returns 500. Do you know how to return 401 from OnTokenValidated? Thanks! – Shaul Zuarets Oct 06 '19 at 18:21
  • 1
    `context.Fail("Invalid token");` or something like that. –  Oct 06 '19 at 18:32

0 Answers0