4

I have been trying to add support for multi tenants to my application.

I initialize like so

const app = firebase.initializeApp();
const tenantManager = app.auth().tenantManager();
const tenant = await tenantManager.createTenant({ displayName: `test- tenant` });
const auth = tenantManager.authForTenant(tenantId);

Part of my application then uses the auth.createCustomToken(uid) in order to create a token that can then be exchanged for a standard id token (Using the rest endpoint /accounts:signInWithCustomToken.

When trying to create the custom token I get the following error

Error: This operation is not supported in a multi-tenant context

Additionally to this when manually creating a token (using jsonwebtoken and the service account key) the error

Specified tenant ID does not match the custom token

Comes up when attempting to verify the token (through the REST API)

Has anyone else encountered this error, or is anyone aware of another way to generate and verify custom tokens in a multi tenant environment (or, alternatively, know of some way to log a user in given only a uid)?

major-mann
  • 2,602
  • 22
  • 37

3 Answers3

2

Instead of using the API to generate the custom token, generate a JWT using the private_key from the service account for signing and making sure you have the values defined below

const jwt = require(`jsonwebtoken`);
const payload = {
    uid,
    sub: serviceAccount.client_email,
    tenant_id: tenantId
};
jwt.sign(payload, serviceAccount.private_key, {
    audience: `https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit`,
    issuer: serviceAccount.client_email,
    algorithm: `RS256`,
    expiresIn: 0
});

Note: The tenant_id in the payload.

Now, when exchanging the custom token for a firebase issued token by POSTing to

`https://identitytoolkit.googleapis.com/v1/accounts:signInWithCustomToken?key=${encodeURIComponent(webApiKey)}`

Ensure that tenantId is as a property in the JSON body of the request and matches the tenant_id found in the token.

{
    tenantId, // Make sure this matches the "tenant_id" claim in the idToken
    token: idToken,
    returnSecureToken: true
}

The second part of this is documented at https://cloud.google.com/identity-platform/docs/reference/rest/client/#section-verify-custom-token (But not in the original firebase auth documentation at the time of this writing)

major-mann
  • 2,602
  • 22
  • 37
1

This question is old, and hence the previous answers are kinda obsolete. Now, you can create a token by setting the tenant-id in the Auth object, both on the Admin SDK and the Firebase Auth Client.

On Admin SDK:

  const auth = admin.auth().tenantManager().authForTenant(<tenant-id-value>);
  const firebaseToken = await auth.createCustomToken(uid);
  return firebaseToken; // send firebaseToken to client

On Firebase Auth Client:

const auth = firebase.auth();
auth.tenantId = <tenant-id-value>;
auth.signInWithCustomToken(firebaseToken);

As long as the Tenant-Id matches, you should not see any issues. You don't need to use any third-party library anymore unless your language is not supported.

Sundeep
  • 384
  • 2
  • 6
-1

Currently custom token authentication is not supported in a multi-tenancy context. This feature is still under construction. You can check the full list of supported capabilities here.

bojeil
  • 29,642
  • 4
  • 69
  • 76