Lars Kemmann
Lars Kemmann

Reputation: 5674

How to authenticate and store tokens in a multitenant web client (multiple B2C identities in the same browser)

I'm designing a single-page app (SPA) and API that will support multiple tenants, including in the same client browser. Imagine an experience similar to the Azure Portal, where users can switch between identities that they have signed into Azure AD with, except that in this case I'm using Azure AD B2C. All sign-ins happen via a single Azure AD B2C instance. Importantly, the tenants do not necessarily have to be aware of each other since they are white-labeled -- the user might be redirected to https://multitenant.app/tenantA and sign in via B2C, and have a totally different experience when directed to https://multitenant.app/tenantB and signing in via B2C there. The two tenants do not need to share data between themselves on the client.

How might I go about: 1) designing the client so that requests to https://multitenant.app/tenantX are directed to Azure AD B2C in a way that enables sign-in using the rules for tenantX, and 2) designing the client so that the MSAL.js library correctly provides a token store containing tokens specific to tenantX when the user has navigated to https://multitenant.app/tenantX in the browser?

Currently I'm expecting to need to intercept requests to the backend API on the client, determine if a redirect to B2C is necessary first in order to sign in to the tenant that the request is for, and attach the appropriate access token for that tenant to the API request. (All this is assuming that I use the Implicit Flow so that I have the access & refresh tokens available on the client.)

Does this make sense? Is there a better way? I've debated using session cookies issued by the server so that the browser handles the "intercept-requests-and-attach-credentials" aspect of this, so maybe that's an option that would avoid the need to maintain all these tokens on the client?

And how does this work when the client signs into B2C? Can I tweak/disable the B2C SSO capabilities sufficiently so that a single user agent (browser) can still obtain multiple different tokens (for different identities)?

Upvotes: 0

Views: 563

Answers (1)

Jas Suri - MSFT
Jas Suri - MSFT

Reputation: 11335

The approach needs to be a bit different. This is how Microsoft do it with their "tenant picker" in the Azure Portal.

  1. We hold a mapping of in which tenants your account lives in
  2. We then list the tenants in a tenant picker UI in the app
  3. When you switch tenants, we do an SSO authentication to the new resource (ie the selected tenant) to get a token to it
  4. We use the new token to evaluate your rights in this tenants subscription

To translate this in AAD B2C you can:

  1. Hold a mapping of identifier to 'tenant'
  2. On authentication, call your API to get a list of tenants. Use this sample to list the tenants in the authentication flow
  3. The user selects the tenant, or maybe you do it like Microsoft and have a default preference, in which case the step above is skipped using a B2C precondition. This way the user only goes through selecting a tenant in the auth flow once. Afterwards they use an in-app tenant picker (read on...)
  4. The token issued to the user has the tenant inside it as a claim, this will then be used to do authorization when this token arrives are your API.
  5. In the SPA, now render a tenant picker, use the same API as used in step 2 essentially
  6. The user can select a new tenant in the SPA, use id_token_hint (example) to seed a new B2C user journey with the selected tenant. The user will get SSO through this journey and get a new token with the new tenant inside it as a claim.

Upvotes: 1

Related Questions