Dot Net Mafia

Group site for developer blogs dealing with (usually) Ionic, .NET, SharePoint, Office 365, Mobile Development, and other Microsoft products, as well as some discussion of general programming related concepts.

A SharePoint MVP bringing you the latest time saving tips for Ionic, SharePoint, and Office 365.

Six considerations for running a multi-tenant mobile app using Azure App Service

With the launch of HappenZap, I now have two multi-tenant mobile app platforms running on Azure App Service. When it comes to the backend services for mobile apps, Azure App Service really isn’t used that much though. In fact, in the 2017 Ionic Developer Survey, Azure only accounted for 10% of the users using it as a server side platform (behind Heroku, Digital Ocean, and Amazon ECS). For authentication, it ranked even lower at only 2.9% of the survey results. For Push Notifications, it wasn’t even on the list. However, for both my platforms, I have chosen to use it and have been doing so successfully.

Why did I go with Azure App Service? When I was getting started with mobile development, I found Azure as an option pretty quickly. Having a lot of experience around the Microsoft stack, I found that App Service was something I could get going with. Maybe this was partly due to my lack of experience with mobile, but I chose to go this route and I am pretty happy with a lot of it. Most mobile developers I have ran into don’t even consider Azure App Service as an option, but I think it’s worth a look.

Let’s look at some of the different aspects.

Database

Azure App Service offers Easy Tables and they are in fact easy. They are awesome for prototyping because you don’t even have to define a schema (although I always do in my apps). In fact, you can basically just insert anything and if the column doesn’t exist in your table, it will create it for you. it automatically creates an id column, a createdAt, modifiedAt, version number, and deleted fields for you as well. It supports a soft-delete capability that you can easily turn on as well. From a developer stand point, it’s easy to get started with a simple API around your database tables using node.js.

From a cost perspective, this is where you want to plan. Even the cheapest Azure SQL database costs you $5. For a service I am charging $40 a month for, having a separate database for each customer is not cost effective. As a result, I put all of my customers in the same database and every table is segmented by a tenant_id column. This works, but that means you have to write a level of security into your API. We’ll talk more about authorization in a bit, but this means you have to validate that the user making the API call has permission to make queries into that tenant.

Azure Web Apps / Mobile Apps

Whether you create a new “Mobile App” or “Web App”, it’s basically the same thing with a different icon in the Azure Portal. When thinking multi-tenant, your goal is to create one of these that can serve all of your clients. If each client has to have their own Web App, you will quickly exceed the memory capacity of your App Service plan. There are reasons why you might consider having more than one though as you will see when you read on.

Authentication

Authentication in mobile apps with Azure App Service is easy due to the large number of SDKs available including Cordova, Xamarin, and native iOS and Android. App Service supports authenticating against Azure Active Directory, Facebook, Google, Microsoft, and Twitter. If you want to authenticate against Microsoft consumer or AAD, App Service is a great option because Firebase doesn’t support it. You can authenticate against one or all of the providers too. Logging a user in as simple as calling azureMobileClient.login(‘providername’). On mobile apps, it will open the InAppBrowser and sign the user in. This works great for interactive logins but auto-login with the token is a bit of a different story. I’ll post in the near future about how to do that as it is not well documented.

The way authentication works is that your mobile client makes a call into the App Service back in which in effect proxies the request over to the appropriate provider. The nice thing about this is that, any subsequent API calls you make automatically pass the user’s token and the API can respond accordingly if the user is not authenticated or their token has expired. If you don’t need authentication on a particular type of API call, you can allow anonymous users to access it. For example, anonymous users might get read access, but authenticated users can insert / update / delete.

The issue you run into with authentication on app service is that all users have to request the same scope / permissions. For example, you may want end users to have just basic profile access to Facebook, but you want administrators to be able to manage pages. The permissions you request are set in the Azure Portal and are essentially fixed. That means all users have to request the same permissions. That’s no good. One way to work around this is to call the authentication provider directly. For example, I’ve done this with AAD to request a scope that included admin consent credentials such as Group.Read.All. Another way to work around this is to have multiple Azure Mobile Apps configured with different permissions. This really doesn’t scale all that well either, but could be an option for simple scenarios. It does create a bit of overhead though since you have to push code to each one and your client side code has to know which endpoint to call.

Authorization

Azure takes care of the Authentication for you, but authorization is still up to you. There are not a lot of complex examples out there for this, so I’ll probably write something up soon. Your API will receive the user’s context and therefore you can get there access token and username if needed. For authentication, I simply implement a users table which has the user’s unique id, role, and tenant id. I first make sure that the user is in that tenant id. Then I make sure the user has the right role for whatever operation I am performing. It’s fairly simple, but it works.

Save Cash with Caching

You pay for every bit of data egress from Azure whether that is your API or SQL. It can really add up too as your volume grows. Be sure and take advantage of caching wherever you can. Cache frequent database calls at the API layer. Cache data that doesn’t change frequently on the mobile app. Only get data when you need it.

Push Notifications

Azure Mobile Apps supports push notifications with Google, Apple, Amazon, and a few others. It’s pretty simple to set up and their are methods built into the node.js SDK that make it easy to set up. However, there are a few limitations. First, App Service doesn’t support the newer key based model used by APNS so that means you need a certificate (for both development and production) for every tenant. The next issue is that you can only install one key per instance of an Azure Mobile App. That means you would have to have a separate Azure Mobile App per tenant. That doesn’t scale well at all. I used this approach for a while but I switched over to Firebase Cloud Messaging and now I can use a single tenant.

Summary

Azure App Service is a cost effective way to run multi-tenant mobile applications. There are factors that you have to consider, but I do think its a viable choice for hosting your mobile app’s backend.