Průvodce migrací z MSAL v1 do @azure/msal-react a @azure/msal-browser

Tento článek obsahuje přehled o migraci z MSAL verze 1 do @azure/msal-react a @azure/msal-browser. Doporučujeme migraci kvůli vyššímu výkonu a lepšímu zabezpečení pomocí toku autorizačního kódu s PKCE a podmíněným přístupem. Kromě toho je k dispozici lepší podpora jednostránkových aplikací.

Předpoklady

  • Účet Azure s aktivním předplatným. Vytvoření účtu zdarma
  • Existující aplikace zaregistrovaná ve vašem tenantovi Microsoft Entra.

Aktualizace registrace aplikace

Knihovna @azure/msal-react je obálkou knihovny @azure/msal-browser, která implementuje tok autorizačního kódu s PKCE. Jedná se o významnou aktualizaci z knihovny MSAL v1, která implementuje implicitní tok.

Budete muset vytvořit novou registraci aplikace nebo aktualizovat existující aplikaci tak, aby používala nový redirectUri typ SPA. Další informace najdete v jednostráňové aplikaci: Registrace aplikace .

Instalace @azure/msal-react a @azure/msal-browser

Z npm lze nainstalovat jak @azure/msal-react, tak i její peer závislost @azure/msal-browser. Je důležité odinstalovat starý balíček MSAL. Otevřete terminál a spusťte následující příkazy.

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

Upgrade z react-aad-msal

Pokud vaše aplikace aktuálně používá React Microsoft Entra MSAL k ověřování a chcete migrovat do @azure/msal-react této části, zobrazí se rozdíly mezi těmito dvěma knihovnami a některými změnami, které je potřeba provést. React Microsoft Entra MSAL je knihovna třetích stran a služba MSAL React byla vytvořena od základů, mohou existovat některé hraniční případy, které nejsou pokryty nebo nejsou podporovány službou MSAL React.

Následující funkce jsou podporovány v react-aad-msal, ale nejsou podporovány v @azure/msal-react:

  • Ověření vypršení platnosti tokenu IdToken před zobrazením chráněných komponent a automatické obnovení prošlých tokenů IdToken
  • Podpora pro Redux store ihned po instalaci (alternativní řešení níže)

V ostatních případech, které byly možné s react-aad-msal, ale s @azure/msal-react už nejsou možné, založte problém v úložišti GitHub microsoft-authentication-library-for-js.

Inicializace

V react-aad-msal inicializujete instanci MSAL vytvořením objektu MsalAuthProvider, který se později předá komponentě AzureAD.

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

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

V @azure/msal-react inicializujete instanci MSAL pomocí PublicClientApplication, exportovaného z @azure/msal-browser, která je poté předána komponentě MsalProvider, exportované z @azure/msal-react. Možnosti konfigurace jsou do značné míry podobné mezi msal a @azure/msal-browser, ale můžete odkazovat na typ konfigurace pro nejaktuálnější možnosti konfigurace.

Parametry authenticationParameters a options použité v react-aad-msal se v @azure/msal-react nepoužívají, ačkoli podobné funkčnosti lze dosáhnout u jednotlivých komponent. To bude vysvětleno dále v tomto dokumentu.

@azure/msal-react používá React Context API, aby zpřístupnil PublicClientApplication a stav ověřování v celém vašem stromu komponent.

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

Obecné poznámky ke komponentě MsalProvider :

  • Všechny komponenty, které potřebují přístup ke stavu autentizace nebo k hookům či komponentám zpřístupněným komponentou @azure/msal-react, musí mít výše ve stromu komponent prvek MsalProvider, proto se doporučuje vykreslit MsalProvider co nejblíže ke kořeni.
  • Aplikace by neměla na žádné stránce vykreslit více než 1 MsalProvider komponentu.
  • Nedoporučujeme inicializovat PublicClientApplication v komponentě kvůli možnosti opakovaného vykreslení.

Ochrana komponent

