This blog post is the second in a series that cover Azure Active Directory Single Sign On (SSO) Authentication in native mobile applications.

  1. Authenticating iOS app users with Azure Active Directory
  2. How to Best handle AAD access tokens in native mobile apps (this post)
  3. Using Azure SSO access token for multiple AAD resources from native mobile apps
  4. Sharing Azure SSO access token across multiple native mobile apps.

In my previous post, I talked about authenticating mobile app users using Azure AD SSO. In this post, I will explore how to take this further to persist the access token to interact with Azure AD.

Let’s assume that we have an API and a mobile app that consumes it. In order to secure the interaction between our mobile app and the API, we can register both the app and API with Azure AD and let Azure handle the authentication for us. Let’s take a look.

Securing the Web App

To start with, we will implement an authentication mechanism in our API. We can create use a vanilla Web API project from Visual Studio and implement Azure AD authentication on that. Our focus isn’t on this so for a good reference see Taiseer Joudeh’s detailed tutorial.

Securing the Mobile App

In the previous post, I showed how we could use Azure AD with ADAL to authenticate users on native mobile apps. The remainder of this post will assume that you have followed the previous post and you have this part ready. If you are not sure, please revisit my previous post.

Setting up the Permissions in AAD

We have seen how to secure our apps with AAD, now we need to authorise the mobile app to access our Web API. To do this we first need to expose the webApi permissions on Azure AD. We can navigate to AAD/Applications/our-web-app, then click on download manifest. This will give us a copy of the configuration of this API in AAD (in a simple JSON file). We need to modify the permission section and add the following section to tell Azure AD that this web app can be accessed by other AAD apps.

AAD app manifest configuration

AAD app manifest configuration

appPermissions": [
    {
      "claimValue": "user_impersonation",
      "description": "Allow the application full access to the service on behalf of the signed-in user",
      "directAccessGrantTypes": [],
      "displayName": "Have full access to the service",
      "impersonationAccessGrantTypes": [
        {
          "impersonated": "User",
          "impersonator": "Application"
        }
      ],
      "isDisabled": false,
      "origin": "Application",
      "permissionId": "place a NEW GUID here",
      "resourceScopeType": "Personal",
      "userConsentDescription": "Allow the application full access to the service on your behalf",
      "userConsentDisplayName": "Have full access to the service"
    }
  ]

We can update the file then upload it to update the permissions settings to enable AAD to allow access to this API just like any other permissions that it manages. You could read more on Azure AD impersonation and permission settings on MSDN. Note that you need to choose a NEW GUID for the permission id.

Now we need to configure our native mobile app in Azure AD to have access to our Web API. This is very simple and is shown in the screenshot below. In the list of permissions on the left, we now have more permissions that we can grant to the mobile app. Whatever name you gave to your mobile app will appear there along with the type of permissions that you have configured. In my case, I have named it MobileServices1 and that is what is appearing there.

Azure AD app permission settings

Azure AD app permission settings

Token Expiry and Caching

Setting the permissions and configuration above will allow our mobile app to authenticate users and manage the access of the API. This access is managed by the token that Azure AD issues when a user authenticates successfully. If the mobile app interacts with the API frequently, then we need to always have a valid token for all our requests. The question is how to keep a valid request token in the native mobile app?

The answer is depends on what you are trying to do – if you are implementing a highly secure mobile app you might want to always check with Azure and maybe ask the user to login every time the token expires. AAD access tokens expire after one hour by default. This means the default behaviour would be to ask the user to login every hour which is OK for some mobile apps, but it is certainly not the normal flow you see in many apps. So what should we do if we wanted to only ask the user to login once, or only occasionally (say, once every 3 months)? To do that, we would then need to manage the access tokens and automatically refresh it.

ADAL comes with the TokenCache class that is designed to manage caching of tokens so that consumers don’t need to go back to Azure AD every time the mobile app asks for a new token. Unfortunately for us persistent caching of tokens is not supported in the release this post is based on (ADAL 3.0.11). This means that ADAL will only cache the token in memory which means that once an app restarts (or is backgrounded in iOS) you will lose your access token. Therefore, we need to manage the token, and refresh it on our own in the background.

