Wednesday, May 15, 2013

Azure Mobile Services HTML Client - This Changes Everything

I started building a web app for tracking my budget. It stores data in a SQL database, so I thought I'd try running it in Microsoft's Azure cloud system. Azure has a web hosting system that is very easy to use and a SQL database system (among many, many other things). The architecture looked like this:

Website and database
Website and database

My first build of the site didn't use authorization and the data in the database couldn't be associated with a particular user. Before .NET 4.0 the out-of-the-box web authentication system was web forms. This meant storing user IDs and passwords in a database and forcing users to create yet another set of credentials on your site.

However, the ASP.NET MVC 4 template leveraged the use of claims-based authentication in .NET 4 and gave you an easy way to let users log in with third party IDs. The included ones are Google, Facebook, Twitter and Microsoft IDs (aka Live IDs). This sounded good to me, so I started down the path of moving my app to the new MVC 4 template. I could log in with my Google ID and received a unique identifier with which to associate my data.  The architecture was now:

Website, database and authorization
Website, database and authorization systems

Shortly after that, I learned about Azure Mobile Services. This is a very handy system that can handle authentication with the same systems as the MVC 4 template, but for smart phones and Windows 8 Store apps. It also integrates with an Azure SQL database. My intention was to use it to create Windows 8 and Windows Phone 7 and 8 clients for my app.

I found out that, while it is technically possible to use an existing database with Azure Mobile Services, there are some hoops through which you must jump to make them talk. I wasn't too far along with my development so I thought it easier to allow the Mobile Service creation wizard to create the database. Soon, I had a little dummy Windows 8 app that could authenticate with my Google ID, and again was receiving a unique ID.

Only, it wasn't the same as the ID I received in the web app. This was a problem, because it meant I couldn't look up data for the same person using their Google ID in both apps. My architecture now looked like this:

Website, database, mobile services and 2 authorization systems
Website, database, mobile services and 2 authorization systems
The cause of the ID mismatch was that the MVC4 template uses Google's OpenID authentication system, while Mobile Services uses Google's OAuth2 system. I had no reliable way of associating one with the other. A little searching around found other people encountering the same problem, and eventually a NuGet package that lets you use Google's OAuth2 system in an MVC 4 web app.

The NuGet package would let me find people's data no matter which app they used. Hardly ideal, though, because it meant extra code just to do the same thing. I suspected there would be other differences between the MVC 4 template's authentication providers and Mobile Services' providers.

My ideal architecture is:

The idea is that the Mobile Service would handle all authorization, and then access a REST endpoint in the website, rather than going directly to the database. This means that the web app would somehow authenticate against and get data from the Mobile Service, just like the other apps.

Besides the centralization of the authorization mechanism, it would also put all the business logic on the server. The Windows 8 and phone apps would be strictly for displaying data. That way any bug fixes to business logic would be web-based, meaning immediate and global. If the logic lived in the Windows and phone apps then I'd have to update them individually, and wait for them to be approved and delivered to people.

It seemed like a pipe dream, because I couldn't find any easily understandable information about how to authenticate against a Mobile Service. Until a few days ago, when I found out that the Mobile Services group published an example HTML client, along with a JavaScript library that can authenticate and get data.

This changes everything.

This is the final piece of the puzzle that will let me create a web app that gets data through Azure Mobile Services.

Actually, there is one change to the architecture needed to keep the REST interface accessible to only the Mobile Service:

That extra User Auth box is an Azure Access Control Service service ID that the Mobile Service will use to access the web service's REST service.

1 comment: