Authentication with Azure AD and React

Overview

In this article, I’ll show you how easy it is to integrate Azure AD as an Authentication mechanism for your React Application.

We’ll use this authentication mechanism for future Articles.

Here’s a simplified high level sequence flow.

Prerequisites

Create a AD User for testing purposes

App Registration

Search for App Registration in Azure, and create a new App Registration. Fill in the fields below. For this example we’ll leave the callback URL as localhost over HTTP.

Take note of the Application(Client ID).

In the Authentication section, tick the ID Token checkbox.

React App

Download and Install NodeJS. Open a command prompt or terminal and create a react application.

npx create-react-app my-app
cd my-app

Install the AAD Microsoft Authentication Library for React

npm install react-aad-msal msal --save

Add the following authProvider.js file, replacing the placeholders for Client ID with the one we generated above

//my-app/src/authProvider.jsimport { MsalAuthProvider, LoginType } from 'react-aad-msal';

// Msal Configurations
const config = {
auth: {
authority: 'https://login.microsoftonline.com/common',
clientId: '<Client ID>',
redirectUri: 'http://localhost:3000/callback'
},
cache: {
cacheLocation: "localStorage",
storeAuthStateInCookie: true
}
};

// Authentication Parameters
const authenticationParameters = {
scopes: [
'user.read'
]
}

// Options
const options = {
loginType: LoginType.Popup,
tokenRefreshUri: window.location.origin + '/auth.html'
}

export const authProvider = new MsalAuthProvider(config, authenticationParameters, options)

Update index.js with the below. This will just prompt for authentication straight away when you navigate to your app

//my-app/src/index.jsimport React from 'react';
import ReactDOM from 'react-dom';
import { AzureAD } from 'react-aad-msal';

import App from './App';
import { authProvider } from './authProvider';

ReactDOM.render(
<AzureAD provider={authProvider} forceLogin={true}>
<App />
</AzureAD>,
document.getElementById('root'),
);

Update App.js with the below. We’re just adding an Auth section to the sample provided to display the username as well as the actual JWT token for this tutorial purposes.

//my-app/src/App.jsimport logo from './logo.svg';
import './App.css';
import { authProvider } from './authProvider';
import { AzureAD, AuthenticationState } from 'react-aad-msal';
function App() {

return (

<div className="App">
<AzureAD provider={authProvider}>
<span>Only authenticated users can see me.</span>
</AzureAD>

<AzureAD provider={authProvider} forceLogin={true}>
{
({login, logout, authenticationState, error, accountInfo}) => {
switch (authenticationState) {
case AuthenticationState.Authenticated:
return (
<p>
<span>Welcome, {accountInfo.account.userName}!</span>
<span>{accountInfo.jwtIdToken}</span>
<button onClick={logout}>Logout</button>
</p>
);
case AuthenticationState.Unauthenticated:
return (
<div>
{error && <p><span>An error occured during authentication, please try again!</span></p>}
<p>
<span>Hey stranger, you look new!</span>
<button onClick={login}>Login</button>
</p>
</div>
);
case AuthenticationState.InProgress:
return (<p>Authenticating...</p>);
}
}
}
</AzureAD>
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;

Run it

npm start

The ID token above can now be used as a bearer token when talking to a services backend. Here you can validate the ID token so you can then trust the claims in this token.

You can also invite users as guests to your Organisation and they can also authenticate to your Application.

Validating ID Token

In future articles we’ll use a java library to validate our JWT token, but for reference purposes you can do the following…

Extract the particular public key from the header kid claim in the JWT token e.g.

“kid”: “iBjL1Rcqzhiy4fpxIxdZqohM2Yk”

Next navigate to the following URL which contains various openid metadata, we’re interested in the “jwks_uri” field. This contains the list of public signing keys.

https://login.microsoftonline.com/{tenant}/.well-known/openid-configuration?appid={client id}

Now if we navigate to that address (jwks_uri), we’ll get a list of public keys.
https://login.microsoftonline.com/{tenant}/discovery/keys?appid={client is}

From here, we will find our kid (Key ID) from above and extract the corresponding public key located in the field “x5c” (x509 cert)

Now add the following wrappers around this key e.g.

-----BEGIN CERTIFICATE-----
public key
-----END CERTIFICATE-----

Open up jwt.io, paste in our JWT token and in the verify signature section, plug in the above and you should get a Signature Verified output

References

Cloud Platform Architect. Opinions and articles on medium are my own.