There are many ways that you could do this, a simple way is to always check token validity before we access the API. If our token isn’t valid then we could check for the Refresh Token. Azure AD gives us a refresh token to use when our access token is about to expire. This means that when we ask AAD for a new token and provide this refresh token, AAD will give us a new token without asking the user to re-authenticate.

By Default, Azure AD refresh tokens are valid for 14 days. This means as long as we refresh the actual token even once in this period then we do not need to re-authenticate. Another security constraint that Azure AD imposes is that the access token can only be refreshed for a maximum period of 90 days (i.e. 90 days after the initial issuance of the access and refresh tokens, the end user will have to sign themselves in again).

Alright, time to write some code. The code snippet below shows how you could structure your API calls from your mobile app. Notice that we always call either AcquireToken() or AcquireTokenByRefreshToken() before every call. This is to ensure that we always have a valid token before we send a request to the API. This could even be optimised further by checking if the access token still valid, then we skip the token refreshing call. I will leave this as an exercise for you to implement. In the next release of ADAL hopefully the TokenCache would be implemented, and then we would not need to do this.


public async Task<string> GetResultFromWebApi(string apiCallPath)
{
	var token = await AcquireOrRefreshToken ();
	using (var httpClient = new HttpClient())
	{
		httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
		HttpResponseMessage response = await httpClient.GetAsync(apiBaseAddress + apiCallPath);
		return await response.Content.ReadAsStringAsync();
	}
}

private async Task<string> AcquireOrRefreshToken()
{
	var refreshToken = _storage.Get<string> (Constants.CacheKeys.RefreshToken);
	AuthenticationResult authResult = null;

	if (string.IsNullOrEmpty (refreshToken)) 
	{
		authResult = await _authContext.AcquireTokenAsync (
			resourceId, clientId, new Uri (redirectUrl), new AuthorizationParameters (_controller), UserIdentifier.AnyUser, null);

	} 
        else 
        {
		authResult = await _authContext.AcquireTokenByRefreshTokenAsync (refreshToken, clientId);
	}

	// when calling refresh token, the UserInfo would be null
	if (authResult.UserInfo != null)
		_storage.Save<string> (Constants.CacheKeys.Email, authResult.UserInfo.DisplayableId);

	_storage.Save<string> (Constants.CacheKeys.Token, authResult.AccessToken);
	_storage.Save<string> (Constants.CacheKeys.ExpireOn, authResult.ExpiresOn.ToString("dd MMM HH:mm:ss"));
	_storage.Save<string> (Constants.CacheKeys.RefreshToken, authResult.RefreshToken);

	return authResult.AccessToken;
}

That’s it! Now your mobile app would keep interacting with the API using a valid token. And if you are concerned about what happens when the user account is disabled, or the password is changed, then well done, you are following the topic properly. Azure AD, would either try to re-authenticate the user again (by showing the login screen), or gives an error. So we need to add some error handling to our code to catch these types of exceptions and handle them properly in the mobile app.

I hope you find this blog post useful and I would love to hear from you if you have a question or comment. In the next blog post, we will look at how we could use the same token for accessing multiple resources registered in Azure AD.

This blog post is the second in a series that cover Azure Active Directory Single Sign On (SSO) Authentication in native mobile applications.

  1. Authenticating iOS app users with Azure Active Directory
  2. How to Best handle AAD access tokens in native mobile apps (this post)
  3. Using Azure SSO access token for multiple AAD resources from native mobile apps
  4. Sharing Azure SSO access token across multiple native mobile apps.
Category:
Application Development and Integration, Azure Platform, Mobile, Security, WebAPI
Tags:
, , , , , , ,

Join the conversation! 6 Comments

  1. how do i extend the lifetime of Refresh token. actually i am not able to find where to edit the settings to extend the lifetime of refresh token from 14days to 90 days. please help.

    Reply
    • Hi Athipathy,
      There is no setting or configuration that allows you to extend the lifetime of a refresh token. You can only extend the lifetime of a refresh token by refreshing the token. Meaning getting a new token (with a new refresh token that is valid for another 14 days). Hope this makes sense

      Reply
  2. In case of web servers with multiple instances, the request may reach different instance of the server based on load balancer. In such cases how do we maintain or cache the tokens, as the in memory cache of one instance of server will not be known to another instance of server

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: