Multi-tenancy with shared authentication/authorization

Topics: Administration, Customizing Orchard, Writing modules
Jul 13, 2012 at 9:27 AM

We are currently building up our customer portal using Orchard 1.5 RC-1. Each customer is a tenant in an isolated database. All tenants are running on the same domain; we use the  RequestUrlPrefix to separate clients.

When a customer arrives as the main site, e.g. customers.contoso.com and logs in, he will be redirected to customers.contoso.com/client1. The customer should also be able to perform user account self-service, i.e. changing/resetting password.

This makes me believe that we need a common database for user authentication and authorization, since the customer needs to log in before beeing redirected to the correct tenant.

My idea was to implement the  IAuthenticationService, IMembershipService etc by wrapping the standard Orchard implementation and then inject the IContentManager for the default tenant into these classes. In that way, all tenants would use the same repository for authentication and we would avoid problems with duplicate user data.

However, I struggle to find a way of injecting the IContentManager corresponding to the default tenant into the wrapped classes. Are there any repository of instantiated ContentManagers or would I need to create one from scratch, using e.g. information from the IRunningShellTable? Or maybe the whole idea is bad?

Regards

 

 

 

Developer
Jul 13, 2012 at 10:45 AM

All injected services deal with the tenant they're requested at. I think you don't have control over tenants other then where you are currently. There is no built-in data sharing capability between tenants.

Why specifically you need a common database for users? I guess you need your users to be logged in on their respective tenants. For this you need user accounts local to each tenant. I don't think this is problematic if one user only corresponds to one tenant (as it is hinted by the fact that you want to redirect the users to their tenant).

Why do you need such a home page in the first place? Isn't it OK that clients directly open their respective tenant site?

Coordinator
Jul 13, 2012 at 11:02 AM

Having a custom implementation of the membership APIs is the way to go, but what puzzles me more is why you would need the default's ContentManager in there. If you implement your own membership and authentication, the data for it should be in a completely separate database, which shouldn't require CM.

Jul 13, 2012 at 11:14 AM

Thank you both. 

Well, the idea was to reuse the nifty Orchard role/user management modules. For instance, the Orchard.Users.Services.MembershipService does exactly what we want. However, the class uses the ContentManager via the IOrchardServices constructor argument. So either I would have to re-implement the functionality from scratch or inject the "correct" ContentManager I guess.

To be even more specific about the requirements: Our staff users should have access to all the tenants, i.e. if a staff member changes password from within one tenant, it should have global effect. 

 

Coordinator
Jul 13, 2012 at 11:49 AM

That's not how multi-tenancy is designed, so you'll have to build your own.

Coordinator
Jul 13, 2012 at 4:19 PM

I think pshustad solution is a valid approach. And there must be a way to resolve dependencies for a specific tenant.

I think it could be done by injecting a IComponentContext into the constructor, and search for a specific "shell" which is the boundary for component registration per tenant. But then you would have to first look for users in the current tenant, then fall back to the default one.

Jul 13, 2012 at 6:41 PM

Hi All, 

I have the same requirement in my project. It would be nice to have single database for membership, so an admin in a SAAS environment can manage the accounts efficiently. 

Regards,

Hayri