In this short series of articles, I will refer to a number of fictitious organisations; CloudStruck (www.cloudstruck.com) , Little Pay (www.littlepay.co.uk) and HasToBe.Net (www.hastobe.net).
HasToBe.Net is actually my personal blog site that I update only sporadically. CloudStruck and Little Pay are simply domains that I registered for personal use, including creating demonstration material. Their use may change over time, or they may disappear altogether.
There are a number of key characteristics that I’m looking to satisfy when designing a multi-tenant application:
- Users of the application should not know that it is supporting multiple tenants
- Customers should be able to brand and customise the application to their own requirements
- The application should strive to maximise resource utilisation by sharing wherever possible…
- Yet allow data to be isolated wherever necessary
- The on-boarding process for new customers should be automated as much as possible
- On-boarding a new customer must not result in downtime for existing customers
In my previous posts (the first and the second), I discussed some approaches to the hosting of data in SQL Azure; shared where possible, isolated where necessary. This time, I’m going to explore a design issue that is important to providing all of these key characteristics: when a user accesses my multi-tenant application, how do I identify the right tenant? Until I identify the tenant, I can’t apply any of the customer-specific customisations or branding and can’t determine what data is the right data for that user.
Here are a number of approaches you may consider along with some pros and cons of each.
Identify the Tenant from the User’s Profile
OK, let’s get this one out of the way quickly, because I hate it.
If each user is associated with a single tenant, you can create them a profile within the application and hold a tenant identifier within profile. When they reach your application, you can force them to login with their credentials. Once they’ve logged in, you have identified the tenant from their account information.
Did I mention that I hate this approach?
The problems are obvious and fundamental.
The first is that the application, up until the user has logged in, must be generic and unbranded. It fails to satisfy a number of my essential characteristics comprehensively:
- It’s blindingly obvious that the user is access a multi-tenant application
- Until the user is logged in, the application can’t apply any branding or customisation
I can think of a few more issues, though:
- It won’t work for anonymous users; they have no user account and consequently, no relationship with a tenant
- A user can’t have a relationship with more than one tenant unless they have different credentials
- It’s difficult to have more than one identity provider. You may want to allow tenants to specify their own identity provider (such as Windows Live ID or their own Active Directory). But in this scenario, you need to know the identity provider before you find out who the tenant is.
So, this model is all wrong (in my opinion). We want to know who the tenant is before we present the application to the user.
Identify the Tenant with an Identifier in the URL
If we include the tenant identifier in the URL, we can solve a lot of those issues easily enough:
OK, so this has a number of distinct advantages. The application now knows who the tenant is, so we can customise the application straight away. We can also choose an appropriate identity provider so that we know where to authenticate the user when they login. It will also work with anonymous users. Users can have accounts with more than one tenant, because their access is scoped by tenant.
This is all a distinct improvement. But there remain a couple of issues.
- It’s still blindingly obvious that this is a multi-tenant application, because the URL specifies a host that means nothing to the user: www.littlepay.co.uk
- Users aren’t going to find the application using the common technique of ‘URL surfing’, where you type into the address bar of your browser an educated guess. For example, if I’m ‘URL surfing’ for Cloudstruck.com’s payroll system, I may guess at (or even vaguely remember) http://www.cloudstruck.com/payroll or http://payroll.cloudstruck.com/ I’m never going to guess that it’s at http://www.littlepay.co.uk?t=cloudstruck
The URL is an important part of a company’s brand; using someone else’s host name in a URL for a site that you’re trying to present as your own only weakens the brand.
The URL of the site is obviously an important factor, so let’s explore some further refinements.
Let's break there, because we're going to go deeper (and we get to look at some real code) when we consider how to identify our tenants using sub-domains.
Steve Morgan is Principal Customer Solution Architect / Windows Azure Centre of Excellence Lead Architect at Fujitsu UK&I.