Authentication with Azure AD and React
By: Adrian Hynes
Tags: Azure Ad, Authentication, Jwt, 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.

Figure 1: Register an Application

Take note of the Application(Client ID).

In the Authentication section, tick the ID Token checkbox.

Tick the ID Token tickbox

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.js



// Msal Configurations

const config = {

auth: {

authority: '

clientId: '<Client ID>',

redirectUri: '

},

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) import { MsalAuthProvider, LoginType } from 'react-aad-msal';// Msal Configurationsconst config = {auth: {authority: ' https://login.microsoftonline.com/common' clientId: ' ',redirectUri: ' http://localhost:3000/callback' },cache: {cacheLocation: "localStorage",storeAuthStateInCookie: true};// Authentication Parametersconst authenticationParameters = {scopes: ['user.read'// Optionsconst 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.js import 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.js import logo from './logo.svg';

import './App.css';

import { authProvider } from './authProvider';

import { AzureAD, AuthenticationState } from 'react-aad-msal';



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="

target="_blank"

rel="noopener noreferrer"

>

Learn React

</a>

</header>

</div>

);

} function App() {return ( Only authenticated users can see me. ({login, logout, authenticationState, error, accountInfo}) => {switch (authenticationState) {case AuthenticationState.Authenticated:return ( Welcome, {accountInfo.account.userName}! {accountInfo.jwtIdToken} Logout );case AuthenticationState.Unauthenticated:return ( {error && An error occured during authentication, please try again! } Hey stranger, you look new! Login );case AuthenticationState.InProgress:return ( Authenticating... ); Edit src/App.js and save to reload. https://reactjs.org target="_blank"rel="noopener noreferrer"Learn React ); export default App;

Run it

npm start

Sign in with the user you created above

Sign in with the user you created above

Accept the ability to Sign on and Read your Profile

Display the Username and ID Token (for demo purposes)

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.

Decoded ID 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