Guide de migration de MSAL v1 vers @azure/msal-react et @azure/msal-browser

Cet article fournit une vue d’ensemble de la migration de MSAL v1 vers @azure/msal-react et @azure/msal-browser. Nous recommandons la migration pour améliorer les performances et améliorer la sécurité avec le flux de code d’autorisation avec PKCE et l’accès conditionnel. De plus, la prise en charge des applications monopages est améliorée.

Prerequisites

  • Un compte Azure avec un abonnement actif. Créez un compte gratuitement.
  • Une application existante enregistrée dans votre locataire Microsoft Entra.

Mise à jour de l’inscription de votre application

La bibliothèque @azure/msal-react est une encapsulation autour de @azure/msal-browser, qui implémente le flux de code d’autorisation avec PKCE. Il s’agit d’une mise à jour significative de la bibliothèque MSAL v1 qui implémente le flux implicite.

Vous devrez créer un nouvel enregistrement d’application ou mettre à jour un enregistrement existant pour utiliser le nouveau type redirectUri « SPA ». Reportez-vous à Application monopage : Enregistrement d’application pour plus d’informations.

Installation de @azure/msal-react et de @azure/msal-browser

@azure/msal-react ainsi que sa dépendance homologue @azure/msal-browser peuvent être installés depuis npm. Il est important de désinstaller votre ancien package MSAL. Ouvrez un terminal et exécutez les commandes suivantes.

npm uninstall msal
npm install @azure/msal-react @azure/msal-browser

Mise à niveau à partir de react-aad-msal

Si votre application utilise actuellement React Microsoft Entra MSAL pour l’authentification et que vous cherchez à migrer vers @azure/msal-react cette section décrit les différences entre les deux bibliothèques et certaines des modifications que vous devez apporter. React Microsoft Entra MSAL est une bibliothèque tierce, et MSAL React a été conçu de A à Z ; il peut donc exister certains cas limites qui ne sont pas couverts ou pris en charge par MSAL React.

Voici les fonctionnalités prises en charge dans react-aad-msal mais non prises en charge dans @azure/msal-react :

  • Vérification de l’expiration d’IdToken avant le rendu des composants protégés et actualisation automatique d’IdTokens expirés
  • Prise en charge native du store Redux (alternative ci-dessous)

Pour les autres cas possibles avec react-aad-msal, mais qui ne sont plus possibles avec @azure/msal-react, ouvrez un ticket dans le dépôt GitHub microsoft-authentication-library-for-js.

Initialisation

Dans react-aad-msal vous initialisez votre instance MSAL en créant un MsalAuthProvider objet transmis ultérieurement au AzureAD composant.

import { MsalAuthProvider } from "react-aad-msal";

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

Dans @azure/msal-react, vous initialisez votre instance MSAL à l’aide de PublicClientApplication, exporté depuis @azure/msal-browser, qui est ensuite transmise au composant MsalProvider, exporté depuis @azure/msal-react. Les options de configuration sont globalement similaires entre msal et @azure/msal-browser ; toutefois, vous pouvez consulter le type de configuration pour obtenir les options de configuration les plus récentes.

Les paramètres authenticationParameters et options utilisés dans react-aad-msal ne sont pas utilisés dans @azure/msal-react, bien qu’il soit possible d’obtenir des fonctionnalités similaires au niveau de composants individuels. Cela sera expliqué plus loin dans ce document.

@azure/msal-react utilise l’API de contexte React pour rendre PublicClientApplication et l’état d’authentification disponibles dans toute l’arborescence de composants.

import { PublicClientApplication } from "@azure/msal-browser";
import { MsalProvider } from "@azure/msal-react";

const pca = new PublicClientApplication(config);

function App() {
    return (
        <MsalProvider instance={pca}>
            <YourAppComponents />
        </MsalProvider>
    );
}

Remarques générales sur le MsalProvider composant :

  • Tous les composants qui ont besoin d’accéder à l’état d’authentification ou aux hooks/composants exposés par @azure/msal-react doivent avoir un MsalProvider plus haut dans l’arborescence des composants. Il est donc recommandé que MsalProvider soit rendu aussi près que possible de la racine.
  • Votre application ne doit pas afficher plus de 1 MsalProvider composant sur une page donnée.
  • Nous vous déconseillons d’initialiser PublicClientApplication à l’intérieur d’un composant en raison du risque de nouveaux rendus

Protection de vos composants

Dans react-aad-msal, les composants sont protégés à l’aide du composant AzureAD ou du HOC withAuthentication, qui enveloppe votre composant avec AzureAD en interne. Le AzureAD composant affiche uniquement les composants enfants si un utilisateur est authentifié et initie éventuellement une connexion si aucun utilisateur n’est authentifié. Les options utilisées pour la connexion (par exemple, les scopes, l’utilisation d’une fenêtre contextuelle ou d’une redirection, etc.) sont spécifiées plus haut, lors de la création de la prop authProvider.

import { MsalAuthProvider } from "react-aad-msal";

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

