Using Azure AD B2C to Authenticate Web App Users

Michael Collins
Neudesic Innovation
9 min readFeb 7, 2022
This photo shows a door with very heavy chains and a padlock. The door is intended to represent a protected web application that the user needs to log into before being able to use it.
Photo by Thom Milkovic on Unsplash

In this series, I have demonstrated how to set up an Azure Active Directory B2C tenant and then create custom flows for signing up and logging in using Azure Active Directory B2C custom policies. In this post, I will demonstrate how to actually use Azure Active Directory B2C to authenticate a user for a web application. Note that when I use the term web application, I mean a modern web browser application or a single page application that is typically built using a web framework such as Angular or Vue.js. I will cover server-based web applications in a future post.

This is the eighth post in a series on Azure Active Directory B2C and how to use Azure Active Directory B2C to create an identity management system for a Software-as-a-Service application. If you are new to this series, I recommend reading the earlier posts in the series:

  1. Building Application Identity Solutions using Azure AD B2C
  2. Configure Azure AD B2C For Customization
  3. Understanding the B2C Directory
  4. Sign Up or Sign In Users With Azure AD B2C: Part 1
  5. Sign Up New Users Using Azure AD B2C
  6. Log In With Local Accounts on Azure AD B2C
  7. Combining Sign Up and Sign In Into a Single Policy Using Azure AD B2C

Introducing the Microsoft Authentication Library

Using Azure Active Directory B2C to authenticate users is incredibly easy, thanks to the work of Microsoft’s engineers. Microsoft makes available several versions of a framework named Microsoft Authentication Library for different platforms. Microsoft Authentication Library implements a common pattern that can be followed for each platform to implement authentication on each platform.

Microsoft Authentication Library implements the client side protocols for OAuth 2.0 and OpenID Connect to interact with an authority. In our scenario, an authority is a custom policy backed by an Azure Active Directory B2C tenant. When using MSAL, we will seek to acquire a token. If you remember to our custom policies, the end result of every policy is the generation and output of a JSON Web Token. When authenticating, we are seeking to acquire an identity token that can be used to read information about the user that was authenticated.

Using MSAL is then pretty basic:

  1. We first will tell MSAL about the authority that we want to use to identify users.
  2. Then we will use MSAL to ask that authority to issue us a token about a user. The authority, or in our case the custom policy, will present the web UI to the user to ask them to authenticate using their username and password, and will then issue us the identity token as a result.

Understanding Azure Active Directory B2C Authentication Protocols

I have mentioned several times so far the names of protocols such as OAuth 2.0 and OpenID Connect. OAuth 2.0 is an authorization protocol that assists applications in authorizing user access to resources. Using OAuth 2.0, an application can ask another trusted service to authenticate the user and then issue a JSON Web Token that the application can use to perform actions on the user’s behalf. Typically, these actions are performed by invoking web APIs and providing the JSON Web Token with each call so that the other party can use the token to authorize the requests. The token provided by OAuth 2.0 is called an access token, because it is used to gain access to services used by the application.

OpenID Connect builds on top of OAuth 2.0 and extends it with the concept of identity. OpenID Connect is intended for authenticating and identifying users and returns an additional token called an identity token that contains information about the user that the service authenticated. We can use OpenID Connect to read the username and email address of the user, or to obtain other identifying information that would be useful to the application.

OAuth 2.0 communicates with clients by implementing several user flows. A flow is basically an agreement or protocol between the client application and the trusted service for how to obtain and exchange tokens. For our web application, we are going to use a flow known as Authentication Code Flow with Proof Key for Code Exchange or Authentication Code Flow with PKCE. OAuth 2.0 flows use security protocols that are dependent on secrets that can be verified cryptographically to ensure that the application and trusted service are talking to each other and there’s not a middleman or other rogue entity involved. Typically the two parties will share a secret value that is usually randomly generated. By exchanging and verifying the secret value, the application and trusted service can establish a trust relationship with each other.

When writing a modern web application, we run into a problem with the OAuth 2.0 flows. Because the code for a web application is downloaded onto the web browser and the code is JavaScript, anybody that can download the code could easily get access to the shared secret. This makes the secret useless. Using PKCE, the application and the trusted service can establish a dynamic secret at runtime that will secure the communication and the exchange of tokens between the two. For more information ok PKCE, read this.

The MSAL library that we will be using and Azure Active Directory B2C implement the Authentication Code Flow with Proof Key for Code Exchange.

Creating the Web Application

The first step in protecting a web application is having a web application to protect. I will start by creating that. For this demonstration, I will build a web application using the Vue.js framework. I will be using the Vue CLI to generate the skeleton for the website and I will be using TypeScript as the implementation language. At the time that I am writing this post, both Vue.js v2 and v3 are supported, but v3 is about to become the new default, so I will use v3 for my web application.

To start, I will open a terminal and use the Vue CLI to create my web application:

vue create projectcenter

