In this post I’ll demonstrate how to protect an Azure API App by using App Service authentication; a turn key solution for providing authentication and authorization to any kind of Azure App Service. It supports many types of authentication providers, but for this post I’ll use Azure Active Directory. Once that is set up, I’ll show how to generate a client library for the API using AutoRest. The generated client authenticates with the API App by using a bearer token that is retrieved from Azure AD by providing application identity (service principal) credentials.

Register applications in Azure AD

You’ll use two Azure AD applications: one for the protected API app and one for the calling app. Follow these steps for each application to add them to Azure AD:

  1. In the Classic Azure portal, navigate to the Applications tab of your Azure AD tenant.

  2. In the bottom toolbar, click Add to add a new application to the directory.

  3. In the pop-up window that opens, select Add an application my organization is developing:

    AddApplicationWizard01.png
  4. Enter the name of your API / application and make sure Web Application and/or Web API is selected:

    AddApplicationWizard02.png
  5. Enter the URL of the API / application. You can use the same URL as the App ID URI.

    AddApplicationWizard03.png
  6. When the application has been added, navigate to the Configure tab and notice the generated client id. You’ll need the client id later on.

Follow the above steps for both applications, so that you’ve got an protected AD app and a caller AD app set up.

Set permissions for caller AD application

The caller AD application requires permission to access the protected AD application.

  1. On the Configure tab for the AD application representing the caller, scroll down to Permissions to other applications and click on Add application.

    SetPermissions01.png
  2. Select All Apps and click on the checkmark button in the upper-right corner.

    SetPermissions02.png
  3. Select the protected API and click on the Complete checkmark to close the dialog.

    SetPermissions03.png
  4. Click on Delegated Permissions and select the checkbox to access the protected AD application:

    SetPermissions04.png

The caller AD application is now granted access to the protected AD application.

Generate access key for caller AD application

You also need to generate an access key (client secret) which is used to authenticate the caller application when requesting a token from Azure AD.

  1. On the Configure tab for the caller AD application, scroll down to Keys and select a duration:

    AccessKey01.png
  2. Click Save in the bottom toolbar to generate the key value. Store the value somewhere where you can retrieve it later on.

Setup authentication for the protected API

  1. In the (new) Azure portal, go to the Settings of your Api App and select Authentication/Authorization.

  2. In the Authentication/Authorization blade, turn on App Service Authentication and select Azure Active Directory as the authentication provider.

    ApiAppAuth01.png
  3. If the Azure AD you’re using is the default Azure AD instance for the subscription, you can simply select the Express management mode and select the application from here. Otherwise, select Advanced. You’ll need to enter the client id of the protected API as well as the Issuer URL of the Azure AD instance.

    To retrieve the Issuer URL:

    1. Navigate to your Azure AD tenant in the Classic Azure portal.
    2. In the bottom toolbar, click on View Endpoints.
    3. Copy the link to the Federation Metadata Document and paste the URL in a new browser window.
    4. In the XML document that is displayed, the Issuer URL is the value of the entityId attribute of the root EntityDescriptor element (e.g. https://sts.windows.net/20ef1a8a-****-****-****-************)).
  4. Click OK and don’t forget the save your changes on the Authentication / Authorization blade.

Your Api App is now protected and you can test this by opening up a browser and navigating to the Api App. You should see a sign-in page. If you’re directly taken to the service you may still be signed in to your Azure AD. Start a new browser in Private / Incognito mode to make sure you’re not already signed in.

Generate a client library for the API

Because the API App exposes a Swagger endpoint, you can use AutoRest to generate a client library to call the API.

autorest -Input http://localhost:8282/swagger/docs/v1 -Namespace Amolenk.ApiApp -ClientName ApiClient -AddCredentials

This command will generate some C# files that you must add to the calling application. In addition, you must also add the Microsoft.Rest.ClientRuntime.Azure.Authentication NuGet package (at the time of writing, you should select the 2.0.1 prerelease package). This package provides ADAL based authentication for the generated client library. Adding the NuGet package will also install the Microsoft.Rest.ClientRuntime NuGet package which is required to be able to compile the generated code.

Notice that I’ve used the -AddCredentials flag when running AutoRest. This tells AutoRest to include a ServiceClientCredentials property and constructor parameter in the generated client. The TokenCredentials class in the Microsoft.Rest.ClientRuntime package extends the ServiceClientCredentials class and can be used for OAuth authentication. Additionally, the Microsoft.Rest.ClientRuntime.Azure.Authentication package supports both username/password and service principal login scenarios for Azure AD.

As this is an application to application scenario, the calling app will use service principal credentials to authenticate with the protected API.

Call the protected API

To call the protected API, you need the following information:

  1. The client ids of both the protected and caller apps.
  2. The generated access key of the calling app.
  3. The Authority URL, which contains the name of the Azure AD tenant in which you provisioned your apps. The format should be https://login.windows.net/tenant-name.onmicrosoft.com.

Using this information, you can use the code below to access the protected app:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var clientCredential = new ClientCredential(
callerAppClientId, callerAppAccessKey);

AuthenticationContext context = new AuthenticationContext(authorityUrl);
AuthenticationResult authenticationResult = context.AcquireToken(
protectedAppClientId, clientCredential);
ApplicationTokenProvider tokenProvider = new ApplicationTokenProvider(
context, protectedAppClientId, clientCredential, authenticationResult);

TokenCredentials creds = new TokenCredentials(tokenProvider);

// DeviceManagementClient class is generated using AutoRest
var client = new DeviceManagementClient(creds);
client.BaseUri = new Uri("https://amolenk-devicemanagementapi.azurewebsites.net");
client.Device.SayHelloAsync();

On a side note: the ApplicationTokenProvider used in the example also exposes a LoginSilentAsync method which directly returns a ServiceClientCredentials instance and would be nicer to use than the code above. Unfortunately though, there’s no way to pass the client id of the protected API because LoginSilentAsync requires the audience to be of type Uri, while a client id is a string. I’ve opened an issue for this at https://github.com/Azure/autorest/issues/835.