1

I have a question regarding Multi-tenancy (with MVC3, EF) and a custom SQL Membership provider.

I have custom User and Roles membership classes created, since I have to include the userId in my application tables along with additional user based attributes. I am now converting this into a multi-tenancy application. We are going for a shared-db, shared-app model. We have a master Tenant table that stores the tenant details (including URL ) and the Tenant_id has been included in every table. And now we're working on the changes to the application itself.

The assumption is that tenants will login using a URL like so: tenantUrl.mybaseURL.com.

I am going to change my custom User Validate methods as per this algorithm:

- User goes to URL to login
- The Account controller logon method calls the Custom validate method passing in user/pwd and the tenantId (which has been looked up from the db using the URL).
- The custom validate method checks if the user/password/tenantId combination are valid. 
- If valid, we set the tenant Id in a HttpRequest Object and login the user
- For each db access, we lookup the Request object for the tenandId and use that as a filter. 

Edit: This is my TenantContext class, where I will be setting/getting the tenantId

public class TenantContext
{
    public static int TenantId
    {
        set
        {

            if (!HttpContext.Current.Items.Contains("tenant-code"))
                HttpContext.Current.Items.Add("tenant-code", value);

            HttpContext.Current.Items["tenant-code"] = value;
        }

        get {return HttpContext.Current.Items.Contains("tenant-code") ? Convert.ToInt32(HttpContext.Current.Items["tenant-code"]) : -1; }

    }
}

The tenantId will be set in the Account Controller Login in the above Context.

Is the above a good way to do this or is there a better way? Anybody see any issues with this I should be aware of?

I have seen an example of the tenantId being stored in AppSettings here Handling data access in multi tenant site. Is this a better way to do it?

Thank You

Community
  • 1
  • 1
SimpleUser
  • 1,341
  • 2
  • 16
  • 36
  • Are you asking for how to fetch tenantId for the remainder of the Login action? Or are you asking how to fetch tenantId for the subsequent requests the logged in user makes. Am asking because for you to set the tenantId in the HttpContext.Items of each subsequent request, you have to fetch it from somewhere, right? – Amith George Nov 25 '12 at 07:35
  • Hi Amith, I was asking if the algorithm above was right, since this is my first multi-tenant app. I will be fetching the tenantId from the db based on the URl and storing in the Request object, if valid user. – SimpleUser Nov 25 '12 at 07:40
  • Any chance you could post the solution to what you did? – SpoiledTechie.com Feb 21 '16 at 04:34

1 Answers1

0

Your algorithm is perfect and in fact i have been working in this kind of an implementation. I have a suggestion that for you, that you use the custom object to maintain the useridentity across different layers. This will contain the userid, tenantid etc.. as this HttpContext will not be helping you in the case of a WCF service and in the context of a user belonging to a tenant and operating on behalf of another tenant. Hence, it would be a better option to have a UserIdentity object that identifies the user. Also, do send the tenantids to the data access layers and do not infer the tenant id's from the request as it will not be available in all environments.

Saravanan
  • 7,637
  • 5
  • 41
  • 72
  • Hi saravanan - have you ever done multi-tenancy with EF Navigation properties? I'm having a bit of trouble, if you have time to check this out I'd really appreciate it: http://stackoverflow.com/questions/19826316/virtual-navigation-properties-and-multi-tenancy – RobVious Nov 07 '13 at 17:37
  • Sorry for the delayed response. You can create an extension of IObjectSet and then do the tenant based filter and then return the IQueryable. In this case, you will be calling. Include("entity").FilterTenant() and this will be the right and easy way to use... – Saravanan Nov 16 '13 at 16:32