Errors

Erreurs d'authentification de la configuration du navigateur

stubbed_public_client_application_called

Message d’erreur : l’instance stub de l’application cliente publique a été appelée. Si vous utilisez msal-react, vérifiez que le contexte n'est pas utilisé sans fournisseur.

Consultez Erreurs msal-react

BrowserAuthErrors

Interaction_en_cours

Message d’erreur : l’interaction est en cours. Vérifiez que cette interaction a été effectuée avant d’appeler une API interactive.

Cette erreur est levée lorsqu’une API interactive (loginPopup, , loginRedirect, acquireTokenPopupacquireTokenRedirect) est appelée alors qu’une autre API interactive est toujours en cours. Les API `login` et `acquireToken` sont asynchrones ; vous devez donc vous assurer que les promesses qui en résultent sont résolues avant d’invoquer une autre API.

Utilisation loginPopup ou acquireTokenPopup

Vérifiez que la promesse retournée par ces API a été résolue avant d’appeler une autre.

❌ L’exemple suivant provoquera cette erreur, car loginPopup sera toujours en cours lorsque acquireTokenPopup sera appelé :

const request = { scopes: ["openid", "profile"] };
loginPopup();
acquireTokenPopup(request);

✔️ Pour résoudre ce problème, vous devez vous assurer que toutes les API interactives ont été résolues avant d’appeler une autre :

const request = { scopes: ["openid", "profile"] };
await msalInstance.loginPopup();
await msalInstance.acquireTokenPopup(request);

Utilisation loginRedirect ou acquireTokenRedirect

Lorsque vous utilisez des API de redirection, handleRedirectPromise doit être appelé lors du retour de la redirection. Cela garantit que la réponse du jeton du serveur est correctement gérée et que les entrées de cache temporaires sont nettoyées. Cette erreur se produit lorsque handleRedirectPromise n’a pas eu le temps de se terminer avant que l’application appelle loginRedirect ou acquireTokenRedirect.

❌ L’exemple suivant générera cette erreur, car handleRedirectPromise sera encore en train de traiter la réponse d’un appel précédent à loginRedirect lorsque loginRedirect sera appelé une deuxième fois :

msalInstance.handleRedirectPromise();

const accounts = msalInstance.getAllAccounts();
if (accounts.length === 0) {
    // No user signed in
    msalInstance.loginRedirect();
}

✔️ Pour résoudre cela, vous devez attendre que handleRedirectPromise soit résolu avant d’appeler une API interactive :

await msalInstance.handleRedirectPromise();

const accounts = msalInstance.getAllAccounts();
if (accounts.length === 0) {
    // No user signed in
    msalInstance.loginRedirect();
}

Ou alternativement :

msalInstance
    .handleRedirectPromise()
    .then((tokenResponse) => {
        if (!tokenResponse) {
            const accounts = msalInstance.getAllAccounts();
            if (accounts.length === 0) {
                // No user signed in
                msalInstance.loginRedirect();
            }
        } else {
            // Do something with the tokenResponse
        }
    })
    .catch((err) => {
        // Handle error
        console.error(err);
    });

Note: Si vous appelez loginRedirect ou acquireTokenRedirect à partir d’une page qui n’est pas votre vôtre redirectUri , vous devez vous assurer handleRedirectPromise qu’elle est appelée et attendue sur la redirectUri page ainsi que la page à partir de laquelle vous avez lancé la redirection. Cela est dû au fait que la redirectUri page lance une redirection vers la page qui a été appelée loginRedirect à l’origine et que cette page traite la réponse du jeton.

Bibliothèques wrapper

Si vous utilisez l’une de nos bibliothèques wrapper (React ou Angular), veuillez consulter la documentation sur cette erreur propre à ces bibliothèques pour connaître d’autres raisons pour lesquelles vous pouvez recevoir cette erreur :

Si vous n’utilisez aucune des bibliothèques wrapper, mais que votre application peut déclencher des demandes interactives simultanées, vous devez vérifier si une autre interaction est en cours avant d’appeler une interaction dans votre méthode d’acquisition de jetons. Pour ce faire, vous pouvez implémenter un état d’application global ou un service de diffusion, etc. qui émet l’état actuel de l’interaction MSAL via l’API Événements MSAL.

❌ L’exemple suivant génère cette erreur, car le acquireTokenPopup bloc catch ne vérifie pas si une autre interaction se produit actuellement :

