Azure AD for user authentication with Vue and NestJS

RecuencoJones
adidoescode
Published in
7 min readOct 15, 2020

Ever wondered how to create an application with user authentication but did not want to suffer implementing user management yourself?

Nowadays there are plenty of solutions regarding User management in the form of Identity Platforms. Almost every known social media and IT company have their own, just to list a few of them:

For this article we will be working with Microsoft Identity Platform, a.k.a Azure Active Directory for authenticating users in a web application.

Creating a directory in Azure Active Directory

First things first, we will need an Azure account — don’t worry about 💸 we are going to work on free license! So go ahead, log in or register at portal.azure.com.

On Azure, go to Create a resource blade and look for Azure Active Directory, there you will be able to Create a directory. Fill the form with any values you prefer, for this example I will be using the name of my dog: Pinquito 🐕

Once Microsoft is finished creating your directory (takes about 1 min) you can navigate to Azure Active Directory blade.

You might need to sign out and sign in back again for the directory to be selected by default!

Creating an App registration

Let’s head now to App registrations view and click New registration.

Give the app a name — i.e. Hello World App.

From Supported account types we will select the option for Accounts in any organizational directory and personal Microsoft accounts. This will implicitly set the application to use v2.0 of Azure AD.

v2.0 of Azure AD also enables cool capabilities like Application Roles.

As for Redirect URI we will use Web and http://localhost:8080 to be able to run Single Sign-On for the application locally.

Hit Register button and wait for it to finish with the registration.

From the Overview blade we will obtain two IDs required for later: the client ID and tenant ID. These will identify our application as well as its realm, where users may have different attributes or claims.

Client ID and Tenant ID

Head now to the Authentication blade to check Access tokens and ID tokens checkboxes from the Implicit grant section and don’t forget to save! 💾

Enabled access tokens and ID tokens

If you are curious, you can check the Manifest section, which is the JSON representation of the App configuration. We will need this later for adding Application roles.

Building the frontend with Single Sign-On

It’s time to get our hands dirty with some JavaScript 🤓

Setting up modern frontend projects its exhausting unless you are using one of the many CLI or generators out there — although anyways you should be aware of all the tools involved in the process: bundlers, linters, transpilers, frameworks… thankfully there is codesandbox.io to help us in this mighty quest!

Head to the Vue template in codesandbox and make yourself familiar with the files in it. Then look for Dependencies section on the file tree and hit Add Dependency. A browsable list of npm packages will be opened in a popup, look for msal and click it to install it 🎉.

Disclaimer: We will be using Vue for this example, but you can use just about anything, there is even additional bindings for MSAL in Angular.

MSAL.js is a convenient library published by Microsoft for managing authentication using Azure Active Directory. It exposes two authentication experiences: popup or redirection.

At first I wanted to use popup as it seemed a far better UX, but I didn’t quite manage to get that right — popup got stuck every time after login was successful 😭 — so I eventually pledged to the redirect experience which in turn worked just fine 🤷

I then found myself stuck because I was redirecting users to a page where there was no available instance of UserAgentApplicationbe aware about it!

Before starting to code, go back to the App registration, look for Authentication blade and under Redirect URIs add a new entry of type Web with the URL of our codesandbox live preview, in this case: https://mqh4e.csb.app/#.

Enough chatter, let’s code!! 👨‍💻

Get back to codesandbox and create a file config/auth.js:

Here we create an instance of UserAgentApplication with our clientID and the authority which will grant the tokens based on the applicationtenantID.

For this example we setredirectUri and postLogoutRedirectUri to the current window location, at later stages of your application you might be interested on adding dedicated login and logout pages.

handleRedirectCallback is required for our redirect flow to properly work. We will manage any errors here (user canceled auth, user unauthorized…).

We also export the function getToken which will be used to obtain either id tokens or access tokens. For our use case we just need raw id tokens. the method acquireTokenSilent — which falls back to acquireTokenRedirect — requires to pass at least a config object with an scopes property. We will be passing User.Read which is the minimum permission we can set.

Now, let’s get to src/App.vue, import our auth instance, getToken function and put them to good use:

We just added a new section for a login button which will start the SSO process. Once the user is authorized, we will replace the button by their account name and meanwhile obtain an id token.

Notice this may imply yet another redirection! 😵

The id token obtained will be used to perform a fetch call to our backend service and retrieve the msg to display.

Sit back and relax, we are done playing frontend, we will now continue with the backend side of things.

Validating user tokens in backend

If you are not familiar with NestJS you should definitely give it a try!

For starters, we need something to build on top of. As with the frontend, we will be using codesandbox.io for it. There’s a container template already in place for us: https://codesandbox.io/s/github/nestjs/typescript-starter

With this we can start writing our AzureGuard. Guards are NestJS components which help us securing our controllers. In this particular case, we want to check that authorized requests include an Authorization header with Bearer token, being that token the id token we obtained on the frontend.

Then we can use the endpoints published at https://login.microsoftonline.com/<tenantID>/v2.0/.well-known/openid-configuration to validate the user sending the JWT as well as its signature and claims. But we don’t want to do all that ourselves, do we?

We will be using a couple of dependencies which will make our life easier. Follow the same process described above to install @nestjs/passport, passport and passport-azure-ad. Additionally you can install @types/passport-azure-ad as a dev dependency for completion and discovery.

passport is a great library for authentication, it’s fairly easy to understand and integrate in any NodeJS application. In particular, we will be using the NestJS bindings on top of it for seamless integration in our application.

passport-azure-ad contains two passport strategies that can be used for logging in users as well as validating their id tokens, and the latter is exactly what we want to do!

This particular strategy is called BearerStrategy and requires just a bit of configuration:

  • The client ID of our App registration
  • The endpoint where the OpenID configuration of our tenant is exposed – which we already mentioned just a few pixels above!

Let’s go ahead and implement AzureADStrategy with PassportStrategy and BearerStrategy.

Simple as 🥧!

We exported AzureGuard as AuthGuard('azure-ad') as it feels more DRY and simpler to apply to controllers.

Let’s now protect our controller with it.

Don’t forget to import PassportModule and AzureADStrategy as provider in the application module or else all our efforts will render useless!

Last but not least, enable CORS for our sandboxes to be able to interact, this can be easily done in NestJS from our entry file.

Our preview should now display a nice { "statusCode": 401, "error": "Unauthorized" }. If it does not, make sure to restart the container running the example. Open the Server Control Panel and hit Restart Server.

So far so good. It’s testing time 😎

Running the example

Open the live preview of our frontend in a new tab and click on Log in with SSO.

This will trigger the redirection to Microsoft where you will log in with your user and confirm the access requirements of the application.

Back in our application we will see a welcoming message and log out button.

After a slight delay, our application will require the id token for the fetch request and eventually perform the request to retrieve our backend message.

Since our token is valid, AzureGuard will let us hit the endpoint and return Hello World! message 🎉

Conclusion

This was a very basic introduction to authentication with Azure AD, there’s more things we can look into like adding Application Roles for different type of users. Feel free to play with it and make sure to check the code in GitHub.

--

--

RecuencoJones
adidoescode

Software Developer. 101st Frontend Division, ‘’Scripting Eagles’’. JavaScript Jedi. Avid learner. LEGO addict.