Question

I am starting to build a SaaS line of business application in ASP.NET MVC2 but before I start I want to establish good architecture foundation.

I am going towards a shared database and shared schema approach because the data architecture and business logic will be quite simple and efficiency along with cost effectiveness are key issues.

To ensure good isolation of data between tenants I would like to implement the Tenant View Filter security pattern (take a look here). In order to do that my application has to impersonate different tenants (DB logins) based on the user that is logging in to the application. The login process needs to be as simple as possible (it's not going to be enterprise class software) - so a customer should only input their user name and password.

Users will access their data through their own sub-domain (using Subdomain routing) like http://tenant1.myapp.com or http://tenant2.myapp.com

What is the best way to meet this scenario?

Was it helpful?

Solution

I would also suggest using two database, a ConfigDB and a ContentDB.

The ConfigDB contains the tenant table and the hostname, databasename, sql username and sql password of the Content database for each of tenants in this table and is accessed via a seperate sql user called usrAdmin

The ContentDB contain all the application tables, segmented on the SID (or SUSER_ID) of the user and is access by each tenants sql user called usrTenantA, usrTenantB, usrTenantC etc.

To retrieve data, you connect to the ConfigDB as admin, retrieve the credentials for the appropriate client, connect to the server using the retrieved credentials and then query the database.

The reasons i did this is for horizontal scalability and the ability to isolate clients upon demand.

You can now have many ContentDBs, maybe with every ten tenants that sign up you create a new database, and configure your application to start provisioning clients in that database.

Alternatively you could provision a few sql servers, create a content DB on each and have your code provision tenants on which ever server has the lowest utilization historically.

You could also host all your regular clients on server A and B, but Server C could have tenants in their own INDIVIDUAL databases, all the multitenancy code is still there, but these clients can be told they are now more secure because of the higher isolation.

OTHER TIPS

The easiest way is to have a Tenants table which contains a URL field that you match up for all queries coming through.

If a tenant can have multiple URL's, then just have an additional table like TenantAlias which maintains the multiple urls for each tenant.

Cache this table web side as it will be hit a lot; invalidate the cache whenever a value changes.

You can look at DotNetNuke. It is an open source CMS that implements this exact model. I'm using the model in a couple of our apps at it works well.

BTW, for EVERY entity in your system you'll need to have a tenantid column acquired for the above table.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top