DEV Community

Cover image for Implementing MSAL Authentication in a React App
Emma
Emma

Posted on

Implementing MSAL Authentication in a React App

Introduction

In my previous company, the first team I was involved in was the Personalised Incentives Team. I was the main frontend developer creating an internal portal that would allow us to set up and launch campaigns that triggered a promotional banner to display with a discount code when a customer met the criteria to be for that specific campaign. Initially, this was a very small frontend piece to remove the need for a developer to set up the campaigns directly in the backend.

As the project progressed, it became more high priority and the plan was to hand it over to the Commercial team who would be able to control the promotional campaigns as and when they needed. We needed to make sure that the portal was secure so only approved campaigns could be set up by authorised users and we could track who was accessing it. The last thing we’d want is someone setting up a campaign to give themselves 100% off a load of products!


MSAL vs ADAL

When we first set the portal up, we took the lead from similar projects and used react-adal for basic authentication. React-adal is an npm package that provides support for interacting with Microsoft’s Azure Active Directory Library (ADAL) using React; at that time, it was a suitable choice, unfortunately, when we later decided to extend the authentication to include roles based access, I discovered Microsoft was ending support for ADAL from June 2021 and replacing it with Microsoft Authentication Library (MSAL), which they recommended all developers used going forward.

It was strange to note that at the time we started to migrate from ADAL to MSAL, Microsoft’s main documentation championed the msal-react wrapper and used it in the React SPA tutorials, yet the msal-react docs explicitly stated it was not to be used in Production yet. We suspected they would announce the official release of msal-react closer to the time when the end of support for ADAL timeline began in June and we opted to go ahead given the lack of alternatives. Our theory proved correct; Microsoft made an announcement on 14th July 2021 officially launching msal-react and the warning was removed from the npm Readme.


Early Success

Our first approach was successful since the portal codebase was still relatively light; the Microsoft tutorials for integrating authentication with a React App were easy to follow, while at the same time, the jump from ADAL to MSAL was minimal, making much of the configuration familiar.

The Azure Portal can be confusing to navigate but there are a couple of key areas that are relevant to basic authentication and the docs are pretty clear about how to register a new application.

The App Registration section within Azure Active Directory is where the main details of a new app are registered. An authentication config file can be created in the app’s src folder using the authConfig.js template from the tutorials, customised with the Client Id (app id), Tenant Id (the overall area that a group of apps are registered under) and the Redirect URI (the page the app redirects to once the user has been authenticated) all found in the App Registration overview.

Once the app was registered in Azure and the auth config file added, I continued following the tutorial to create an instance of MSAL in the index.js using logic provided by the msal-browser package and wrapping the App component in the MsalProvider component that msal-react provides.

I created a Sign In Button component and used the provided login/logout functions from msal-react. These functions are useful and time saving but they can abstract away a lot of the understanding around how Azure authentication works. It took me some time to visualise exactly how our portal was interacting with Azure. Similarly, you can use the provided Authenticated/Unauthenticated components to wrap any components you need to conditionally render.

It’s fair to say this was all deceptively easy, though I had a suspicion it wouldn’t remain so. The main lesson I took away from this is the earlier you can integrate authentication into an app, the better and as I would later realise, if you can have your state management in order before that stage, it can only help.


The Documentation Rabbit Hole

There’s a lot of documentation around implementing MSAL to use with Microsoft’s Identity Platform using their Graph API but at the time I was working on it, not as much, and not as clear, around setting up roles based access using other APIs. Since Graph API appears to work out of the box with only a couple of lines in the auth config required, it doesn’t reflect the reality of authenticating with an independent API.

My experience of Microsoft products and services has been that there is a wealth of documentation but it can range from very good lightweight ‘How to’ guides to some incredibly dense technical articles. I often find it’s a slippery slope from one to the other and unsurprisingly, there were several times I fell down the MSAL documentation rabbit hole. As msal-react becomes more widely used, there may be a broader range of articles and information available that use different approaches, which should reduce some of the trawling through Microsoft docs.


Roles Based Access Control

Part of the reason we revisited our early authentication implementation was because we wanted to include roles based access control (RBAC). We had some functionality that wasn’t used by the majority of users of our portal but was relevant to some, RBAC allowed us to only show certain things to users with the appropriate role.

The logged in user’s role is accessible on the account object that Azure responds with after authenticating the user. It can also be accessed using the provided getActiveAccount and getAllAccounts functions.

I didn’t find creating and assigning roles in the Azure portal easy to understand, mainly since it takes place across two sections of the Azure Active Directory.

The creation and configuration of roles is done in the App Registration section of the Active Directory and only owners listed in the Owners section of App Registration can create roles.

It’s not possible to assign users to roles within App Registration, instead this is done in the Enterprise Applications section and only Configuration Owners listed in this section’s owners list can assign users to a role.


Authenticating with our API

Microsoft’s docs used their Graph API for most of the examples of how to authenticate with a Web API and this appears quite straightforward, likely for the same reason basic authentication is; Microsoft provides a lot of ready made functionality that gets things off the ground quicker. The cost, however, is that it’s not immediately clear how it works or how to customise it.

Something that caught us out was not realising we needed to register and configure our API in Azure separate to our app and grant it API permissions in the portal’s app registration. It was also unclear whether I needed to use the Azure idToken or accessToken in the headers of the API calls. Eventually, I found that when the Login function triggers, it sends an authentication request to Azure, which returns the idToken; this is Azure’s way of saying ‘This user has a legitimate account in this tenant space for this app’.

Once Azure has approved the user, another acquireSilentToken request can be sent with the API scope (the API ‘Application ID URI’ listed in the API’s app registration in Azure) to receive the accessToken and it’s this token that is then added into the API call headers to authenticate the requests.


Authentication Redux

Our implementation changed a few times as our app evolved; initially, it was quite a small application and didn’t require dedicated state management outside of what React Hooks provided, but as our ambition and ideas grew, we wanted to future proof it by adding Redux. This had a significant effect on the MSAL authentication and in looking back, I now think Context API would have been enough for the state management we needed.

Since adding Redux was already a large change, we opted not to move away from react-router to connected-react-router (formerly react-router-redux) to minimise the complexity and scale of the changes. Unfortunately, this led to an unconventional approach with our routing which impacted on the authentication.

In hindsight, it would have been better to handle the learning curve of both Redux and connected-react-router; getting Redux and msal-react to work with react-router probably took the same amount of time as adding in and getting to grips with connected-react-router.


Conclusion

Our authentication approach still required some refinement, particularly around routing and Redux. Like any new tech, there was a steep learning curve at the beginning but the docs provided a useful starting point and if the basic authentication had been all we needed, it would have been relatively easy to integrate. Microsoft’s docs appeared to favour their own Graph API so the biggest hurdle we had was authenticating the portal’s API requests through both Azure and our own API instead. It’s not strictly true to say Microsoft doesn’t also provide docs for this but given the volume of documentation that they have as a whole and the newness of msal-react at the time, it took longer to find relevant information for our particular situation. Overall, MSAL provided what we needed for authentication and roles based access control, and after the initial learning, was fairly user friendly and flexible.


Resources

Discussion (0)