If you’ve worked with Azure AD B2C before, you know authentication is a multi-step process. Microsoft really wants you to go through this workflow, always. And generally, you should for maximum security. However, here’s my current use case, and why that doesn’t work this time around.
I’m building a NodeJS API application for a customer. This API will be consumed by a few external clients within existing systems. Certain events will trigger a call to the API, and after authentication, will create a new record or update records that were previously created. Pretty straightforward. Or so I thought.
There’s an extra wrinkle – the user account for each of these external apps is managed in an Azure AD B2C tenant. As I said, authentication is a multi-step process. Unfortunately, that doesn’t work for my use case. Authentication for these systems needs to happen programmatically. There rarely will be a user behind the call to manually enter their credentials.
What I need is this:
Fortunately, after a bunch of testing (and a timely Azure preview feature), I am happy to report that programmatic or “headless” authentication to Azure AD B2C using only a username and password is possible to achieve!
Steps to implement:
Step 1 – Set up your Azure AD B2C tenant so this authentication method is possible using these instructions.
- At the time of writing, this feature is listed as “preview”.
- Setup consists of “Create a Resource Policy Owner” and “Register an application”. Do both exactly as described.
Step 2 – When you get to “Test the policy”, the steps here are close, but not quite correct per testing from myself and a few others. You will need to use a different URL than what’s listed:
Step 3 – Install libraries in your NodeJS application that are required for authentication to Azure B2C. You will need:
- morgan* (not technically required, but useful for debugging)
Step 4 – Implement the example code provided in this Azure-Samples GitHub repo. I had to make a few minor tweaks:
- This line of code gave me a couple of problems –
if (claims['scp'].split(" ") …
- First, the linter I’m using in VS Code stated that the “dot notation” was the more correct way to access the property. I have a linter on my CI build in Jenkins, so to avoid build issues I changed it to
- Unfortunately, my claims object didn’t actually have an ‘
scp’ property anyway (more on that topic here). Therefore, I changed the code to reference the ‘
name’ property, which I expected since we chose to return it when setting up the Azure AD B2C tenant Resource Policy Owner. I replaced the code in this function with:
var claims = req.authInfo;
res.status(200).send(claims.name + ' - Workie!');
At this point I could successfully request an access token from Azure AD B2C using only the username and password, and then pass that token as a Request Header (
Authorization: Bearer eyJ0eXAiOiJ…) in all of my API calls for successful authentication.