Komponenty v react-aad-msal jsou chráněny pomocí komponenty AzureAD nebo HOC withAuthentication, který interně obaluje vaši komponentu pomocí AzureAD. Komponenta AzureAD vykreslí podřízené komponenty pouze v případě, že je uživatel ověřený, a volitelně zahájí přihlášení, pokud se žádný uživatel neověří. Možnosti používané pro přihlášení (např. scopes, zda se má použít vyskakovací okno nebo přesměrování atd.) se zadávají dříve při vytváření propu 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, na druhé straně dává vývojářům větší kontrolu nad tím, co chtějí zobrazit komu.

  • Komponenta AuthenticatedTemplate vykreslí potomky, pokud je uživatel ověřen.
  • Komponenta UnauthenticatedTemplate vykreslí podřízené položky, pokud uživatel není ověřený.
  • Komponenta MsalAuthenticationTemplate automaticky zahájí přihlášení, pokud uživatel není přihlášený, a jakmile je přihlášený, vykreslí podřízené prvky.
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>
    );
}

Kromě toho, pokud dáváte přednost přístupu @azure/msal-react založenému na hácích, nabízí několik háků, které můžete použít k dosažení podobných výsledků. Toto jsou jen některé základní příklady a další informace najdete v hácích MSAL React .

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

Získání přístupového tokenu

react-aad-msal zveřejňuje metodu getAccessToken , kterou můžete použít k získání přístupového tokenu před voláním rozhraní API.

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

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

Při použití @azure/msal-react a @azure/msal-browser zavoláte acquireTokenSilent na instanci PublicClientApplication.

Pokud potřebujete získat přístupový token uvnitř komponenty nebo háku, který je pod MsalProvider ním, můžete pomocí useMsal háku získat potřebné objekty.

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

Pokud potřebujete získat přístupový token mimo kontext MsalProvider , můžete použít PublicClientApplication instanci přímo a volat getAllAccounts() k získání objektu účtu.

Important

O tiché získání tokenu se pokoušejte pouze mimo kontext MsalProvider. Neměli byste volat interaktivní metodu (přesměrování nebo vyskakovací okno) mimo kontext MsalProvider.

Následující příklad ukazuje inicializaci PublicClientApplication pro demonstrační účely. PublicClientApplication by se měla inicializovat pouze jednou při načtení stránky a zde byste měli použít stejnou instanci, kterou předáváte do 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;
}

Získání tokenu ID

react-aad-msal zpřístupnil getIdToken funkci pro získání nebo obnovení idTokenu.

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

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

Možná také znáte postup, kdy požadujete váš clientId jako jediný rozsah, abyste získali idToken. Tento model již není podporován v @azure/msal-browsersouboru .

V @azure/msal-react a @azure/msal-browser všechna volání tokenů vrátí jak přístupový token, tak i ID token, a všechna obnovení přístupového tokenu také obnoví ID token.

Pokud potřebujete získat token ID uvnitř komponenty nebo háku, který je pod MsalProvider ním, můžete pomocí háku useMsal získat potřebné objekty.

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

Pokud potřebujete získat token ID mimo kontext MsalProvider , můžete použít PublicClientApplication instanci přímo a volat getAllAccounts() k získání objektu účtu.

Important

O tiché získání tokenu se pokoušejte pouze mimo kontext MsalProvider. Neměli byste volat interaktivní metodu (přesměrování nebo vyskakovací okno) mimo kontext MsalProvider.

Následující příklad ukazuje inicializaci PublicClientApplication pro demonstrační účely. PublicClientApplication by se měla inicializovat pouze jednou při načtení stránky a zde byste měli použít stejnou instanci, jakou předáváte do 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;
}

Aktualizace integrace úložiště redux / reakce na události

react-aad-msal poskytoval již v základu integraci s úložištěm Redux tím, že odesílal akce při událostech, jako je přihlášení nebo odhlášení. @azure/msal-react neposkytuje tuto funkci, ale podobné funkce lze dosáhnout pomocí rozhraní API událostí zveřejněného @azure/msal-browser.

Můžete zaregistrovat zpětné volání pro událost, které se vyvolá pokaždé, když je událost odvysílána (např. LOGIN_SUCCESS). Vaše funkce zpětného volání může zkoumat událost a něco udělat s datovou částí. Pokud chcete pokračovat v používání existujícího úložiště redux, můžete zaregistrovat zpětné volání události, které odesílá akce do úložiště.

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

Datové struktury se mohou mezi msal v1 a @azure/msal-browser lišit, takže možná budete muset provést několik úprav, pokud vaše aplikace spoléhá na konkrétní pole nebo strukturu objektu. V naší dokumentaci TypeDoc najdete nejaktuálnější seznam typů událostí a typů payloadů a mapování mezi nimi najdete v dokumentaci k událostem.

Viz také