Secure access to on-premises APIs with Azure Active Directory Application Proxy
You may have business logic APIs running on-premises, or hosted on virtual machines in the cloud. Your native Android, iOS, Mac, or Windows apps need to interact with the API endpoints to use data or provide user interaction. Azure AD Application Proxy and the Microsoft Authentication Library (MSAL) let your native apps securely access your on-premises APIs. Azure Active Directory Application Proxy is a faster and more secure solution than opening firewall ports and controlling authentication and authorization at the app layer.
This article walks you through setting up an Azure AD Application Proxy solution for hosting a web API service that native apps can access.
Overview
The following diagram shows a traditional way to publish on-premises APIs. This approach requires opening incoming ports 80 and 443.
The following diagram shows how you can use Azure AD Application Proxy to securely publish APIs without opening any incoming ports:
The Azure AD Application Proxy forms the backbone of the solution, working as a public endpoint for API access, and providing authentication and authorization. You can access your APIs from a vast array of platforms by using the Microsoft Authentication Library (MSAL) libraries.
Since Azure AD Application Proxy authentication and authorization are built on top of Azure AD, you can use Azure AD Conditional Access to ensure only trusted devices can access APIs published through Application Proxy. Use Azure AD Join or Azure AD Hybrid Joined for desktops, and Intune Managed for devices. You can also take advantage of Azure Active Directory Premium features like Azure AD Multi-Factor Authentication, and the machine learning-backed security of Azure Identity Protection.
Prerequisites
To follow this walkthrough, you need:
- Admin access to an Azure directory, with an account that can create and register apps
- The sample web API and native client apps from https://github.com/jeevanbisht/API-NativeApp-ADAL-SampleApp
Publish the API through Application Proxy
To publish an API outside of your intranet through Application Proxy, you follow the same pattern as for publishing web apps. For more information, see Tutorial: Add an on-premises application for remote access through Application Proxy in Azure Active Directory.
To publish the SecretAPI web API through Application Proxy:
Build and publish the sample SecretAPI project as an ASP.NET web app on your local computer or intranet. Make sure you can access the web app locally.
In the Azure portal, select Azure Active Directory. Then select Enterprise applications.
At the top of the Enterprise applications - All applications page, select New application.
On the Browse Azure AD Gallery page, locate section On-premises applications and select Add an on-premises application. The Add your own on-premises application page appears.
If you don't have an Application Proxy Connector installed, you'll be prompted to install it. Select Download Application Proxy Connector to download and install the connector.
Once you've installed the Application Proxy Connector, on the Add your own on-premises application page:
Next to Name, enter SecretAPI.
Next to Internal Url, enter the URL you use to access the API from within your intranet.
Make sure Pre-Authentication is set to Azure Active Directory.
Select Add at the top of the page, and wait for the app to be created.
On the Enterprise applications - All applications page, select the SecretAPI app.
On the SecretAPI - Overview page, select Properties in the left navigation.
You don't want APIs to be available to end users in the MyApps panel, so set Visible to users to No at the bottom of the Properties page, and then select Save.
You've published your web API through Azure AD Application Proxy. Now, add users who can access the app.
On the SecretAPI - Overview page, select Users and groups in the left navigation.
On the Users and groups page, select Add user.
On the Add assignment page, select Users and groups.
On the Users and groups page, search for and select users who can access the app, including at least yourself. After selecting all users, select Select.
Back on the Add Assignment page, select Assign.
Note
APIs that use integrated Windows authentication might require additional steps.
Register the native app and grant access to the API
Native apps are programs developed to use on a particular platform or device. Before your native app can connect and access an API, you must register it in Azure AD. The following steps show how to register a native app and give it access to the web API you published through Application Proxy.
To register the AppProxyNativeAppSample native app:
On the Azure Active Directory Overview page, select App registrations, and at the top of the App registrations pane, select New registration.
On the Register an application page:
Under Name, enter AppProxyNativeAppSample.
Under Supported account types, select Accounts in this organizational directory only (Contoso only - Single tenant).
Under Redirect URL, drop down and select Public client/native (mobile & desktop), and then enter *https://login.microsoftonline.com/common/oauth2/nativeclient *.
Select Register, and wait for the app to be successfully registered.
You've now registered the AppProxyNativeAppSample app in Azure Active Directory. To give your native app access to the SecretAPI web API:
On the Azure Active Directory Overview > App Registrations page, select the AppProxyNativeAppSample app.
On the AppProxyNativeAppSample page, select API permissions in the left navigation.
On the API permissions page, select Add a permission.
On the first Request API permissions page, select the APIs my organization uses tab, and then search for and select SecretAPI.
On the next Request API permissions page, select the check box next to user_impersonation, and then select Add permissions.
Back on the API permissions page, you can select Grant admin consent for Contoso to prevent other users from having to individually consent to the app.
Configure the native app code
The last step is to configure the native app. The code snippet that's used in the following steps is based on Add the Microsoft Authentication Library to your code (.NET C# sample). The code is customized for this example. The code must be added to the Form1.cs file in the NativeClient sample app where it will cause the MSAL library to acquire the token for requesting the API call and attach it as bearer to the header in the request.
Note
The sample app uses Azure Active Directory Authentication Library (ADAL). Read how to add MSAL to your project. Remember to add the reference to MSAL to the class and remove the ADAL reference.
To configure the native app code:
In Form1.cs, add the namespace
using Microsoft.Identity.Client;
to the code.Remove the namespace
using Microsoft.IdentityModel.Clients.ActiveDirectory;
from the code.Remove lines 26 and 30 because they are no longer needed.
Replace the contents of the
GetTodoList()
method with the following code snippet:// Acquire Access Token from Azure AD for Proxy Application var clientApp = PublicClientApplicationBuilder .Create(clientId) .WithDefaultRedirectUri() // Will automatically use the default URI for native app .WithAuthority(authority) .Build(); var accounts = await clientApp.GetAccountsAsync(); var account = accounts.FirstOrDefault(); var scopes = new string[] { todoListResourceId + "/user_impersonation" }; AuthenticationResult authResult; try { authResult = await clientApp.AcquireTokenSilent(scopes, account).ExecuteAsync(); } catch (MsalUiRequiredException ex) { authResult = await clientApp.AcquireTokenInteractive(scopes).ExecuteAsync(); } if (authResult != null) { // Use the Access Token to access the Proxy Application var httpClient = new HttpClient(); httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken); // Call the To Do list service var response = await httpClient.GetAsync(todoListBaseAddress + "/api/values/4"); var responseString = await response.Content.ReadAsStringAsync(); MessageBox.Show(responseString); }
To configure the native app to connect to Azure Active Directory and call the API App Proxy, update the placeholder values in the App.config file of the NativeClient sample app with values from Azure AD:
Paste the Directory (tenant) ID in the
<add key="ida:Tenant" value="" />
field. You can find and copy this value (a GUID) from the Overview page of either of your apps.Paste the AppProxyNativeAppSample Application (client) ID in the
<add key="ida:ClientId" value="" />
field. You can find and copy this value (a GUID) from the AppProxyNativeAppSample's Overview page, in the left navigation under Manage.This step is optional as MSAL uses the method PublicClientApplicationBuilder.WithDefaultRedirectUri() to insert the recommended reply URI. Paste the AppProxyNativeAppSample Redirect URI in the
<add key="ida:RedirectUri" value="" />
field. You can find and copy this value (a URI) from the AppProxyNativeAppSample's Authentication page, in the left navigation under Manage.Paste the SecretAPI Application ID URI in the
<add key="todo:TodoListResourceId" value="" />
field. This is the same value astodo:TodoListBaseAddress
below. You can find and copy this value (a URI) from the SecretAPI's Expose an API page, in the left navigation under Manage.Paste the SecretAPI Home Page URL in the
<add key="todo:TodoListBaseAddress" value="" />
field. You can find and copy this value (a URL) from the SecretAPI Branding & properties page, in the left navigation under Manage.
Note
If the solution doesn't build and reports the error invalid Resx file, in Solution Explorer, expand Properties, right-click Resources.resx, and then select View Code. Comment lines 121 to 123.
After you configure the parameters, build and run the native app. When you select the Sign In button, the app lets you sign in, and then displays a success screen to confirm that it successfully connected to the SecretAPI.
Next steps
Feedback
Submit and view feedback for