Authenticate a HoloLens Application to the Azure AD

Martin Tirion
8 min readAug 18, 2022

This article is part of a series with best practices from projects executed by a Microsoft CSE team I’m part of. Have a look at Learnings from developing a HoloLens Application to get the overview of the other posts.

I had this very simple idea (I thought). As the HoloLens 2 has a nice Windows Hello implementation using iris-scan, the user is securely logged into the device as soon as he or she puts it on. In the application we were developing, I just wanted to use the identity of the logged in user to connect to the backend API. It turned out to be a long journey at the time. Of course, when you know how to do it, it’s not that complicated. So it’s a good idea to share it with you, so it saves you time. 🤓

There are a few key ingredients for setting up this kind of authentication:

  • Setting up Azure AD App Registrations (yes, plural … that’s key).
  • Get an access token for the logged in user on the HoloLens for a specific endpoint (our backend API).
  • Use the token to call the backend API.

Setting up Azure AD App Registrations

An App Registration in the Azure Active Directory is a way to define an application and connect permissions to it. An App Registration has a unique id (Client ID) that is used by the application to authenticate against it. There are settings in the App Registration that determines how it can be used. More information can be found in this article: How and why apps are added to Azure AD — Microsoft Entra | Microsoft Docs.

We need (at least) two app registrations: one for the API and one for the HoloLens Application. Although it seem a bit strange to have an app registration for the HoloLens, it’s the only way to identify the unit and let the Azure AD give you access to the API. If you read the rest of this article it will make sense. 🤓.

We won’t go into the details of the Azure Portal UI, but if you need a walkthrough how to setup an App Registration, please follow this guide: Quickstart: Register an app in the Microsoft identity platform — Microsoft Entra | Microsoft Docs.

Create a first App Registration for the HoloLens Application:

  1. Give it a good name, use the defaults, no redirect URL and click Register.
  2. Go to the Authentication tab under Manage in the left bar of the App Registration UI.
  3. Under Advanced settings set Allow public client flows to Yes and click Save.
  4. Write down the app registration name, the tenant id and the application (client) id.

Next, create an App Registration for the backend API:

  1. Give it a good name, use the defaults, no redirect URL and click Register.
  2. Go to the Expose an API tab under Manage in the left bar of the App Registration UI.
  3. Click Set just after the Application ID URI at the top. Keep the defaults and click Save.
  4. A bit down click Add a scope and enter user_impersonation as scope name, select Admins and users for Who can consent?.
    Enter a display name and description for both the admin and user consent and click Add scope.
  5. Again a bit down click Add a client application and enter the application (client) id of the HoloLens Application. Check the Authorized scopes and click Add application.
    This step provides access for the HoloLens Application to connect to the backend API.
  6. Write down the app registration name, the tenant id, the application (client) id, the application ID URI and the scope name.

Configure the HoloLens Application

Now we have the app registrations in place, we need to configure the HoloLens Application to use the things we just created.

IMPORTANT: Keep the client id’s and such a secret! Do not publish it in your repo. In a CI/CD pipeline this information can be retrieved from the Azure KeyVault for instance to keep it safe.

As described in the previous post Adding Application Settings to a Unity-based HoloLens Application, we can now setup these settings in an appsettings.json file for instance. The SettingsManager class from the Application in the sample repo MRTK Utilities can be used to read the settings at runtime.

As the HoloLens Application is a Universal Windows Platform (UWP) application, you need to enable some capabilities to enable the app to use functionality we need. In Unity, go the Project Settings dialog and go to Player settings. All the way down under Settings for Universal Windows Platform and then Publishing Settings you can find the capabilities list. Make sure these capabilities are checked:

  • Enterprise Authentication
  • Internet (Client & Server)
  • Private Networks (Client & Server)
  • User Account Information
Unity Capabilities settings

Register the return URI for the HoloLens Application

Now we need to get some information from the HoloLens Application and register it in the App Registration for the HoloLens Application. We need to get the return URI that is generated by UWP for this package. The format is like this:

ms-appx-web://Microsoft.AAD.BrokerPlugIn/S-1-15-2-111111111-222222222-3333333333-4444444444-5555555555-66666666-7777777777

The id “S-1–15–2–11111…” is generated by information from the Publishing Settings including the generated certificate.

Note: for development purposes you can commit the WSATestCertificate.pfx to the repo, so all developers use the same one on their machine. This ensures that the return URI is the same. Make sure that you use a certificate from the KeyVault (for instance) in the CI/CD pipeline when automating packaging the application for production.

The code to get the return URI in a UWP app is this:

using Windows.Security.Authentication.Web;...string url = string.Format(
CultureInfo.InvariantCulture,
"ms-appx-web://Microsoft.AAD.BrokerPlugIn/{0}",
WebAuthenticationBroker
.GetCurrentApplicationCallbackUri()
.Host
.ToUpper(CultureInfo.InvariantCulture));

You have run the HoloLens Application once on the device and print out the URI (for instance with the Debug Console). If you have the return URI, go to the App Registration for the HoloLens Application in the Azure Portal and follow these steps:

  1. Go to the Authentication tab under Manage in the left bar of the App Registration UI.
  2. Click Add a platform and click Mobile and desktop applications
  3. Enter the return URI as Custom redirect URIs and click Configure.

Once this is registered, you can comment the code to show the return URI.

Using the Microsoft Authentication Library (MSAL) for authentication

