Migreringsguide från MSAL v1 till @azure/msal-react och @azure/msal-browser

Den här artikeln innehåller en översikt över migrering från MSAL v1 till @azure/msal-react och @azure/msal-browser. Vi rekommenderar migrering för bättre prestanda och bättre säkerhet med auktoriseringskodflödet med PKCE och villkorlig åtkomst. Dessutom finns det bättre stöd för ensidesprogram.

Förutsättningar

  • Ett Azure-konto med en aktiv prenumeration. Skapa ett konto kostnadsfritt
  • Ett befintligt program som är registrerat i din Microsoft Entra klientorganisation.

Uppdatera din appregistrering

Biblioteket @azure/msal-react är en omslutning runt @azure/msal-browser vilken implementerar auktoriseringskodflödet med PKCE. Det här är en betydande uppdatering från MSAL v1-biblioteket som implementerar implicit flöde.

Du måste skapa en ny appregistrering eller uppdatera en befintlig för att använda den nya redirectUri typen "SPA". Mer information finns i Ensidesprogram: Appregistrering .

Installera @azure/msal-react och @azure/msal-browser

Både @azure/msal-react och dess peer-beroende @azure/msal-browser kan installeras från npm. Det är viktigt att avinstallera ditt gamla MSAL-paket. Öppna en terminal och kör följande kommandon.

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

Uppgradera från react-aad-msal

Om appen för närvarande använder React Microsoft Entra MSAL för autentisering och du vill migrera till @azure/msal-react det här avsnittet beskrivs skillnaderna mellan de två biblioteken och några av de ändringar du behöver göra. React Microsoft Entra MSAL är ett bibliotek från tredje part och MSAL React skapades från grunden, det kan finnas vissa gränsfall som inte omfattas eller inte stöds av MSAL React.

Följande är funktioner som stöds där react-aad-msal stöds inte i @azure/msal-react:

  • Verifiera att IdToken upphör att gälla innan skyddade komponenter återges och automatisk uppdatering av utgångna IdTokens
  • Out of the box-stöd för Redux Store (alternativ nedan)

För andra fall som är möjliga med react-aad-msal men inte längre möjliga med @azure/msal-react, öppna ett ärende i GitHub-repot microsoft-authentication-library-for-js.

Initialisering

I react-aad-msal initierar du MSAL-instansen genom att skapa ett MsalAuthProvider objekt som senare skickas till komponenten AzureAD .

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

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

I @azure/msal-react initierar du msal-instansen med exporterad PublicClientApplication från @azure/msal-browser som sedan skickas ned till komponenten MsalProvider som exporteras från @azure/msal-react. Konfigurationsalternativen liknar i stort sett mellan msal och @azure/msal-browser, men du kan referera till konfigurationstypen för de senaste konfigurationsalternativen.

Parametrarna authenticationParameters och options som används i react-aad-msal används inte i @azure/msal-react, men liknande funktioner kan uppnås på enskilda komponenter. Detta förklaras senare i det här dokumentet.

@azure/msal-react använder React Context API för att göra PublicClientApplication och autentiseringstillstånd tillgängligt i hela komponentträdet.

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>
    );
}

Allmänna anteckningar om komponenten MsalProvider :

  • Alla komponenter som behöver åtkomst till autentiseringstillstånd eller krokar/komponenter som exponeras av @azure/msal-react måste ha en MsalProvider högre upp i komponentträdet, därför rekommenderas att MsalProvider återges så nära roten som möjligt.
  • Appen får inte rendera fler än 1 MsalProvider komponent på en viss sida.
  • Vi rekommenderar inte att du initierar PublicClientApplication inuti en komponent på grund av möjligheten att åter rendera

Skydda dina komponenter

