How to use Stormpath for subdomain multi-tenancy using Spring Boot

With a single application and some configuration in Stormpath’s Admin Console, your application will be able to support multiple Organizations of users. This is great for SaaS applications who need to securely partition their Customer organizations; each Organization will have no knowledge of or access to the others.

What Is Multi-Tenancy?

Imagine a self-storage company. There’s a large building. Inside the building, there are multiple storage units, each with a lock on the door that only the renter of that unit has access to.

One of the reasons self-storage works so well is that it is easy to repeat. Each storage unit is basically the same as the others. Adding a new tenant does not require a whole new large building. It simply requires that a storage unit be allocated to that tenant. It also ensures that each tenant has a protected storage unit, unique to them and that only they can access.

It’s the same idea for a multi-tenant application. You have one application that can support distinct collections of users. Setting up a new tenant is reduced to a little configuration in an admin console. There’s no need to deploy your application to a new server.

A Multi-Tenant Sample for Spring Boot

Building all this multi-tenant infrastructure yourself from scratch is a royal pain, but multi-tenancy is native to and easily configurable in the Stormpath user model. In this post, we’ll show you how to use it in a Spring Boot app.

We’re going to follow along with a made-up company in this post to demonstrate multi-tenancy. It’s called the Imperial Xchange – your one-stop shop for all your evil apparel needs! In this scenario, we want to keep the Sith Lords separate from the Stormtroopers.

The goal is to deploy the Application once, to allow both Sith Lords and Stormtroopers to login to their respective tenants while also ensuring that they can’t login to each other’s tenants. Finally, we will add another Organization into the mix without any code changes or even the need to restart the application.

 

Getting Ready for A Multi-Tenant User Store

The first step to multi-tenant bliss is to get Stormpath setup. While there are few steps along the way, you’ll see that it’s pretty easy.

There are a number of ways to accomplish authentication in a multi-tenant enabled Application:

  1. Add a field to the login form for users to type in their Tenant name
  2. Select Tenant after login
  3. Automatically set Tenant by subdomain

The most advanced version of this – and the easiest on users – is the subdomain approach. That is the approach we will be configuring in the examples that follow.

For more information on the various approaches, check out our Multi-Tenancy Guide

Create a Stormpath Account

Point your browser over to https://api.stormpath.com and signup for a Stormpath account. Fill out the form, verify your account, create an API key pair and you’re good to go.

For more detailed information on setting up your free Stormpath account, refer to the Product Guide.

Setup the Organizations

Organizations are the key to our subdomain-based configuration. A Stormpath Organization is a type of Account Store. That is, a container for Accounts. The important part here is that you specify an Organization Name Key that matches your subdomain.

In this case, we will use sith and stormtrooper Organization names to match the subdomains we setup below.

Follow these steps:

Setup the Organizations

  1. Browse to your Stormpath Admin Console
  2. Click the Organizations tab at the top of the page
  3. Click the Create Organization button

create_org

  1. Enter Sith for the Name and sith for Name Key and click the Create Organization button
  2. Repeat steps 2 – 4 using Stormtrooper for the Name stormtrooper for the Name Key

orgs

Setup the Directories

Stormpath Directories contain the Accounts that we will use for a particular Tenant.

  1. Click the Directories tab at the top of the page
  2. Click the Create Directory button

create_directory

  1. Enter Sith Directory for the Name and click the Create Directory button
  2. Repeat steps 2 – 3 using Stormtrooper Directory for the Name

Setup the Accounts

We’re going to create two Accounts – one in each Directory.

First, a Sith Account:

  1. Click Accounts tab at the top of the page
  2. Click the Create Account button

create_account

  1. Choose the Sith Directory option for Account Location
  2. Enter dvader for Username
  3. Enter Darth for First Name
  4. Enter Vader for Last Name
  5. Enter dvader@empire.biz for Email
  6. Enter a password of your choosing for Password and re-enter it for Confirm Password
  7. Click the Create button

Next, a Stormtrooper Account:

  1. Click Accounts tab at the top of the page
  2. Click the Create Account button

create_account

  1. Choose the Stormtrooper Directory option for Account Location
  2. Enter tk421 for Username
  3. Enter TK for First Name
  4. Enter 421 for Last Name
  5. Enter tk421@empire.biz for Email
  6. Enter a password of your choosing for Password and re-enter it for Confirm Password
  7. Click the Create button

Setup the Application

The Stormpath Application is where we point the Spring Boot application to for authentication and authorization.

Follow these steps to create an Application:

  1. Click the Applications tab at the top of the page
  2. Click the Create Application button
  3. Enter Imperial Xchange for the Name
  4. Uncheck the Create new Directory checkbox (we will associate the Organizations we created with the Application below)
  5. Click the Create button

create_application

Tying it all Together

The last steps in this section are to add the Directories we’ve created as Account Store Mappingsin the Organizations and to associate the Organizations with the Application

