Accessing AAD Graph Information from Azure Mobile Services

Azure Mobile Services recently announced a preview of Azure Active Directory (AAD) as an identity provider, opening up a lot of new opportunities for enterprise application building. Syncing with an on-premises Active Directory instance allows employees to sign in to your apps with their corporate credentials, but of course you can also use AAD’s built-in user management. If you are interested in trying out the preview, be sure to email the Mobile Services team.

Like the other identity providers we offer with Mobile Services, AAD offers a rich graph API which can be used to obtain information about a user. In this post, I’ll show you how to personalize a user’s app experience based on that information. On the server, we’ll write a custom API which will contact AAD and return basic graph data. The mobile client will call this API following each login and use the data to welcome the user to the app. This post assumes that you already know how to connect a Mobile Service to an AAD tenant for authentication.

The AAD Graph

The AAD team has some nice samples for the Graph API, but unfortunately none are for Node.js. There exist some third-party Node modules for AAD integration, but today we’ll be going straight to the AAD REST API. Our good friend the request module will help here. Go ahead and create the custom API now – I called mine “getIdentities” since we’re basically mimicking a server-side function that we’ll be using later. Set the permissions to “only authenticated users.”

The AAD graph operates a bit differently from that of other providers in that access tokens are scoped at the application level as opposed to a specific user. This means that I only need one token in order to access the information of every user in the directory. To get that token, we’ll need to collect some credentials from our directory application.

In the AAD tab of the Windows Azure Management Portal, select your directory. Copy your tenant domain name from the “Domains” tab and make a record of it. Under the “Application” tab, click on the application you set up for Mobile Services authentication, and select “Configure.” By default, tenant applications are SSO only, so we need to make sure that the application has permission to use the graph. Click “Manage Access” at the bottom of the screen, and follow the wizard to configure the app for read access at least.

Manage Access

Next, make note of the Client ID, and generate a new secret under “Keys.” Be sure that you save this value in a secure place; once you leave the page, there’s no way to get this value out of the portal again.

AAD Credentials

At this point you should have three values. Since we’ll be referencing them a lot, go ahead and store them in some variables at the top of the API script.

We can now write a function to obtain the access token for us. The following code hits the token endpoint for our domain with a POST containing the request and the credentials that we just obtained. The response has some metadata about the token, such as its expiration details, but for now we’ll just extract the token.

With the access token in hand, we can finally make calls to the AAD graph. For my app, all I care about is getting basic user info, but the API can do a lot more, such as looking up to whom a given user reports. In all cases, you just need to form the appropriate URL and shove the access token in the request header.

You might be wondering about that mysterious “objectId” field. This is how AAD identifies different kinds of objects (such as users) in the directory. Note that this is not the same as the user ID that is provided by the Mobile Services user object. We’ll get that by taking the user object passed to the custom API’s GET action and calling its getIdentities() function.

I return the whole set of user information that I get back, leaving the client to decide what it does and doesn’t need. Speaking of…

Application Personalization

Our API has everything it needs for getting information about the logged in user, so the next step is to access it from the client. Today I’m working with Windows Phone 8, but of course the same principles apply to the other clients. I’ll be modifying the authentication quickstart with AAD to show the user’s display name upon login.

This actually ends up being very straightforward. I first create a “UserDetails” class to help handle deserializing relevant data from the call. I then modify Authenticate() such that after a user logs in, I call InvokeApiAsync() with the parameter “getIdentities,” as this is what I named my API earlier. Once the task completes, I pull information out of the returned UserDetails and show it in a MessageBox.

Now let’s try it all out. I start the app, punch in my credentials, and…

AAD Graph

Closing Remarks

That’s it! Hopefully this helps make the AAD graph seem less daunting. There is a lot of power there, and you can quickly tune your mobile apps to leverage your organization’s structure, or to just make a nicer experience for your users.

You probably noticed that the API requests the access token every time it is called, and I mentioned at the start that the token is shared by all users. Best practice is certainly to cache the token in your database, making a new request only when the old token expires. For simplicity of the walkthrough I have omitted this step and leave it as an exercise for the reader.

The completed server code for the walkthrough can be found here. Once again, if you are interested in enrolling in the private preview for AAD integration, let us know at mobileservices@microsoft.com.

Resources

The AAD Graph REST API Reference – Reference material for the different operations you can perform on the AAD Graph
AAD Graph Samples – Samples for .NET, Java, and PHP
AAD Directory Sync – How to set up AAD for sync with on-premises Active Directory
Getting User Information on Azure Mobile Services – Carlos Figueira’s blog post on accessing graphs for other identity providers
Azure Mobile Services – Documentation for Azure Mobile Services
Changes to getIdentities() – We recently changed the getIdentities() function, and the details are discussed here