Now the registrations are in place, we can use the Microsoft Authentication Library (MSAL) to authenticate. The code below uses MSAL to acquire the token silent, so without UI, which is important for a good user experience on the HoloLens.

IAccount account;
try
{
// create and build the client app.
// We use the client id of the Client app registration.
// we also use the Windows broker (Web Account Manager)
App = PublicClientApplicationBuilder
.Create(ClientId)
.WithAuthority(AadAuthorityAudience.AzureAdMultipleOrgs)
.WithBroker()
.WithWindowsBrokerOptions(new WindowsBrokerOptions
{
ListWindowsWorkAndSchoolAccounts = true,
})
.Build();
// get the basic system account from the OS (UWP only!)
account = PublicClientApplication.OperatingSystemAccount;
}
catch (Exception ex)
{
// error! skip for this demo.
return;
}
AuthenticationResult authResult = null;
var scopes = Scopes.Split(' ');
try
{
// acquire the access token silenty
authResult = await App.AcquireTokenSilent(scopes,
account).ExecuteAsync();
}
catch (Exception ex)
{
// error! skip for this demo.
return;
}
if (authResult != null)
{
// getting the access token successful.
Username = authResult.Account.Username;
AccessToken = authResult.AccessToken;
}

MSAL also takes care of refreshing tokens in the internal cache. To make use of that, you always have to call this method and not cache the token yourself. Don’t worry about performance, it’s extremely fast.

Using the Microsoft Authentication Library (MSAL) for authentication with Device Code flow

In the project we worked on the HoloLens Application, we used a different Azure AD on the HoloLens then on the development machines. To make the development in Unity easier and enable running the application with the Unity Player, we use Device Code Flow for authentication in the player. With this process a code is shown that you have to enter on https://login.microsoftonline.com/common/oauth2/deviceauth. This can be done on another device, but also on the development machine.

Device code flow

When you click Next you will be prompted to enter your credentials. Once you’re authenticated the last step asks you if you want to login to the App Registration name of the HoloLens Application. When you click Continue, you’re authenticated and the code continues in your application.

This is the code that can be used to use this device code flow:

IAccount account;
try
{
// create and build the client app.
// We define the redirect URL to use (mobile client default)
// and provide the tenant ID to login to.
App = PublicClientApplicationBuilder
.Create(ClientId)
.WithRedirectUri("https://login.microsoftonline.com/common/oauth2/nativeclient")
.WithAuthority($"https://login.microsoftonline.com/{TenantId}")
.Build();
}
catch (Exception ex)
{
// error! skip for this demo.
return;
}
AuthenticationResult authResult = null;
var scopes = Scopes.Split(' ');
try
{
// Start the Device Code flow.
// We write the result message to the debug console.
// It contains instructions to open a URL in a browser
// and enter the given code. Once that flow is completed
// (or cancelled) we return in this method.
authResult = await App.AcquireTokenWithDeviceCode(
scopes, async result =>
{
// this is the instruction what to do
Debug.WriteLine(result.Message);
}).ExecuteAsync();
}
catch (Exception ex)
{
// error! skip for this demo.
return;
}
if (authResult != null)
{
// getting the access token successful.
Username = authResult.Account.Username;
AccessToken = authResult.AccessToken;
}

Access the backend API authenticated from the HoloLens Application

Now we have authenticated the user and obtained a token, it’s easy to call the backend API with this information. The code below is from the sample repo MRTK Utilities (see below) and uses the AuthenticationManager to get the access token as string. The SettingsManager contains the base URL for the backend API. And just for demo we call a fictive URL of a fictive backend 🤔.

using (HttpClient client = new HttpClient())
{
client.BaseAddress = new
Uri(settingsManager.Settings.BaseEndPointUrl);
string url = "/YourApi/GetSampleData";
string token = await authenticationManager.GetAccessTokenAsync();
// setup the JWT token as bearer for authenticated API access
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", token);
try
{
// get the data from the backend API
string json = await _client.GetStringAsync(url);
List<string> data;
data = JsonConvert.DeserializeObject<List<string>>(json);
return _data;
}
catch (Exception ex)
{
Debug.LogError($"ERROR: url={url}\n{ex}");
}
}

We have code to help you out

In our sample repo MRTK Utilities we have code to make implementation of this authentication mechanism easier for you. When you import this Unity Package from that repo, it provides you with

  • Application hierarchy containing helper scripts.
  • Scripts\Helpers\AuthenticationHelper.cs with methods containing the code above, with a bit more error handling.
  • Scripts\AuthenticationManager.cs which is a MonoBehaviour and can be used to obtain the token (login the user or get from the cache) by either the silent approach or device code flow, depending on the environment you’re in.
  • Scripts\SettingsManager.cs that is used to read the static settings with the secrets from appsettings.json.
  • Scripts\ApplicationManager.cs to manage the logic of the application and provide access to other classes in the application to the AuthenticationManager.
  • Scripts\Data\ApiClient.cs with code to call the backend API and use the access token.

Conclusion

As said in the top of this post, if you know what to do it’s simple. I hope this can help you implement this in your HoloLens applications when you need this kind of authentication.

In other posts we’ll explain how to use settings, for instance in authentication. See Learnings from developing a HoloLens Application for the overview of the posts.

--

--

Martin Tirion

Senior Software Engineer at Microsoft working on Azure Services and Spatial Computing for enterprise customers around the world.