How to acquire and use an access token from Azure AD in a React & Spring app: a simple developer’s guide.

Alexei Ivanov
Sopra Steria Norge
Published in
4 min readFeb 22, 2022

Recently, I wrote an article on how to How to set up SSO authentication and RBAC with Azure AD in a React web app. There, I promised to publish another one where I describe the end-to-end process of acquiring and verifying, or validating, an access token from Microsoft Azure AD. Taking the previous article into account, this article assumes that you have a React frontend application written in TypeScript where you leverage the Microsoft Authentication Library (MSAL) in similar fashion. And you also have a Spring boot application that exposes several endpoints which you wish to protect. Of course, there are multiple ways in which you can address token acquisition and subsequent validation, but I, however, have chosen the acquireTokenSilent() approach described here. Yes, there are some limitations in the authentication/authorization approach described in my previous article — for instance the lack of any session termination (whether user-initiated, or automatic), or any security configuration regarding what we are about to do here. But since this is a simple guide to showcase how the following can be achieved, I will not cover those things.

As far as the Azure AD configuration is concerned you only need to add a scope in order to proceed, a process which I have detailed here. So, if you have already followed the steps described in my previous article, you are all set up. Let us jump straight to the code.

Frontend

Here, I will describe two approaches that you can choose between while working on this implementation. Then I will share my thoughts on the strengths and weaknesses of each of them.

In the sample application that I used, I have a utility class called api.ts from where all API calls are made. By the way, in this application I use axios, a popular, promise-based HTTP client written in Javascript. So, the code looks something like this:

Solution inspired by Nhu Kangasniemi, shared through bilot.group

Allow me to briefly explain what is happening here:

  • There is a basic setup of an axios instance, called api, which is used to call API endpoints at our backend application (which I will describe later).
  • Then there is a method called getToken(), which conducts authorization on the active account to make sure the caller actually has sufficient rights to the API endpoint he/she tries to access.
  • Finally, there is a method for each API call that is either wrapped by a call to getToken() method or not — all depending on if the call tries to access a protected resource.

Now, you may be wondering would it not be easier to have a single method and simply use axios request interceptor to do the calls? And rightly so! In most cases that would have been the proper way of doing it to avoid the hassle of having us code a function for each call. Matter of fact, that is the second approach I was going to talk about:

Adding this to the axios instance will intercept each request and perform an asynchronous function prior to sending it. In doing so, the requests will benefit from having AxiosRequestConfig possibly modified and attached to them. Here, we can do a check of the path that is being accessed to see if we should do a token request beforehand. However, if by the previous approach we could pick and choose which requests we wanted to wrap, this approach leaves no such alternative. Of course, in our case we were simply able to perform a string test, but what if the endpoints were more complex or different/multiple, disallowing any such easy test? Sure, it is possible to create a separate axios instance for each endpoint group and work around the problem that way. But how will that be different from writing a function for each separate call? Writing advanced path inspection methods can become a tedious task and doing an if-sentence for each and every API call is practically the same as putting them in separate functions. I will let you decide what is best for your application.

Backend

Now that we have had a look at our frontend implementation, let's take a look at our backend part. The backend application mentioned earlier is a typical Spring boot application with matching endpoints. So, what we are going to examine is the portion of this application where the token authenticity and validity is actually handled:

The solution is provided by Jim Xu, shared through stackoverflow.com.

As you can see I have put the validator in a separate class. In it, a single static method to validate the token, such that it can be used anywhere in the application. This method returns a boolean value: true, if given token is deemed to be valid — false otherwise. The class leverages auth0 library packages `jwks-rsa` and `java-jwt` to probe a token’s authenticity. It uses the `java.security.interfaces` package to extract its public key so that the token’s signature can be validated. Finally, a simple date validation is performed to see if it has not expired.

The provided solution has a known issue, especially when used in a containerised application, which can be worked around by implementing the suggested fix. It has a medium success rate, but definitely worth a try.

Conclusion

In this article, we have looked at how to acquire an access token from Azure AD inside a React application, and how to validate it within a Spring boot application. However, I would like to further stress the importance of certificates and secrets, which I have also mentioned in my previous article, and highly recommend configuring such option in your production projects. This concludes the article on how to secure a Spring application API with Azure AD. I hope the solutions discussed here will help you in any one of your projects.

--

--

Alexei Ivanov
Sopra Steria Norge

Alexei Ivanov is a senior fullstack developer and cloud engineer with Sopra Steria based in Oslo, Norway.