async function myAcquireToken(request) {
    const msalInstance = getMsalInstance(); // get the msal application instance

    const tokenRequest = {
        account: msalInstance.getActiveAccount() || null;
        ...request
    };

    let tokenResponse;

    try {
        // attempt silent acquisition first
        tokenResponse = await msalInstance.acquireTokenSilent(tokenRequest);
    } catch (error) {
        if (error instanceof InteractionRequiredAuthError) {
            try {
                tokenResponse = await msalInstance.acquireTokenPopup(tokenRequest);
            } catch (err) {
                console.log(err);
                // handle other errors
            }
        }

        console.log(error);
        // handle other errors
    }

    return tokenResponse;
};

const request = {
    scopes: ["User.Read"]
};

myAcquireToken(request);
myAcquireToken(request);

✔️ Pour résoudre ce problème, vous devez attendre que l’état de l’interaction soit None avant d’appeler une autre API interactive :

async function myAcquireToken(request) {
    const msalInstance = getMsalInstance(); // get the msal application instance

    const tokenRequest = {
        account: msalInstance.getActiveAccount() || null;
        ...request
    };

    let tokenResponse;

    try {
        // attempt silent acquisition first
        tokenResponse = await msalInstance.acquireTokenSilent(tokenRequest);
    } catch (error) {
        if (error instanceof InteractionRequiredAuthError) {
            // check for any interactions
            if (myGlobalState.getInteractionStatus() !== InteractionStatus.None) {
                // throw a new error to be handled in the caller below
                throw new Error("interaction_in_progress");
            } else {
                // no interaction, invoke popup flow
                tokenResponse = await msalInstance.acquireTokenPopup(tokenRequest);
            }
        }

        console.log(error);
        // handle other errors
    }

    return tokenResponse;
};

async function myInteractionInProgressHandler() {
    /**
     * "myWaitFor" method polls the interaction status via getInteractionStatus() from
     * the application state and resolves when it's equal to "None".
     */
    await myWaitFor(() => myGlobalState.getInteractionStatus() === InteractionStatus.None);

    // wait is over, call myAcquireToken again to re-try acquireTokenSilent
    return (await myAcquireToken(tokenRequest));
};

const request = {
    scopes: ["User.Read"]
};

myAcquireToken(request).catch((e) => myInteractionInProgressHandler());
myAcquireToken(request).catch((e) => myInteractionInProgressHandler());

Procédure de résolution du problème

Si vous ne parvenez pas à déterminer pourquoi cette erreur se produit, ouvrez un ticket et préparez-vous à fournir les informations suivantes :

  • Journaux détaillés
  • Exemple d’application et/ou d’extraits de code que nous pouvons utiliser pour reproduire le problème
  • Actualisez la page. L’erreur disparaît-t-elle ?
  • Ouvrez votre application dans un nouvel onglet. L’erreur disparaît-t-elle ?

block_iframe_reload

Message d’erreur : la demande a été bloquée à l’intérieur d’un iframe, car MSAL a détecté une réponse d’authentification.

Cette erreur est levée lors de l'appel de ssoSilent ou acquireTokenSilent et lorsque la page utilisée comme redirectUri tente d'appeler une fonction de connexion ou acquireToken. La mesure d’atténuation que nous recommandons consiste à définir votre redirectUri sur une page vide qui n’implémente pas MSAL lors de l’invocation d’API en mode silencieux. Cela aura également l’avantage supplémentaire d’améliorer les performances, car l’iframe masqué n’a pas besoin d’afficher votre page.

✔️ Vous pouvez le faire au cas par cas, pour chaque requête, par exemple :

msalInstance.acquireTokenSilent({
    scopes: ["User.Read"],
    redirectUri: "http://localhost:3000/blank.html",
});

N’oubliez pas que vous devrez enregistrer ce nouveau redirectUri dans votre inscription d’application.

Si vous ne souhaitez pas utiliser un élément dédié redirectUri à cet effet, vous devez plutôt veiller à ce que votre redirectUri ne tente pas d’appeler les API MSAL lorsqu’il est rendu à l’intérieur de l’iframe masquée utilisée par les API silencieuses.

monitor_window_timeout

Messages d’erreur :

  • L’obtention du jeton dans l’iframe a échoué pour cause de dépassement de délai.

Cette erreur peut être générée lors de l’appel de ssoSilent, acquireTokenSilent, acquireTokenPopup ou loginPopup, et cela peut se produire pour plusieurs raisons. Voici quelques-unes des plus courantes :

  1. La page que vous utilisez comme redirectUri supprime ou modifie le hash
  2. La page que vous utilisez comme redirectUri redirige automatiquement vers une autre page
  3. Votre fournisseur d'identité vous limite.
  4. Votre fournisseur d'identité n'a pas redirigé vers votre redirectUri.

