-
Notifications
You must be signed in to change notification settings - Fork 4k
Multi tenancy support #442
Comments
So what we're planning is:
We don't have any docs on this, but if you want to give it a try and let us know if you're able to do what you want to, we'd appreciate it. Then if you run into any roadblocks, you can let us know so we can make changes. |
I've created a small example application on how we have tackled multitenancy https://github.com/khelben/IdsvrMultiTenantExample Herein the IdSvr is hosted in a tenant specific route For extra safety, we've scoped the IdSvr cookie name with the tenant also. I'm interested in knowing what you think about this. Christiaan |
Hey Brock, The solution seems to work for a "multiple account" scenario where by you have multiple accounts and want to switch between them. (ie like gmail / gapps does if you have a "work" and a "personal" account.) However what we are looking for is the ability to have multiple logins simultaneously where both accounts are active in different browser windows. The websites that the auth service is providing access to all run in client specific domains (eg clientname.OurAppDomain.com) which allows our support staff and our users who have logins to multiple "tenants" to access these simultaneously (as the session cookie is in separate domains once logged in). However, when switching out app specific logins with a central auth service for our newer development which is API backed, we didn't want to have to introduce another full set of tenant domains. So we want the auth service (in a single domain -eg login.OurAppDomain.com) to auth for all tenants. Basically what we hoped to do was attach acr_values containing the client ID we are requesting access for to each identity server call, then validate that the user has already logged in to that specific tenant on identity server. In the case they are logged into two tenants with two separate user accounts, the acr_value would help us determine the tenant specfic cookie to look for. On the surface is seems like @khelben's solution may work. Just trying to ascertain if it has any other drawbacks. Brad |
Hey @TooMuchTaurine, actually we have the same idea if I understand your point correctly. From what I understand is that you want to be able to allow to login a user with the same credentials in the different client applications which are tenant specific. Correct? We've solved this by implementing 2 different auth servers based on IdSvr4. The first is the multi tenant aware version (as shown in the example) hosted on The other one is a central one hosted on The general idea is the following: the first one acts as a gateway in which the second one is configured as an external provider. This also allows us to configure other external providers per tenant. I'd love to know your ideas/remarks on this architecture. I'll be planning another sample where this architecture is used. Christiaan |
I have created an issue in your repo to ask a couple of questions I have on your implementation. I am trying to solve a similar problem at the moment but have a different design in mind. I will add another comment here with what I am thinking. |
@brockallen @TooMuchTaurine @khelben We have similar requirements around multi-tenancy. We have several multi-tenanted applications that need to single sign on into each other. We also need an ability to do external SSO but I will come to that later. For the internal SSO, one of the situations could be as below There are two products - I am thinking I can make use of domains to make multi-tenancy and SSO work. For identity server, I will have a single deployment of it with two hostnames configured as With this setup, any cookies issued by any of the applications will be tied to TLD which is Is there any reason why this will not work? The external SSO is a bit more complicated. |
@TooMuchTaurine @khelben I have setup a very basic multi-tenant version of Identity Server according to the design I described in my previous comment. You can check the code out if you want. This is not a production quality code and the does not do a lot of things aka a lot of hard-codings. I just wanted to make sure that the idea works. I coming days I will add the description of some more implementation. Let me know what you think. |
+1 |
This is risky business as folks will want to use the same username and password across multiple apps, and you'll run into issues in a great many places. If you really need to be multi-tenant, I would recommend one of the following:
I know 2 seems like a drag, but the only truly safe way to do multitenancy is to not share the data store depending on a tenant id; too much potential for cross-client leakage. These are just my 2c based on experience. Multitenancy is normally more trouble than it's worth, long term, especially in this day and age where deployments to IaaS are so lightweight and easier to manage. |
IMO the world of multi-tenancy is not very simple. There are tens of ways where each implementation differs from the other. If you operate in B2B space then this becomes even more challenging because you have got a range of people to satisfy. You are generalising by saying "folks will want to use the same username and password". There are several other factors other than the design of your identity server that makes consumers use same or different usernames across websites. Having said the above, I completely agree with your option 2 if you are capable of doing that with least overhead. This usually means you have automated most tasks around deployment and maintenance. If you still live the old world of manual or semi-automated deployments then that option comes with lot of overheads. |
I am generalizing; yes, but no matter how you slice it, multitenancy is an incredibly difficult problem to solve correctly and to scale correctly; especially if it wasn't a requirement up front and is an afterthought. It's certainly possible; anything is possible; I was just offering my 2cents. :) |
For everyone involved -- How do you identity the tenant? DNS/host? QS param? Or acr_values tenant param? Also, does tenant mean to you customer isolated version of IdentityServer, or does tenant mean a way to distinguish different groups of users for authentication? |
Related: #19 |
In my case the tenant is identified by acr_values param. |
@brockallen
|
@brockallen For us, it is DNS/host name most of the times. But we have couple of complex examples involving a sub-tenant which we may send in acr values / route paramter /query string |
DNS/Host, Different Groups of Users |
@brockallen we have gone ahead with DNS / hostname to separate out sessions for each tenant. This allows for users who have access to more than one tenant to avoid issues with sessions interfering with each other (The user / identities for each tenant are stored separately, so logically they are not the same identity in our identity server, even though they maybe be the same physical person with two accounts) A complication we have found implementing this is when we need to use identity server for Mobile apps. As mobile apps are global and somewhat independent of tenant, we use a generic url configured in the app settings for mobile apps to authenticate against on initial login. The workflow is such that we redirect the user to the correct tenant host in identity server once we have established which tenant the user belongs to (established by email address on the login page). However after rolling this out in beta, we realized that the token endpoints urls as part of the Auth Code flow would need to change to the tenant specific urls after the redirect occurs. At the moment we have done this by returning an additional parameter on the ReturnURL in the auth code flow along with the code, and then use this in a wrapper around OAuthAuthenticator2 Xamarin.Auth middleware. This is use to update the token endpoint before completing the auth code flow by requesting the access token / refresh token. We had to jump through a number of hoops to find a way to pass this information back to the mobile app and we are a little worried that the IDSVR4 implementation may change and break this "shoe horn" into the redirectUrl. Do you have any thoughts on this? |
Yep, this in effect means you're running different IdentityServers (from the browser perspective).
Ahh, you had to go and complicate things! :)
I don't know for certain, to be honest. I considered allowing custom response params in the authorize response... if this were formalized would it help? I don't know how you're doing it now. |
yes I think some formal way to pass information back to the client in addition to auth code would be good. At the moment we are implementing a custom AuthorizeResponseGenerator.
Then in the implementation... public async Task CreateCodeFlowResponseAsync(ValidatedAuthorizeRequest request)
|
Hello, For some time i've been busy building an identity-server, some complicated structures came up as i'm trying to implemented multi-tenancy. I would like to know if there are any security-risks regarding the approach im planning to take. Maybe others are struggling as well and could use an example-structure. The following case is present:
The structure i had in mind: The user provides an email (Student@company3.com) and a verification is sent to the user. The identityserver-database holds data regarding a one-to-many relationship between a user and the registered client, and a one-to-many between these registrations and the verified email-addresses. When logging into the identityserver, the token would hold the data for the tenants and the verified accounts. This token is returned and the current client verifies the token using the key from the discovery-endpoint. An example of the custom claims would be: Company3 would have secure confirmation that the current user has access to 2 accounts. Company1 would have the same information out the token which makes SSO between the different tenants possible. As i see it, there wouldnt be any security risks. But, im not very experienced with Identity-servers and authentication yet. I would love some feedback regarding possible security risks. Cheers |
This seems to be a general question about IdentityServer - not a bug report or an issue. Please use one of the our free or commercial support options See here for more details. Thanks! |
I really can't remember all the details (nor do I want to read that thread again). Please open a more specific issue if this is still a problem. |
@leastprivilege Thanks :) |
@brockallen sorry for commenting on an old ticket but I wanted to add our experience with this. Setting up a multi tenant system with subdomains is quite achievable when the client knows which discovery document to go to. For mobile apps, a global discovery document and jwks endpoint can be setup which redirects to a tenant login page, but like @TooMuchTaurine says, the token, user info and session endpoints are no longer correct. Information on the correct endpoints to use can be returned in the id_token but this is not ideal as it requires work from the client and it's not possible to change these URLs dynamically in some OpenID client libraries. It might be nice if there was a standard for clients to use URLs returned in requests. |
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Hi guys,
We are currently building out our own OAuth server using IdentityServer4 for SSO between our various apps. However our application is multi-tenant, with hundreds of clients.
I noticed this thread regarding identity server 3 around using separate cookies for each "tenant" which would allow us to big "logged in" to more than 1 client at a time.
IdentityServer/IdentityServer3#947
Has this progressed at all with Identity Server 4?
Currently it seems the only way to manage this would be to have a separate domain for each client on the identity server? With hundreds of client this would not be ideal, and a separate cookie would be much easier to manage. (eg idsrv_)
Do you have any opinions or other options for how this design should be handled?
Thanks,
Brad
The text was updated successfully, but these errors were encountered: