Multiple Tenant Guide
In the previous guide, we saw how to integrate SuperTokens with SAML Jackson for a single tenant.
#
1) Add multiple tenants to SAML JacksonWe must first add each tenant to SAML Jackson. This can be done via the addTenant.sh
script in the example repo:
addTenant.sh tenant1
addTenant.sh tenant2
important
Make sure to change the values of defaultRedirectUrl
, redirectUrl
, product
, name
and description
in the above script to match your app's details.
Each tenant will have its own unique client_id
and client_secret
which you must store in your database mapped to the tenant's ID (tenant1
or tenant2
) in the above example.
You can either add them yourself, or let end users add their own tenant. If you let end users add their own tenant, then you have to allow them to upload their SAML provider's XML file via a UI and then relay that to SAML Jackson.
#
2) Allow end-users to select their tentant during loginThere are two ways of doing this:
#
Asking users to type in their tenant ID during login.In our example app, you can see that we use the React component override feature to insert an input
box above the "login with SAML" button which allows users to type in their tenant ID during sign in / up.
note
The example app only accepts tenant IDs that you have pre configured with SAML Jackson.
#
Assigning a sub domain to each user and associating a sub domain to their tenant.In this approach, you can map a sub domain to a tenant ID in your database, and then use the API override feature to fetch the request's origin, extract the sub domain from it and query your database to get the associated tenant ID.
client_id
and client_secret
for the tenant ID#
3) Fetch the Once you have the tenantID on the backend API, you can query your database to fetch the associated client_id
and client_secret
. These values are the same as what were obtained from Step (1) on this page.
You should fetch these values in the API overrides associated with signing in / up the user.
client_id
and client_secret
to the custom auth provider logic via userContext
#
4) Pass the Using the user context feature, you can save the client_id
and client_secret
in the userContext
object in the sign in / up API before calling the original implementation. These values will then be available in the userContext
object passed to your custom OAuth provider implementation:
- NodeJS
- GoLang
- Python
import axios from "axios";
import SuperTokens from "supertokens-node";
import Session from "supertokens-node/recipe/session";
import ThirdPartyEmailPassword from "supertokens-node/recipe/thirdpartyemailpassword";
SuperTokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
supertokens: {
connectionURI: "...",
},
recipeList: [
ThirdPartyEmailPassword.init({
providers: [
{
id: "saml-jackson",
get: (redirectURI, authCodeFromRequest, userContext) => {
/*
userContext.client_id and userContext.client_secret needs to be
set in the API override for sign in up based on the user's input
*/
let client_id = userContext.client_id;
let client_secret = userContext.client_secret;
return {
accessTokenAPI: {
url: `http://localhost:5225/api/oauth/token`,
params: {
client_id,
client_secret,
grant_type: "authorization_code",
redirect_uri: redirectURI || "",
code: authCodeFromRequest || "",
}
},
authorisationRedirect: {
url: `http://localhost:5225/api/oauth/authorize`,
params: {
client_id
}
},
getClientId: () => {
return client_id;
},
getProfileInfo: async (accessTokenAPIResponse) => {
const profile = await axios({
method: 'get',
url: `http://localhost:5225/api/oauth/userinfo`,
headers: {
Authorization: `Bearer ${accessTokenAPIResponse.access_token}`,
},
});
return {
id: profile.data.id,
email: {
id: profile.data.email,
isVerified: true
}
};
}
}
}
}
]
}),
Session.init({})
]
});
note
Please see the NodeJS tab and make similar changes to the Go integration. You can see how to integrate a custom OAuth provider in the Go SDK using this guide, and how to pass around UserContext
using this guide.
note
Please see the NodeJS tab and make similar changes to the Python integration. You can see how to integrate a custom OAuth provider in the Python SDK using this guide, and how to pass around user_context
using this guide.