Important : Si votre application utilise une bibliothèque de routeurs (par exemple, React Router, Angular Router), assurez-vous qu’elle ne supprime pas le hachage ou la redirection automatique pendant que l’acquisition de jetons MSAL est en cours. Si possible, il est préférable que votre redirectUri page n’appelle pas le routeur du tout.

Problèmes causés par la page redirectUri

Lorsque vous effectuez un appel silencieux, dans certains cas, un iframe est ouvert et accède à la page d’autorisation de votre fournisseur d’identité. Une fois que le fournisseur d’identité a autorisé l’utilisateur, il redirigera de nouveau l’iframe vers redirectUri avec le code d’autorisation ou les informations d’erreur dans le fragment de hachage. L’instance MSAL s’exécutant dans le cadre ou la fenêtre qui a initialement effectué la requête extrait ce hachage de réponse et le traite. Si votre redirectUri supprime ou manipule ce fragment, ou redirige vers une autre page avant que MSAL ne l’ait récupéré, vous recevrez cette erreur de dépassement de délai.

✔️ Pour résoudre ce problème, vous devez vous assurer que la page que vous utilisez comme redirectUri ne fasse rien de tout cela, au moins lorsqu’elle est chargée dans une fenêtre contextuelle ou un iframe. Nous vous recommandons d’utiliser une page vide comme votre redirectUri pour les flux silencieux et de fenêtre contextuelle afin de vous assurer qu’aucune de ces situations ne puisse se produire.

Vous pouvez le faire pour chaque requête, par exemple :

msalInstance.acquireTokenSilent({
    scopes: ["User.Read"],
    redirectUri: "http://localhost:3000/blank.html",
});

N’oubliez pas que vous devrez enregistrer ce nouveau redirectUri dans votre enregistrement d’application.

Remarques concernant Angular et React :

  • Si vous utilisez @azure/msal-angular votre redirectUri page ne doit pas être protégé par le MsalGuard.
  • Si vous utilisez @azure/msal-react, votre page redirectUri ne doit pas afficher MsalAuthenticationComponent ni utiliser le hook useMsalAuthentication.

Problèmes causés par le fournisseur d’identité

Limitation

L’une des raisons les plus courantes pour lesquelles cette erreur peut être levée est que votre application est bloquée dans une boucle ou a effectué trop de demandes de jetons dans un court laps de temps. Dans ce cas, le fournisseur d'identité peut limiter les demandes suivantes pendant un court laps de temps, ce qui aura pour effet de ne pas vous rediriger vers votre redirectUri et, au final, de provoquer cette erreur.

✔️ Pour résoudre les problèmes liés à la limitation du débit, deux options s’offrent à vous :

  1. Arrêtez d’effectuer des demandes pendant un court instant avant de réessayer.
  2. Appeler une API interactive, telle que acquireTokenPopup ou acquireTokenRedirect.
X-Frame-Options Deny

Vous pouvez également obtenir cette erreur si le fournisseur d’identité ne parvient pas à rediriger vers votre application. Dans les scénarios sans interaction, cette erreur est parfois accompagnée d’une erreur « X-Frame-Options: Deny » indiquant que votre fournisseur d’identité essaie soit d’afficher un message d’erreur, soit de nécessiter une interaction.

✔️ L’erreur X-Frame-Options aura généralement une URL dans celle-ci et l’ouverture de cette URL dans un nouvel onglet peut vous aider à discerner ce qui se passe. Si l’interaction est requise, envisagez plutôt d’utiliser une API interactive. Si une erreur s’affiche, résolvez l’erreur.

Certains flux B2C sont censés lever cette erreur en raison de leur besoin d’interaction utilisateur. Ces flux sont les suivants :

  • Réinitialisation du mot de passe
  • Modification du profil
  • S’inscrire
  • Certaines stratégies personnalisées en fonction de la façon dont elles sont configurées
Latence du réseau

Une autre raison potentielle pour laquelle le fournisseur d’identité peut ne pas rediriger vers votre application dans le temps peut être qu’il existe une latence réseau supplémentaire.

✔️ Le délai d’expiration par défaut est d’environ 10 secondes et devrait être suffisant dans la plupart des cas ; toutefois, si votre fournisseur d’identité met plus de temps à vous rediriger, vous pouvez augmenter ce délai dans la configuration MSAL à l’aide des paramètres de configuration iframeHashTimeout, windowHashTimeout ou loadFrameTimeout.