Account Store Mappings:

  1. Click the Organizations tab again
  2. Click the Sith link
  3. Click the Account Stores link
  4. Click the Add Account Stores link
  5. On the Directories tab, click the checkbox next to Sith Directory
  6. Click the Create Mappings button

sith_mapping

  1. Click the Organizations tab again
  2. Click the Stormtrooper link
  3. Click the Account Stores link
  4. Click the Add Account Stores link
  5. On the Directories tab, click the checkbox next to Stormtrooper Directory
  6. Click the Create Mappings button

stormtrooper_mapping

Application Account Stores:

  1. Click the Applications tab again
  2. Click the Imperial Xchange link
  3. Click the Account Stores link

application_account_stores_before

  1. Click the Add Account Store button
  2. Choose the Organizations tab and select the Sith and Stormtrooper checkboxes

org_mappings

  1. Click the Create Mappings button

application_account_stores

Phew! Your Application is now completely setup for multi-tenancy. Hooray!

Configure ID Site

ID Site is Stormpath’s hosted and pre-built user interface screens that take care of the most common authentication workflows, including the login and register functions (among others) of your Application.

We’re using it here as it automatically supports the subdomain approach to multi-tenancy.

For more information on ID Site, check out the product guide here.

When you authenticate to an Application backed by ID Site, you will be automatically redirected to the hosted login page and then redirected back to your Application. For security purposes, you must specify the allowed origin and redirect urls.

For the purposes of our example app, we are going to use a locally defined domain: ix.localhost.

Specifically, we’ll be using sith.ix.localhost and stormtrooper.ix.localhost.

ID Site supports the notion of wildcard domains. This means that you don’t have to specify every subdomain you want to support for a given domain. You use the wildcard character * as you’ll see below.

Follow these steps for configuring ID Site:

  1. Click the ID Site tab at the top of the page
  2. Scroll down to the Authorized Javascript Origin URLs section and enterhttp://*.ix.localhost:8080
  3. Click into the Authorized Redirect URLs section and enter http://*.ix.localhost:8080/
    and http://*.ix.localhost:8080/idSiteResult

create_application

  1. Scroll to the bottom of the page and click the Save button.

/idSiteResult is the default callback URI used in Spring Boot applications.

Configure Your Local Environment

Rounding out our configuration journey is setting up your local environment to support the local domains we are using for this example.

On Macs and Linux machines, you edit the /etc/hosts file. On Windows machines, you edit the%SystemRoot%\System32\drivers\etc\hosts file. Update the following line:

 

 

When we run the Spring Boot application below on the standard port, 8080, this configuration allows you to browse to http://sith.ix.localhost:8080 and http://stormtrooper.ix.localhost:8080

Spring Boot Application

The code for the example application can be found here.

This application simply demonstrates the subdomain based multi-tenant capability that we configured in the previous section.

So, how do we go about enabling ID Site for our application? What about displaying the Organization field on the login form? This is done as a configuration in the application.properties file:

 

 

That’s it!

The application consists of two controllers and a couple of templates. The HomeController shows thehome template. The homepage / is completely unprotected. The RestrictedController shows therestricted template. You must be logged in to go to /restricted.

You can fire up the app as follows:

 

 

Let’s see the multi-tenancy partitioning in action:

  1. Browse to: http://sith.ix.localhost:8080/

sith_localhost

  1. Click the green button
  2. Enter in the Darth Vader account information we created earlier

sith_localhost_login

Notice that the tenant, extracted from the subdomain, is shown in the read-only Organization field on the page. This is a result of the application.properties configuration we did above. We could choose to not show the Organization field at all since it is taken from the subdomain automatically.

  1. Click the Login button and you will be redirected back to the /restricted page

sith_localhost_login

So, what? What’s the big deal? Here it is: Logout and then try to login again using the Stormtrooper account we setup earlier:

stormtrooper_bad_login

Stormtroopers are not allowed to log into the sith Tenant.

Now, try to login with the Stormtrooper Account using the correct URL:http://stormtrooper.ix.localhost:8080/

stormtrooper_localhost_login

stormtrooper_localhost_auth

There it is! Remember, we have a single instance of our Spring Boot application running. We’ve achieved the goal of partitioning the Sith Lord’s from the Stormtroopers. This was accomplished mainly through the Organizations and the ID Site configurations in the Admin Console.

Wanna add another tenant to your Application? All you need to do is create another Organization with mapped Directory and then add that Organization to the Account Store Mappings of your Application. You can then immediately browse to the new subdomain – no need to even restart the application!

If you added an Organization with name key officer, you could immediately browse to:http://officer.ix.localhost:8080 (you’d still need to add officer.ix.localhost to your/etc/hosts file).

 

Have more questions? Submit a request

Comments

0 comments

Please sign in to leave a comment.