function App() {
    return (
        <AzureAD provider={authProvider} forceLogin={true}>
            <span>Only authenticated users can see me.</span>
        </AzureAD>
    );
}

@azure/msal-react, d’autre part, donne aux développeurs plus de contrôle sur ce qu’ils veulent afficher à qui.

  • Le AuthenticatedTemplate composant affiche les enfants si un utilisateur est authentifié
  • Le UnauthenticatedTemplate composant affiche les enfants si un utilisateur n’est pas authentifié
  • Le MsalAuthenticationTemplate composant lance automatiquement une connexion si un utilisateur n’est pas authentifié, puis affiche les enfants une fois qu’un utilisateur est authentifié.
import { PublicClientApplication, InteractionType } from "@azure/msal-browser";
import { MsalProvider, AuthenticatedTemplate, UnauthenticatedTemplate, MsalAuthenticationTemplate } from "@azure/msal-react";

const pca = new PublicClientApplication(config);

function App() {
    return (
        <MsalProvider instance={pca}>
            <AuthenticatedTemplate>
                <span>Only authenticated users can see me.</span>
            </AuthenticatedTemplate>
            <UnauthenticatedTemplate>
                <span>Only unauthenticated users can see me.</span>
            </UnauthenticatedTemplate>
            <MsalAuthenticationTemplate interactionType={InteractionType.Popup} authenticationRequest={request}>
                <span>Only authenticated users can see me. Unauthenticated users will get a popup asking them to login first.</span>
            </MsalAuthenticationTemplate>
        </MsalProvider>
    );
}

En outre, si vous préférez adopter une approche @azure/msal-react basée sur des crochets, vous pouvez utiliser plusieurs crochets pour obtenir des résultats similaires. Il s’agit simplement d’exemples de base, et vous pouvez vous référer aux hooks MSAL React pour plus d’informations.

import { PublicClientApplication, InteractionType } from "@azure/msal-browser";
import { MsalProvider, useIsAuthenticated, useMsalAuthentication } from "@azure/msal-react";

const pca = new PublicClientApplication(config);

function App() {
    return (
        <MsalProvider instance={pca}>
            <ExampleComponent />
        </MsalProvider>
    );
}

function ExampleComponent() {
    const isAuthenticated = useIsAuthenticated();
    const { error } = useMsalAuthentication(InteractionType.Popup, request); // Will initiate a popup login if user is unauthenticated

    if (isAuthenticated) {
        return <span>Only authenticated users can see me.</span>
    } else if (error) {
        return <span>An error occurred during login!</span>
    } else {
        return <span>Only unauthenticated users can see me.</span>
    }
}

Acquisition d’un jeton d’accès

react-aad-msal expose une getAccessToken méthode que vous pouvez utiliser pour obtenir un jeton d’accès avant d’appeler une API.

import { MsalAuthProvider } from "react-aad-msal";

const authProvider = new MsalAuthProvider(config, authenticationParameters, options);
const accessToken = authProvider.getAccessToken();

Lorsque vous utilisez @azure/msal-react et @azure/msal-browser, vous appellerez acquireTokenSilent sur l’instance PublicClientApplication.

Si vous devez obtenir un jeton d’accès à l’intérieur d’un composant ou d’un hook qui se trouve sous MsalProvider vous pouvez utiliser le useMsal hook pour obtenir les objets dont vous avez besoin.

import { useState } from "react";
import { useMsal } from "@azure/msal-react";
import { InteractionRequiredAuthError } from "@azure/msal-browser";

function useAccessToken() {
    const { instance, accounts } = useMsal();
    const [accessToken, setAccessToken] = useState(null);

    if (accounts.length > 0) {
        const request = {
            scopes: ["User.Read"],
            account: accounts[0]
        };
        instance.acquireTokenSilent(request).then(response => {
            setAccessToken(response.accessToken);
        }).catch(error => {
            // acquireTokenSilent can fail for a number of reasons, fallback to interaction
            if (error instanceof InteractionRequiredAuthError) {
                instance.acquireTokenPopup(request).then(response => {
                    setAccessToken(response.accessToken);
                });
            }
        });
    }

    return accessToken;
}

Si vous devez obtenir un jeton d’accès en dehors du contexte de MsalProvider vous pouvez utiliser l’instance PublicClientApplication directement et appeler getAllAccounts() pour obtenir l’objet de compte.

Important

Tentez uniquement une acquisition silencieuse de jeton en dehors du contexte de MsalProvider. Vous ne devez pas appeler une méthode interactive (redirection ou fenêtre contextuelle) en dehors du contexte de MsalProvider.

L’exemple ci-dessous montre l’initialisation de PublicClientApplication à des fins de démonstration. PublicClientApplication ne doit être initialisé qu’une seule fois par chargement de page et vous devez utiliser la même instance ici que celle que vous fournissez MsalProvider.

import { PublicClientApplication } from "@azure/msal-browser";

const pca = new PublicClientApplication(config);
const accounts = pca.getAllAccounts();

