Using OAuth On-Behalf-Of flow in a Node.js Azure Functions

April 15, 2021

While implementing a couple of Azure Functions, I needed to use the OAuth 2.0 On-Behalf-Of flow. With this flow, you can allow, for instance, an API to perform tasks on your behalf. This flow is great when you want to offload some of the work from the front-end or perform additional calls on the back-end when processing data.

For this type of flow, there are already a lot of samples out there. Unfortunately, most of them are outdated and written in C#. That is why I thought it would be a good idea to write this article, to show how you can use this OAuth On-Behalf-Of flow in Node.js Azure Functions.

Code Sample msal-obo-azurefunctions

Azure AD App Registration

First things first, it all starts with your Azure AD App Registration.

This App Registration will be used for the following:

  1. To acquire a token to call the Azure Function
  2. The Azure Function will use the acquired token to request an Access Token from the same App Registration on your behalf.

Follow the following steps to set up the app registration:

  • Go to your Azure AD
  • Open App Registrations and create a new registration
  • Give the app a meaningful name, select the type of accounts you want to support, and provide your redirect URL
Azure AD App registration
Azure AD App registration
  • Once the app is registered, go to expose an API and click on the set link next to Application ID URI.
  • By default, it will provide you a URI like: api://<client-id>. You can leave this in place, and click on save
  • Under the Scopes defined by this API, add a new scope. In my case, I use user_impersonation as the scope name, but you can define it yourself.
Create an app scope
Create an app scope
  • Save the scope
Expose API overview
Expose API overview
  • Go to API Permissions and define the scopes you want to grant access to the run on-behalf-of flow. By default, it will have the Microsoft Graph User.Read scope already configured. We will use this scope in the sample.
  • If you want, you can already do an admin consent.
  • Go to Certificates & Secrets and create a new client secret. You will need the generated secret later on in the process, so copy it.
  • On the Overview you can copy the Application (client) ID as well.

The code

For this article, I prepared the following code sample: msal-obo-azurefunctions.

The sample project contains one Azure Functions profile-get, which will use the MSAL On-behalf-of flow to request an access token and get the current user its profile by calling the Microsoft Graph.

To use the sample, all you need to do is pass the client id and client secret to the config object in the index.ts file of the function.

Important The config object is added in the code to simplify the process. When you would use this in production, it is recommended to put these kinds of IDs and Secrets in Azure Key Vault. Read more on using the Key Vault in your Azure Functions on Use Key Vault references for App Service and Azure Functions.

The flow

Once you got all of it in place, you first need to retrieve a token to call the API. The scope you will use for this is the api://<client-id>/user_impersonation.

With the retrieved token, you can call the Azure Function. Pass it as the authorization header.

Performing the Azure Functions call
Performing the Azure Functions call

When the Azure Function retrieves the call, it will first validate the JWT token to make sure it comes from known audiences. In this case, it is the Application ID URI api://<client-id>. If it is a valid token, that will be used to get an access token to call the Microsoft Graph on your behalf.

Info In the sample, you will find an app folder. This folder contains a sample express app that you can use combined with the Azure Function to test the flow.