Azure Key Vault in UWP Applications

As part of my strategy to transition some of my skills from WPF to UWP (two standards of graphical user interfaces with C# that are fairly similar), I decided to do a full port of my Azure Key Vault Manager application into UWP. One of the most significant issues I ran into was around the authentication mechanism to utilize Key Vault.

UWP’s standard of authentication is to use WebAuthenticationCoreManager and WebTokenRequest to authorize against (at least) the Microsoft account provider. However, in using these classes, the developer is turning over control of the redirect URI for the authentication callback to the WebAuthenticationCoreManager. UWP defines a standard for the format of this callback; “ms-appx-web://Microsoft.AAD.BrokerPlugIn/{GUID}”.

When registering a native client application in Azure Active Directory to use Key Vault, there is, as of the time of this writing, no item registered in the application directory that grants permissions to the Key Vault resource for a native client application.

The current workaround for this for everything else? Applications can impersonate PowerShell by submitting its client ID and redirect URI during the token acquisition process instead of using the developer’s registered client:

PowerShell’s Client ID: 1950a258-227b-4e31-a9cf-717495945fc2
PowerShell’s Redirect URI: urn:ietf:wg:oauth:2.0:oob

This strategy works wonderfully… unless you’re using WebAuthenticationCoreManager. Don’t forget, that mechanism does not allow the developer to set the redirect URI manually, which means any attempt to use the PowerShell client ID will result in an error retrieving the token.

However, you can use the Microsoft.IdentityModel.Clients.ActiveDirectory package within a UWP application to authenticate. It won’t integrate with the system’s authentication as cleanly as WebAuthenticationCoreManager, which means SSO from the system level is not supported. However, if you’re using WebAuthenticationCoreManager in other parts of your application, the given code can wrap an access token with a WebTokenResponse to enable compatibility with those token providers.

Using the IdentityModel package is as simple as using this code:

private const string LoginBase = "https://login.microsoftonline.com";
private const string PowershellClientId = "1950a258-227b-4e31-a9cf-717495945fc2";

private static TokenCache TokenCache = new TokenCache();

public async Task<WebTokenResponse> GetToken(string resource, string authority = "common")
{
	var authContext = new AuthenticationContext($"{LoginBase}/{authority}", true, TokenCache);
	var result = await authContext.AcquireTokenAsync(resource, PowershellClientId, new Uri("urn:ietf:wg:oauth:2.0:oob"), PromptBehavior.Auto);
	var accessToken = result.AccessToken;
	return new WebTokenResponse(accessToken);
}

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 )

Facebook photo

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

Connecting to %s