Multiple Tenants one API

Hi -

Right now, I have a single tenant (tenant1) with a hosted login page (hlp1) and single server side API that is secured by the access token created from that tenant / hosted page.

I am trying to set up multiple hosted login pages by creating separate tenants - but I want to have the access token for all the tenants be used by the same server-side API.

Is there any solution to this?

For example, I want all these subdomains to have their own hosted login page but to use the same server-side api:

www.partner.company.com
www.customer.company.com

I’ve looked into using rules to set roles (per link below)- but the issue there is I need to set the role based on sign up link (there is no pattern that I can grep out of the users email). So for example:

Sign Up As A Partner → www.partner.company.com
Sign Up As A Customer → www.customer.company.com

Thanks!

1 Like

Hi there.
First let me answer your question right away, but then I’ll go back to architectural decisions.
Each tenant has its own set of public/private key to generate and validate the token signature, and the iss (issuer) claim on JWT tokens will vary depending on the tenant. This means, effectively, that tokens generated from different tenants are completely independent.
Now, nothing prevents you from building a server-side API authorized by JWT tokens that looks for the iss claim and, based on it, fetches the matching public key to validate the signature. Some of the Jwt Bearer authentication SDKs (like ASP.Net’s) allows you to easily configure support for more than one token issuer, but it’s definitely not a common scenario.

Which leads me to the architectural decisions talk. As I said before, having more than one token issuer for an API would be really uncommon. Thinking of a widely know API such as the Google Docs API. You might have a third-party app made by Acme.com that wants to use the API, but the issuer of tokens is Google, and the authentication comes from Google Accounts. When requesting a token for the Google Docs API, the login page is branded by Google, with a mention of the application that is requesting the token (e.g. “Acme”). The login page should be a reflection of the directory where the user authenticates, that’s why you see Google branding regardless of the application that is requesting the token. It also helps the user know that the Google Account is being used to authenticate.
So, in your case, it might help thinking who really authorizes applications to access the API, and that would be the tenant where the API is defined. That authorization server might have multiple options to authenticate the users (those would be the connections). You could have social connections and a database connection for email/pwd authentication.

Will you have just these two subdomains? Do you want to keep identities completely isolated? If so, the solution might be using two different database connections, one per subdomain. The hosted login page could pick the connection name and change the style accordingly (as in “Authenticate as a partner” or “Authenticate as a user”).
Sorry if the answer is light on details, but it’s difficult to go deeper without the whole picture.

4 Likes

This is really helpful - can you provide anymore details on how to accomplish this:

Basically you’ll have to code some logic to determine which DB connection you are going to be using. Could be based on the clientID requesting the application:

var clientConnections = {
  "the-client-id-for-the-customers-domain": "customers-db",
  "the-client-id-for-the-partners-domain": "partners-db"
};
// config.clientID comes from the HLP template, is part of the context provided by the server.
var connectionName = clientConnections[config.clientID];

Then, you can use the connectionName to switch the style, like assigning a different CSS class to an element, changing titles, etc. E.g:

  switch(connectionName) {
    case "partners-db":
      // assign custom styling
      [...]
      break;
    case "customers-db":
      // assign custom styling
      [...]
      break;
  }

But, I want to emphasize, this would be an advanced scenario. In the majority of cases, one DB connection per tenant is sufficient (a global user directory), and the authorization logic handled elsewhere.

4 Likes

Thanks @nicolas_sabena - you were right that the multi connection part was overkill. I can just send some data along in config.clientID, set the role in a rule, and redirect back to the originating page. Thanks again

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.