READ THIS FIRST
Update: 3-4-2016: If you're finding this blog and looking for information related to Azure Mobile Services, I'd strongly recommend checking out Azure Mobile Apps. Azure Mobile Apps is a new version (consider it a v2) of Azure's mobile backend support. All of the same features of Azure Mobile Services are there, with a lot of other very cool features to go along. You can read more about Azure Mobile Apps, and how to transition from Azure Mobile Services, here.
Update 4/22/2014: Version 1 JWTs have been deprecated. Make sure you check out this post to see how the script for JWT creation needs to be changed.
Update 5-9-2013: With Twitter retiring their version 1.0 API on June 11, 2013, I thought it would be a good idea to let people know how to update the script that pulls out the username to support v1.1. The script necessary for this is a good deal more complicated but I've walked through it in a new blog post you can find here.
One of the most powerful capabilities of Windows Azure Mobile Services is how easy it is to add user authentication to your mobile apps. Mobile Services does this by providing a super easy way to connect your app with Facebook, Google, Microsoft, and Twitter. For each provider, you go to their developer site and create an application which yields a key / id and a secret. You then take thoose pieces of information and put them in the portal for your Mobile Service and now your app can use that provider as a way of authenticating. Behind the scenes, things are a lot more complex because when you use these providers to authenticate, you’re using something called OAuth. Explaining how OAuth works is far beyond the scope of this article. Fortunately you don’t need to know how it works to take advantage of it in your mobile applications. I wanted to build an application that demonstrated how you could put authentication with all four of these providers into the same app but got a little ambitious and decided to do more. This article and the two that follow will cover how to set up your Mobile Service for auth with all four providers as well as how to generate custom accounts (users select their own usernames and passwords and can then login with them) and then how to connect to that Mobile Service from an iOS and an Android client. In addition, I’ll show you how to cache the user’s identity locally on the device and then how to deal with token expiration. These samples should show you how you can build the “front end” of your application leaving the actual functionality of “what happens after my user is logged in” up to you! In this article, we’ll go over how to set everything up on the server side. We’ll start by addressing how to hook into each of the providers mentioned above (Facebook, Google, Microsoft, and Twitter) and then we’ll talk about how you can use custom auth. Lastly, we’ll go over how you can poll each provider (or our custom one) for more information (like the user’s username).A bit of thanks
Before I get into things, I would be remiss to not thank Josh Twist. Josh is a Program Manager that works on Mobile Services and I made use of several of the blog posts he did as part of the 12 Days of Zumo series. While I will talk through all of the points I borrowed from Josh, I highly recommend paying attention to his site if you’re working with Mobile Services
Create a Mobile Service
The first step is to sign up for a Windows Azure account if you don’t already have one. You can sign up for a free 90 day trial here. Next, as opposed to walking through the steps to create a new Mobile Service yet again, you can reference the Setting up the app portion of this article. Now that that is done, we can start setting up our authentication providers.
Setting up Facebook auth
We’ll set up Facebook for our first auth provider. To do this, you’ll definitely need a Facebook account (the same is true of for each provider). First navigate to https://developers.facebook.com/. If you’re not currently logged in, you’ll see a Log In link at the top right. Click that and login with your Facebook account. Afterwards you should be at the developers home page again. Click on the Apps link at the top:
You’ll then be taken to your Apps dashboard. If you have already created apps, one may be selected, however today we’re going to click the + Create New App button in the top right:
On the next page, we can name our app. We’ll just name this AuthenticationDemo:
Click Continue to proceed. Facebook will then prompt you to fill in a captcha and you can then continue. In the next screen, we’ll see our App ID and App Secret at the top. We’re going to need this information, but not yet. First, return to your Mobile Service in the Windows Azure Portal and go to the DASHBOARD link at the top:
On the right side of the Dashboard, you’ll see MOBILE SERVICE URL about midway down. Remember where this is at as you’ll need it again for the other providers but for now, copy that URL:
Return to the Facebook developers site and click the checkmark next to Website with Facebook Login. Where it says Site URL paste in the URL of your Mobile Service and then click Save Changes at the bottom:
Now copy the App ID and App Secret values and return to the Mobile Services portal. This time click on the IDENTITY link at the top:
Find the area for facebook settings and paste in your ID and secret:
Now click the SAVE button at the bottom and confirm that you want to save the changes. On the server side we’ve done everything we need to do for Facebook. I’ll continue to walk you through the rest of the providers but I’m going to skip the sections that are going to be nearly the exact same. You can refer back to this Facebook section if you need screenshots for any of those things.
Setting up Google auth
To start with Google Auth, navigate to the Google API Console. If you haven’t been here before, the first thing you’ll need to do is accept some terms of service (this may also happen as you follow the steps below, just agree to everything). After you’ve gotten into the console, click the drop down in the top left under Google apis and select Create near the bottom under Other projects:
In the next window, give you project a name (i.e AuthDemo) and click Create Project. Once your project is created, you’ll be taken to a very long list of APIs that you can connect to if you want. Today we’re going to skip all of these. In the top left, click the API Access link:
In the next screen, all you’ll have access to do is click the Create an OAuth 2.0 client ID… button:
In the next screen, you’ll be required to enter a Product name before you can click Next. We can just name ours AuthDemo:
On the next page, you’ll need to enter the URL of your Mobile Service (which we got from the Dashboard earlier) into a text box near the bottom of the popup. Make sure you take off the https:// part of your URL and, before proceeding, add /login/google to the end of the URL. Once you leave the textbox (or hit tab) you should see the Redirect URI at the bottom become the URL for your Mobile Service with /login/google at the end (and the /login/google part will be taken off in the textbox):
While the picture shows /login/google still in the textbox, it will AUTOMATICALLY be taken off, this is what you want. Hi the Create client ID button when you’re done. In the next screen, you’ll have the Client ID and Client secret which you’ll need to copy over to the google settings area of the Mobile Services portal’s Identity area:
While I’ve only blurred the leading number here, make sure you copy the WHOLE string for Client ID over. If you just copy the number, it won’t work.
Adding Microsoft auth
Start by navigating to the My Applications page. Here you’ll need to login to your Microsoft account. At the top of the Applications page, there will be a link to Create application:
In the next page, give your application a name, choose a language, and click the I accept button:
In the next page, you’ll have access to the Client ID and Client secret but before you grab these, paste your Mobile Service URL into the Redirect domain and click the Save button at the bottom:
Make sure you leave the Mobile client app radio box at No. Copy and paste your ID and Secret over to the microsoft settings in the portal and save.
Adding Twitter auth
Twitter is the last of the provided identity providers we’re going to add. Start by going to the Twitter dev portal. If you aren’t already signed in, click the Sign in button at the top right and sign in. Once you are logged in, you’ll see your icon in the top right with an arrow pointing down. Click that and go to the My applications link:
Once there, click the Create a new application button in the top right (a little ways under your icon). You’ll then need to enter a Name and Description for your app. These can be whatever you want (as long as they meet the requirements described under the textboxes). Next, paste the Mobile Service URL into the Website and Callback URL textboxes. Scroll down to agree to their terms and conditions, enter their captcha, and finally click the Create your twitter application button. On the next page you’ll have access to your Consumer key and Consumer secret:
Before you put that into the Windows Azure portal, go to the Settings link at the top of the page under your app name. On this page, under the Application Type header there is a checkbox to Allow this application to be used to Sign in with Twitter. Check that and click the Update this Twitter application’s settings button at the bottom:
With that done, copy the key and secret over to the twitter settings area in the Identity section.
Creating our Mobile Service tables
We’re not going to store very much data with our application, however, we are going to use the script layer that is generated for tables to do a few different things. Return to the Windows Azure Portal and click on the DATA tab at the top. Currently your Mobile Service will have no tables. Click the + Create button at the bottom of the screen and create a table named Accounts with the default permissions. Do the same thing and create tables named AuthData and BadAuth. Now it’s time to set a few scripts for these tables.
Accounts
The first script we’ll look at is the most complicated as it handles creating custom auth accounts and facilitating logging in those users (you can read more about this from Josh who first blogged about it in December):
The first thing we have are several variables we’ll use throughout the script. Make sure you set the masterKey variable equal to your own Mobile Service’s master key (which you can access from the MANAGE KEYS button on the Dashboard). Once we’re in the insert method, we first check to see if login is a parameter that was sent over in the query string. If it was, we know that the user is trying to login with an already created custom auth account. If not, we go down to create an account. If we’re logging in, we first pull the data from the Accounts table where the username is equal to the username sent in. If that can’t be found, we respond with a 401. Provided we did find a user, we then hash the password using the salt that was originally used when the account was created. After that, we check that our has of the password sent into the service is the same as what’s in the database. If they are equal, we return the userId and a custom JWT token we generate using the zumoJwt method. You can read more about JSON Web Token (JWT) and generating them with Mobile Services on Josh’s blog. If the hashs didn’t match, we return a 401.
Now if the login parameter did not come across, we know we’re creating an account. First we’ll check to make sure the username and password match a few validation requirements (length and characters inside of them). This logic could be whatever you want it to be for your application. We then check to see if the username is already in use and return a 400 if it is. If it isn’t, we generate a new random salt to be saved with our account and then use that salt to has our password. We can then insert our record to the database. Finally, we remove the salt and password from the JSON item before it’s returned, add the userId and generate a JWT token. All of this is then returned to the application. Note that we could then require the user to login and NOT return a token here. In this, we’re just bypassing making them login after they create their account.
AuthData
We only have one script for the AuthData table and that is for the Read method:
This script handles trying to pull out the user’s username from whatever provider they logged in with. The majority of this script is owed to Carlos Figueira (another PM on Mobile Services) and his blog post on getting user information on Azure Mobile Services. This script first creates a result object that will be sent back to the calling application. We then check the provider the user is logged in with. This will be one of five things: facebook, google, microsoft, twitter, or custom. If it’s custom we know they created an account through our app and we can check the Accounts table for their username. Otherwise, we construct a URL specific to whichever provider they logged in with. Notice that Facebook, Google, and Microsoft all make use of whatever access token they handed back in the original authentication (which you can get from the user.getIdentities() object). Twitter, however, requires us to get the Twitter ID out of the user’s userId and put that in the URL. Once we have the URL, we use the request module to make a web request to the provider and try to parse the username out of the body. Finally we return our results to the calling application.
BadAuth
The BadAuth table exists so that we can test out using expired tokens from the client. We’re only going to implement the Insert script for this table:
This is extremely simple compared to the other scripts. We check for a parameter named bypass in the query string. If it’s there, we respond with a 200. If it isn’t, we respond with a 401. This way we can call the method without the parameter to signal an expired token and then call it again with the parameter to act like it’s not expired. This will be useful on the client when we want to test using cached user tokens and then handling expired tokens.
The Client
Now that we’ve covered everything on the server side, we’re ready to tackle the clients. I’ve split things up so there is one article that will cover everything for Android and one for iOS. It’s important to remember though that we’re using the same Mobile Service for BOTH clients. There is no need to create a different Mobile Service for each client. You can find the specific articles for each client here:
Conclusion
Today we looked at how you can easily set up a Mobile Service to handle several different methods of authenticating your users. In addition to the built in support for Facebook, Google, Microsoft, and Twitter account auth, we’ve seen that from the server side, it isn’t very complicated to add custom user auth so we can make users generate their own accounts. In the next series of articles we’ll talk about things from a client perspective including logging in with each of those providers, creating new accounts, caching user tokens so users don’t have to log in every time the app starts, and handling expired tokens as well.
26 Comments
Scott W
Excellent tutorial Chris! Thanks so much. I've been struggling with implementing a custom provider since January. A custom provider is the ONLY option for most companies and government agencies, so this is a much needed example.
I do have one question about your tutorial. When creating the tables, you say:
"Click the + Create button at the bottom of the screen and create a table named Accounts with the default permissions. Do the same thing and create tables named AuthData and BadAuth."
Doesn't that leave the Account table open to read for anybody with an application key? What are the most restrictive permissions we can put on the AuthData and Accounts table without breaking the provider?
Chris
Hi Scott. Great question (and sorry for the delay). For the Accounts table, you need to be able to call insert as anyone, so once you launch the permissions should be set to Everyone (App Key perms shouldn't be used once you're live). The insert script already prevents anyone from just inserting any data. The other operations should all be locked down to admins only. For AuthData, Read should be only Authenticated Users. The other operations should be admin only since you're not using them for anything.
Peter Ennis
I followed this and have authentication with Facebook working. Doing some translation of the app shows "Connecting to a service" message but I do not find this in the code anywhere to translate. The Facebook login correctly appears in the other language. How do I deal with this?
Chris
That's part of the auth flow on the server side. I don't think today you could change the language but I'll have to do some checking.
Kevin Hinton
I know this has been a while but is there anyway you could do a windows phone client example as well?
Chris
I don't do very much Windows Phone development but if I have a chance, I'll try to get this working.
George Lovitz
At the risk of sounding silly, I do not understand where the "scripts" come in. Are they implemented on the db side and if so, where do you enter them? Sorry if this is a silly question I just can't seem to find where these are input. Thx
Chris
Hi George, the scripts act as intercepts for any request against your Mobile Service tables. Check out these two tutorials (there are links to the other client OSs at the top) for more understanding: http://azure.microsoft.com/... and http://azure.microsoft.com/...
George Lovitz
Thx so much!
Ismar Duderija
What about .NET based Mobile Services - what can we do to implement similar custom auth there?
Chris
Take a look at this: http://azure.microsoft.com/...
Attiqe Ur Rehman
Great article and I got it working on my side. Usually we store user's information from Facebook, Twitter, Microsoft and Google, So we can use it later rather than sending the request again to get the same information again and again. What I would like to do is keep every user's information into one table like accounts. Accounts will have the information about every user coming from different providers(Facebook, Twitter and Custom etc). This would be ideal situation for me so if I want to get data later any time I would know to go to Accounts.
Please give me pointers on how to do the above scenario.
Thanks,
Attiqe
Chris
Are you looking to be able to connect accounts (i.e. tie a single user's facebook account to their twitter account) or just store all account data in a single table? If it's the latter, then you wouldn't have to do anything special, just store the data in the same table.
Techy Ashutosh
I am wondering about the same problem for long time but i will get what i want, but this code is working in .net domain?
Chris
I don't have any samples but you should be able to pretty easily follow the auth tutorials at http://azure.microsoft.com/.... Just select the .NET backend
Techy Ashutosh
Thanks a lot Chris for great help !!!
Ferslev Andersen
Hi Chris.
Great article. I am new to javascript and azure tables, and i can't quite figure out how you storing the costum account's parameters into a new table in the insert script. Im trying to insert a PartitionKey and a RowKey, and i can't figure out where to put em in the script, so the proper values will be assigned.
i hope you can give me some pointers
thx
Chris
If you're using Azure Table Storage, I'd recommend taking a look at this walkthrough: http://chrisrisner.com/Mobi...
emilio
hi, first thanks for your tutorial!! just one detail, you say " Click the + Create button at the bottom of the screen and create a table named Accounts with the default permissions. " but you miss the columns that the table must have "username, password, email" :)
Chris
Columns are added automatically using dynamic schematization when using the JavaScript backend.
Anie
I have an Android App which upload blobs to windows azure storage , so I need to create users account that acces to their specific stuff. Is there a way to create user account for windows azure storage!!!
Thanks in advance..
Chris
There is no built in authentication system for Azure Storage. What I would recommend you do is authenticate your users and then use something like Azure Mobile Services to function as a proxy layer. In that way, whenever you want to save data for a specific user, you can put their user ID in as one of the keys (so the container name for blob storage as an example). Then whenever you want to pull the data, you can use that same proxy layer to query the data for the specific user. Of course you don't want to actually pull down all the data from your Mobile Service / upload it to, so instead you should use your mobile service to create Secure Access Signature (SAS) Urls which you can then return to your client app. The client can then temporarily write to blob storage / pull data down. There are a few examples of how to do this on this site if you search for "Azure Storage Mobile Services"
James
Great Article
Werner van Deventer
The access token property is no longer available on the server. I can't seem to find anything regarding why this was removed. The code above will not work since the provider specific object has no accessToken property using the latest services. Anyone have an idea when and why this was removed?
There is also an enhanced users preview which is supposed to provide more user information in the call to getIdentities but enabling has no effect on the results.
https://goo.gl/BY7oco
daadada
https://goo.gl/5BdNYm
Practical discussion . Apropos if others are requiring a MI TR-13A , I came across a sample form here