July 8, 2018

Login as Service Principal (Application) in Azure Active Directory with JWT

Here's a quick post about how to login as a Service Principal in Azure for non-interactive login scenario.

Say you have an API service, protected by Azure Active Directory (AAD). It's being used by a web application, and it works fine with an interactive login – for users in the AD.

Now you're building a headless application, such as a long-running service, and it also needs to access the APIs. You can create a regular user in AD and use it from the application using username / password authentication, but you know that's not a clean solution. Azure must have something, and they do, in the form of Service Principal. It's also known as an Application, for example, when you're creating a service principal, you're actually registering an application. Like many things in Azure, they seem to love confusing terms.

More info about registering an application can be found in Microsoft's documentation.

Benefits

One benefit of using a service principal is that you can create multiple keys (passwords), and use that from your application. This can be useful if you want to control access to APIs by say different clients of the application.

How many keys would Azure let you create? It doesn't seem to be documented anywhere...

Also, you may not have permission to create a user in the Active Directory (perhaps it's managed by a different team in your company), but you can register an application (as long as the App Registrations option is set in the Active Directory).

High-level Diagram

Here's a quick diagram that I created to illustrate the flow:

Note: Steps 4 and 5 are cached by Azure SDK.

Sample Code

A simple, but functional demo code can be found in my Github repository.

On the Wire

Here's what the request looks like for getting the token from AAD from the client application:

TO URL: https://login.microsoftonline.com/

POST /[YourADTenantName].onmicrosoft.com/oauth2/token HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache

client_id=[YourServicePrincipalID}&client_secret=[OneOfSecretKey]&grant_type=client_credentials&resource=[YourServiceAppId or URI]

Azure Management API

Service Principals can access Azure resources, and can be assigned to roles as well. One scenario where this can be useful is if you need to monitor Azure metrics. A sample can be found in Azure's official repository.

Can you add the Service Principal to AAD Group?

Yes, but not via the Portal yet at the time of writing this post. That should give more flexibility when setting up authorization policies, as you can use group based claims.