async function getAccessToken() {
    if (accounts.length > 0) {
        const request = {
            scopes: ["User.Read"],
            account: accounts[0]
        }
        const accessToken = await pca.acquireTokenSilent(request).then((response) => {
            return response.accessToken;
        }).catch(error => {
            // Do not fallback to interaction when running outside the context of MsalProvider. Interaction should always be done inside context.
            console.log(error);
            return null;
        });

        return accessToken;
    }

    return null;
}

Acquisition d’un jeton d’ID

react-aad-msal expose une getIdToken fonction pour obtenir ou renouveler un idToken.

import { MsalAuthProvider } from "react-aad-msal";

const authProvider = new MsalAuthProvider(config, authenticationParameters, options);
const token = await authProvider.getIdToken();
const idToken = token.idToken.rawIdToken;

Vous connaissez peut-être aussi le schéma consistant à demander votre clientId comme seule portée afin d’obtenir un idToken. Il ne s’agit plus d’un modèle pris en charge dans @azure/msal-browser.

Dans @azure/msal-react et @azure/msal-browser tous les appels de jeton retournent à la fois un jeton d’accès et un jeton d’ID et tous les renouvellements de jetons d’accès renouvellent également le jeton d’ID.

Si vous devez obtenir un jeton d’ID à l’intérieur d’un composant ou d’un hook qui se trouve sous MsalProvider vous pouvez utiliser le useMsal hook pour obtenir les objets dont vous avez besoin.

import { useState } from "react";
import { useMsal } from "@azure/msal-react";

function useIdToken() {
    const { instance, accounts } = useMsal();
    const [idToken, setIdToken] = useState(null);

    if (accounts.length > 0) {
        const request = {
            scopes: ["openid"],
            account: accounts[0]
        };
        instance.acquireTokenSilent(request).then(response => {
            setIdToken(response.idToken);
        }).catch(error => {
            // acquireTokenSilent can fail for a number of reasons, fallback to interaction
            if (error instanceof InteractionRequiredAuthError) {
                instance.acquireTokenPopup(request).then(response => {
                    setIdToken(response.idToken);
                });
            }
        });
    }

    return idToken;
}

Si vous devez obtenir un jeton d’ID en dehors du contexte de MsalProvider vous pouvez utiliser l’instance PublicClientApplication directement et appeler getAllAccounts() pour obtenir l’objet de compte.

Important

Effectuez uniquement l’acquisition silencieuse de jetons en dehors du contexte de MsalProvider. Vous ne devez pas appeler une méthode interactive (redirection ou fenêtre contextuelle) en dehors du contexte de MsalProvider.

L’exemple ci-dessous montre l’initialisation de PublicClientApplication à des fins de démonstration. PublicClientApplication ne doit être initialisé qu’une seule fois par chargement de page et vous devez utiliser la même instance ici que celle que vous fournissez MsalProvider.

import { PublicClientApplication } from "@azure/msal-browser";

const pca = new PublicClientApplication(config);
const accounts = pca.getAllAccounts();

async function getIdToken() {
    if (accounts.length > 0) {
        const request = {
            scopes: ["openid"],
            account: accounts[0]
        }
        const idToken = await pca.acquireTokenSilent(request).then((response) => {
            return response.idToken;
        }).catch (error => {
            // Do not fallback to interaction when running outside the context of MsalProvider. Interaction should always be done inside context.
            console.log(error);
            return null;
        });

        return idToken
    }

    return null;
}

Mise à jour de l’intégration du magasin redux / réaction aux événements

react-aad-msal fournissait une intégration prête à l’emploi avec un store Redux en déclenchant des actions lorsque des événements tels que la connexion ou la déconnexion se produisaient. @azure/msal-react ne fournit pas cette fonctionnalité, cependant, des fonctionnalités similaires peuvent être obtenues à l’aide de l’API d’événement exposée par @azure/msal-browser.

Vous pouvez inscrire un rappel d’événement qui sera appelé chaque fois qu’un événement est diffusé (par exemple LOGIN_SUCCESS). Votre fonction de rappel peut inspecter l’événement et faire quelque chose avec la charge utile. Si vous souhaitez continuer à utiliser votre store Redux existant, vous pouvez enregistrer une fonction de rappel pour un événement qui envoie des actions à votre store.

import { PublicClientApplication, EventType } from "@azure/msal-browser";
import { store } from "your-redux-store-implementation";

const msalInstance = new PublicClientApplication(config);

const callbackId = msalInstance.addEventCallback((message: EventMessage) => {
    if (message.eventType === EventType.LOGIN_SUCCESS) {
        store.dispatchAction({type: "AAD_LOGIN_SUCCESS", payload: message.payload});
    }
});

Les charges utiles peuvent différer entre msal v1 et @azure/msal-browser vous devrez peut-être effectuer des ajustements si votre application s’appuie sur des champs spécifiques ou la forme d’objet. Nos typesdocs contiennent la liste les plus à jour des types d’événements et des types de charge utile . Vous pouvez trouver le mappage entre les deux dans la documentation d’événement.

Voir aussi