Azure Mobile Services supports two.. no, three kinds of security.
First it support no security. Right 🙂
Second, it support basic authentication. This can be configured using the application key or the master key generated for the service. The application key is used typically for applications (hence the name) and the master key (aka the admin key) is more for a B2B solution. This master key is not to be communicated over the internet or stored in clients.
And the last kind of security is based on OAuth. This blog is dedicated to this kind of authentication. I will show you how to take advantage of the claims of each Oauth provider. But first: how does it work?
The foundation is that a secured AMS does provide access for users with an existing account from Google, Facebook, Microsoft, Twitter or Azure Active directory. But we do not want to be involved in the login process of these providers. We are only interested in the fact that the user consuming our services is known and authenticated.
So first we register our app for all providers we want to support in our app. In exchange, from each provider, we get some secret codes we do not share with anyone.
And we both exchange some endpoints between our service and the provider so they can check user specific knowledge if one passes by. AMS has already everything in place for easy configuration in the portal (more details can be found at http://azure.microsoft.com/en-us/documentation/articles/mobile-services-dotnet-backend-windows-universal-dotnet-get-started-users/).
There is one catch… If a user is authenticated, the only thing we know about this user is: nothing; well, almost nothing; only a unique number and some almost meaningless token. Should it be nice to know at least the name of the user and the email address? This a called: scope. And there are several kinds of scopes. Eg. if you want to know the friends of the user in Facebook, you have to request the scope for it.
So finally we declare the scope of data access we are interested in. We want the email address of the user logging in, so Facebook and MSFT ask use to declare the email scope. This is done in the configuration of the service in the portal.
Then a user comes by and accesses our service when using our app.
Because we do not want to know anything regarding to passwords, we redirect the user to the specific provider the user has chosen. In the client app, the provider redirects to a login screen (so the user can enter her/his name and password, to be confirmed by the provider) and the provider shows a consent screen so the uses is shown what scope our service is interested in. This is actually just the scope we provided. So in this example eg. Facebook will tell the user that he or she is about to disclose their email address. So as a service, do not ask too much of a user will deny you everything.
Finally the user logged in gets that (almost) useless token and this token (just a very long piece of gibberish) is passed to the service which will ask the provider for confirmation the token is correct (this user is logged in and has given his/her consent).
We only have this token, nothing more. Although the token contains some information (see https://sandervandevelde.wordpress.com/2015/02/10/getting-the-token-expiration-date-in-azure-mobile-services/) it does not contain the information we hoped for when we defined the scope. You will not find an email address in the token.
How do we get the information we asked for?
As seen in the image at the top of this blog, we can access the ‘graph’ for each provider. It’s just an extra endpoint of the provider service.
In the following paragraphs I will show you how to call the graph for several providers
Facebook graph access
When registering our app at Facebook, we get a secret combination of the keys. Put them in the Identity settings:
If we want to access Facebook to get the email address, we have to pass the extra scope request. So put a line in the app setttings:
Finally access the graph of Facebook using this WebApi call on the server.
The response gotten from the request at the graph endpoint is just json so we can transform it to the following class:
So here we have the name and the email address of the user from Facebook.
Just like Facebook, also a Microsoft account requires an extra scope for the email:
And the request to the graph is almost similar:
The difference is the number of different email addresses we get back from Microsoft:
You control their destiny, so choose wisely…
For getting graph data from Google we need nothing special. Just call the end point:
And the claims are almost the same too. Also notice the picture url:
Accessing Twitter is not easy. It is painful and difficult. It involves extra encodings and ugly coding. But I took the liberty to ask for some help. And the nugget package Linq To Twitter came to the rescue. First we added four secret values we got from Twitter to the App Settings in the portal. Then we consumed them during the call to the graph of twitter:
This is pretty code indeed. Good job Linq To Twitter! And because this library does all the json conversion, we do not need another class for mapping the answer.
Twitter does not pass the email address. We can get the unique twitter handle.
Azure Active Directory AAD
This is my favorite provider. Why? It’s because we can access every other AD in the world using AAD if there is a trust between them. For this example I just created a new user directly into AAD.
So first lets call the service. It is already explained in http://azure.microsoft.com/nl-nl/documentation/articles/mobile-services-dotnet-backend-windows-store-dotnet-aad-graph-info/ , but not after some extensive email conversation with Wesley McSwain from Microsoft.
Just like with Twitter, we need to have access to three secret values provided by AAD. We access them from the App settings:
This actually is a large amount of code. Luckily most of it is just the description of the large class the AAD json response has to be mapped to.
Please notice several things. First of all the address of the endpoint is having a version number in it (a date). It has changed in the past and it will most certainly change in the future. And the email address of the user was not passed in the ‘mail’ property. I got it in the UserPrincipalName. So check your own response!
It is not easy to access the graphs, but it can be done. Here I only took the time to get the email address of the user. Check the response of the different graphs if you access other scopes.
Do it end with these providers? No, take a look at http://azure.microsoft.com/blog/2014/07/28/azure-mobile-services-net-updates/ for an example on how to support LinkedIn.