const msalConfig = {
    auth: {
        clientId: "your-client-id",
    },
    system: {
        windowHashTimeout: 9000, // Applies just to popup calls - In milliseconds
        iframeHashTimeout: 9000, // Applies just to silent calls - In milliseconds
        loadFrameTimeout: 9000, // Applies to both silent and popup calls - In milliseconds
    },
};

hash_empty_error

Messages d’erreur :

La valeur de hachage ne peut pas être traitée, car elle est vide. Vérifiez que votre redirectUri n'efface pas le hachage.

Cette erreur se produit lorsque la page que vous utilisez comme redirectUri supprime le hachage ou la redirection automatique vers une autre page. Cela se produit le plus souvent lorsque l’application implémente un routeur qui accède à un autre itinéraire, en supprimant le hachage.

Pour résoudre cette erreur, nous vous recommandons d’utiliser une page redirectUri dédiée qui n’est pas soumise au routeur. Pour les appels silencieux et contextuels, il est préférable d’utiliser une page vide. Si cela n’est pas possible, assurez-vous que le routeur ne navigue pas pendant que l’acquisition de jeton MSAL est en cours. Pour ce faire, vous pouvez détecter si votre application est chargée dans un iframe pour les appels silencieux, dans une fenêtre contextuelle pour les appels contextuels ou en attendant handleRedirectPromise les appels de redirection.

hash_does_not_contain_known_properties

Messages d’erreur :

Le hachage ne contient pas de propriétés correctes connues. Vérifiez que votre redirectUri ne modifie pas le hachage.

Veuillez consulter l’explication de hash_empty_error ci-dessus. La cause racine de cette erreur est similaire, à la différence que le hachage a été modifié plutôt que supprimé.

impossible_d_obtenir_un_jeton_depuis_la_plateforme_native

Messages d’erreur :

  • Impossible d’acquérir un jeton à partir de la plateforme native.

Cette erreur est levée lors de l'appel de l'API acquireTokenByCode avec le nativeAccountId au lieu de code et lorsque l'application s'exécute dans un environnement qui n'acquiert pas de tokens auprès du broker natif. Pour obtenir la liste des prérequis, consultez la documentation sur les jetons liés à l’appareil.

Connexion native non établie

Messages d’erreur :

  • La connexion à la plateforme native n’a pas été établie. Installez une extension de navigateur compatible et exécutez initialize().

Cette erreur se produit lorsque l’utilisateur s’est authentifié avec le broker natif, alors qu’aucune connexion au broker natif n’existe actuellement. Ceci peut se produire pour les raisons suivantes :

  • L’extension comptes Windows a été désinstallée ou désactivée
  • L’API initialize n’a pas été appelée ou n’a pas été attendue avant d’appeler une autre API MSAL

application cliente publique non initialisée

Messages d’erreur :

  • Vous devez appeler et attendre la fonction d’initialisation avant de tenter d’appeler une autre API MSAL.

Cette erreur se produit lorsqu’une API login, acquireToken ou handleRedirectPromise est invoquée avant que l’API initialize n’ait été appelée. L’API initialize doit être appelée et attendue avant de tenter d’acquérir des jetons.

❌ L’exemple suivant génère cette erreur, car handleRedirectPromise est appelé avant la fin de l’exécution de initialize :

const msalInstance = new PublicClientApplication({
    auth: {
        clientId: "your-client-id",
    },
    system: {
        allowNativeBroker: true,
    },
});

await msalInstance.handleRedirectPromise(); // This will throw
msalInstance.acquireTokenSilent(); // This will also throw

✔️ Pour résoudre ce problème, vous devez attendre que initialize soit résolu avant d’appeler toute autre API MSAL :

const msalInstance = new PublicClientApplication({
    auth: {
        clientId: "your-client-id",
    },
    system: {
        allowNativeBroker: true,
    },
});

await msalInstance.initialize();
await msalInstance.handleRedirectPromise(); // This will no longer throw this error since initialize completed before this was invoked
msalInstance.acquireTokenSilent(); // This will also no longer throw this error

Other

Erreurs non générées par MSAL, telles que les erreurs de serveur

L’accès à la ressource située à l’adresse [url] a été bloqué par la politique CORS

Cette erreur se produit avec MSAL.js v2.x et est due à une configuration incorrecte lors de l’inscription d’application sur Portail Azure. En particulier, vous devez vous assurer que votre redirectUri est inscrit avec le type : Single-page application sous le panneau Authentification dans votre inscription d'application. Si l'opération réussit, une coche verte s'affiche avec le message suivant :

Votre URI de redirection est éligible au flux de code d’autorisation avec PKCE.

image