I react-aad-msal skyddas komponenter med AzureAD-komponenten eller HOC-komponenten withAuthentication, som omger din komponent med AzureAD bakom kulisserna. Komponenten AzureAD renderar endast underordnade komponenter om en användare autentiseras och eventuellt initierar en inloggning om ingen användare autentiseras. De alternativ som används för inloggning (t.ex. omfång, om du vill använda popup-fönster eller omdirigering osv.) anges tidigare när du skapar rekvisitan 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, å andra sidan, ger utvecklare mer kontroll över vad de vill visa för vem.

  • AuthenticatedTemplate-komponenten renderar underordnade element om en användare är autentiserad
  • Komponenten UnauthenticatedTemplate renderar underordnade om en användare inte autentiseras
  • MsalAuthenticationTemplate-komponenten startar automatiskt en inloggning om en användare inte är autentiserad och visar sedan underordnade element när användaren har autentiserats.
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>
    );
}

Dessutom, om du föredrar att använda en hook-baserad metod, tillhandahåller @azure/msal-react flera hooks som du kan använda för att åstadkomma liknande resultat. Det här är bara några grundläggande exempel och du kan läsa mer om MSAL React-krokar .

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>
    }
}

Hämta en åtkomsttoken

react-aad-msal exponerar en getAccessToken metod som du kan använda för att hämta en åtkomsttoken innan du anropar ett API.

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

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

När du använder @azure/msal-react och @azure/msal-browser du kommer att anropa acquireTokenSilent på instansen PublicClientApplication .

Om du behöver få en åtkomsttoken inuti en komponent eller krok som bor under MsalProvider kan du använda kroken useMsal för att få de objekt du behöver.

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;
}

Om du behöver hämta en åtkomsttoken utanför kontexten MsalProvider kan du använda instansen PublicClientApplication direkt och anropa getAllAccounts() för att hämta kontoobjektet.

Important

Försök endast att hämta en tyst token utanför kontexten för MsalProvider. Du bör inte anropa en interaktiv metod (omdirigering eller popup) utanför kontexten för MsalProvider.

Exemplet nedan visar initiering av PublicClientApplication i demonstrationssyfte. PublicClientApplication bör endast initieras en gång per sidinläsning och du bör använda samma instans här som du anger för 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;
}

Hämta en ID-token

react-aad-msal gjorde en getIdToken-funktion tillgänglig för att hämta eller förnya en idToken.

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

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

Du kanske också känner igen mönstret att begära clientId som den enda scopet för att hämta ett idToken. Det här är inte längre ett mönster som stöds i @azure/msal-browser.

I @azure/msal-react och @azure/msal-browser alla tokenanrop returnerar både en åtkomsttoken och en ID-token och alla förnyelser av åtkomsttoken förnyar även ID-token.

Om du behöver få en ID-token inuti en komponent eller krok som bor under MsalProvider kan du använda kroken useMsal för att få de objekt du behöver.

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;
}

Om du behöver hämta en ID-token utanför kontexten MsalProvider för kan du använda instansen PublicClientApplication direkt och anropa getAllAccounts() för att hämta kontoobjektet.

Important

Försök endast med tyst tokenhämtning utanför kontexten för MsalProvider. Du bör inte anropa en interaktiv metod (omdirigering eller popupfönster) utanför kontexten för MsalProvider.

Exemplet nedan visar initiering av PublicClientApplication i demonstrationssyfte. PublicClientApplication bör endast initieras en gång per sidinläsning och du bör använda samma instans här som du anger för 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;
}

Uppdatera redux-butiksintegrering/reagera på händelser

react-aad-msal erbjöd färdig integrering med en Redux store genom att skicka actions vid händelser som in- eller utloggning. @azure/msal-react tillhandahåller inte den här funktionen, men liknande funktioner kan uppnås med hjälp av händelse-API: et som exponeras av @azure/msal-browser.

Du kan registrera ett händelseåteranrop som anropas varje gång en händelse sänds (t.ex. LOGIN_SUCCESS). Din återanropsfunktion kan undersöka händelsen och göra något med nyttodata. Om du vill fortsätta använda din befintliga Redux-store kan du registrera ett händelseåteranrop som dispatchar actions till din 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});
    }
});

Nyttolasten kan skilja sig åt mellan msal v1 och @azure/msal-browser därför kan du behöva göra vissa justeringar om programmet förlitar sig på specifika fält eller objektformen. Våra typedocs innehåller den senaste listan över händelsetyper och nyttolasttyper och du kan hitta mappningen mellan de två i händelsedokumentet.

Se även