The Vue CLI will ask me several questions in order to generate the skeleton web application. I will choose Vue.js v3 for the framework version and then accepted any default values for other settings. I will next use the Vue CLI to add support for TypeScript as the implementation language and to automatically convert the web application code to TypeScript:

vue add typescript

Finally, I will run the web application in a local development server and view it in a web browser:

yarn server
The skeleton web application created by the Vue CLI

When I run the web application, I can see that the local web server is listening for requests and serving the application from http://localhost:8080. Make a mental note about this because we will need this address when registering the application with Azure Active Directory B2C in the next section.

Registering the Web Application with Azure Active Directory B2C

Now that we have an application to protect, we will register the application with our Azure Active Directory B2C tenant. Open the Azure Active Directory B2C management console in a web browser and navigate to the App registrations view. This view will show you what applications have been registered with the tenant. If you have been following along with my journey from the beginning, you should only have three applications: the test application that we have been using to test the custom policies, IdentityExperienceFramework, and ProxyIdentityExperienceFramework that we set up to support the use of custom policies.

Follow these steps to register your application:

  1. Click the New registration link. A form will appear to collect the information for the new application registration.
  2. In the Name field, enter the name of your application. For example, I am using Project Center as the name of my application.
  3. For the Supported account types field, choose Accounts in any identity provider or organizational directory (for authenticating users with user flows).
  4. In the Redirect URI field, choose Single page application in the drop-down list and enter the local URL of the app running on your machine (https://localhost:8080).
  5. Ensure that the Grant admin consent to openid and offlineaccess permissions is checked.
  6. Click the Register button to complete the registration.

The application is now registered with the Azure Active Directory B2C tenant and you can use Azure Active Directory B2C to identify users.

📝 It is common to have multiple versions of an application for different platforms. For example, you may offer a web application, an iOS application, and an Android application. The good news is that one application registration can support multiple platforms, so you only need to register the application once. For example, I created an application named Project Center, but I do not need to create platform-specific application registrations such as Project Center (Web), Project Center (iOS), or Project Center (Android).

After the application registers, you should be taken to the Overview page for the application registration. Make note of the Application (client) ID value. You will need this next when we implement authentication in the web application.

Authenticating Web App Users

With the web application created and registered with the Azure Active Directory B2C tenant, I will start to implement the login feature for the application. I am going to use the combined sign up or log in flow that I created in my previous post to give the user the option of logging in or signing up for a new account.

The first thing that I need to do is to add a dependency on the MSAL JavaScript library. MSAL is packaged and deployed via NPM using the @azure/msal-browser package. I can add the dependency using Yarn:

yarn add @azure/msal-browser

Most of the MSAL functionality is exposed through the PublicClientApplication class. The first thing that I will do is to create a module that initializes a singleton instance of PublicClientApplication and exports it for other application code to use to interact with Azure Active Directory B2C:

The configuration for PublicClientApplication will pass my application ID from the Azure Active Directory B2C app registration, and the URL of the sign up or log in policy. I am also passing my local app URL for the redirect URI.

Next, I will add two buttons to App.vue to allow the user to log in or log out of the application. Logging in and logging out will happen via a pop-up window. When the user clicks the log in button, a pop-up window will appear and it will present the sign up or log in user journey. After the user is authenticated, then the pop-up window will close and the application will refresh to show the log out button.

If the user closes the log in pop-up window, an exception will be thrown and the user_cancelled error code will be returned. We can use this error code to restore the application state or indicate that the log in was cancelled.

Testing User Authentication

To test this, I will run my Vue.js application in a local development server:

yarn server

The web application will be hosted at http://localhost:8080. When I open the web browser and navigate to the URL, I will see the Log In button:

The Log In button now appears for the user to log in using Azure AD B2C

When I click the Log In button, a pop-up will appear and ask me to log in. I can enter a test username and password and then click the Sign In button:

Clicking the Log In button causes a pop-up window to appear to log in using Azure AD B2C

After successfully logging in, the Log In button should disappear and the Log Out button will appear:

The Log Out button now appears to show that the user is logged in

I can then click on the Log Out button and I will return to seeing the Log In button:

Clicking Log Out causes the user to be logged out and the Log In button re-appears

Where Did We Go?

In the first seven posts in this series, we focused on building sign up and log in capabilities in our custom Azure Active Directory B2C tenant. In this post, we put those policies into use to actually let a user log in using the custom policy and authenticate to use the application. We haven’t introduced any kind of authorization capabilities yet. That will be handled in a future post. But now you can build a simple web app and authenticate users. In the next post, we’ll attempt to do the same thing, but with a native SwiftUI iOS application.

⚠️ IMPORTANT: My sample code was meant to be simple and show the shortest route to implementing user authentication for a web application. There are probably more robust ways of implementing full MSAL capabilities, but they were outside the scope of my intention with this post. For a more complete example of how to integrate MSAL with Vue.js, see the sample code here.

--

--

Michael Collins
Neudesic Innovation

Senior Director of Application Innovation at Neudesic; Software developer; confused father