Använda MSAL i inramade appar

Som standard förhindrar MSAL fullständiga omdirigeringar till Microsoft Entra ID autentiseringsslutpunkt när en app återges i en iframe, vilket innebär att du inte kan använda omdirigerings-API:er för användarinteraktion med IdP:

  • Den här begränsningen införs eftersom Microsoft Entra ID vägrar att göra någon uppmaning som kräver användarinteraktion (t.ex. autentiseringsuppgifter, medgivande, utloggning osv.) i en iframe genom att X-FRAME OPTIONS SET TO DENY utlösa felet, en åtgärd som vidtas för att förhindra klickkapningsattacker.
  • I stället måste du förlita dig på MSAL:s popup-API:er om användarinteraktion krävs och/eller tysta API:er (ssoSilent(), acquireTokenSilent()) om användarinteraktion kan undvikas.
  • På samma sätt måste du använda logoutPopup()-API:et för utloggningar (:varning: om din app använder en äldre version msal-browser än v2.13 måste du uppgradera och ersätta API:etlogout(), eftersom det kommer att försöka utföra en fullständig omdirigering till Microsoft Entra ID).
  • När du använder popup-API:er måste du ta hänsyn till eventuella begränsningar för sandbox-miljön som införts av den överordnade appen. I synnerhet måste den överordnade appen ange flaggan allow-popups när iframen körs i sandbox-läge.

Azure AD B2C erbjuder en inbäddad inloggningsupplevelse som gör det möjligt att återge ett anpassat inloggningsgränssnitt i en iframe. Eftersom MSAL förhindrar omdirigering i iframes som standard måste du ange konfigurationsalternativet allowRedirectInIframe till true för att kunna använda den här funktionen. Observera att det inte rekommenderas att aktivera det här alternativet för appar på Microsoft Entra ID på grund av ovanstående begränsning.

Webbläsarbegränsningar

Eftersom Microsoft Entra sessionscookies inom en iframe betraktas som cookies från tredje part blockerar eller rensar vissa webbläsare (till exempel Safari eller Chromei inkognitoläge) dessa cookies som standard. Detta påverkar funktionen för enkel inloggning för iframed-appar eftersom de inte har åtkomst till IdP:s sessionscookies (se: Enkel inloggning).

När cookies från tredje part är inaktiverade i Chrome har dessutom iframlagda MSAL-appar inte åtkomst till lokal lagring eller sessionslagring. MSAL återgår till minnesintern lagring i det här fallet.

Enkel inloggning

Du kan uppnå enkel inloggning mellan iframerade och överordnade appar med samma ursprungoch med korsande ursprungom du skickar ett kontotips från den överordnade appen till den iframerade appen.

Appar med samma ursprung

Iframed och överordnade appar med samma ursprung kan ha åtkomst till samma MSAL.js cacheinstans och kunna logga in utan uppmaningar, förutsatt att båda apparna konfigurerar MSAL för att använda den lokala lagringen för cachelagring. Mer information finns i Enkel inloggning med MSAL.js

Appar med korsande ursprung

Iframed-appar och överordnade appar från olika ursprung kan använda ssoSilent()-API:et för att uppnå enkel inloggning (SSO). För att göra det bör den överordnade appen skicka antingen ett konto, en loginHint (användarnamn) eller ett sessions-ID (sid) till den iframerade appen.

Appar kan försöka använda ssoSilent utan någon av ovanstående parametrar. Tänk dock på att det finns ytterligare överväganden när du använder ssoSilent utan att ange någon information om användarens session.

För kommunikation mellan ursprung mellan iframlade och överordnade appar finns det några alternativ som du kan överväga:

  • Du kan lägga till frågeparametrar i iframes källadress i föräldraappen och hämta dem senare i den underordnade appen:
// Create the main myMSALObj instance
// configuration parameters are located at authConfig.js
const myMSALObj = new msal.PublicClientApplication({
    auth: {
        clientId: "ENTER_CLIENT_ID",
        authority: "https://login.microsoftonline.com/ENTER_TENANT_ID",
        redirectUri: "/redirect", // set to a blank page for handling auth code response via popups
    },
    cache: {
        cacheLocation: "localStorage", // set your cache location to local storage
    },
});

window.onload = () => {
    
    const urlParams = new URLSearchParams(window.location.search);
    const sid = urlParams.get("sid");

    // attempt SSO
    myMSALObj.ssoSilent({
        sid: sid
    }).then((response) => {
        // do something with response
    }).catch(error => {
        // handle errors
    });
}
  • Du kan använda API:et postMessage() i den överordnade appen och lyssna efter meddelandehändelser i det underordnade:
// Create the main myMSALObj instance
// configuration parameters are located at authConfig.js
const myMSALObj = new msal.PublicClientApplication({
    auth: {
        clientId: "ENTER_CLIENT_ID",
        authority: "https://login.microsoftonline.com/ENTER_TENANT_ID",
        redirectUri: "/redirect", // set to a blank page for handling auth code response via popups
    },
    cache: {
        cacheLocation: "localStorage", // set your cache location to local storage
    },
});

const parentDomain = "http://localhost:3001";

window.addEventListener("message", (event) => {
    // check the origin of the data
    if (event.origin === parentDomain) {
        const sid = event.data;

        // attempt SSO
        myMSALObj.ssoSilent({
            sid: sid
        }).then((response) => {
            // do something with response
        }).catch(error => {
            // handle errors
        });
    }
});

Felhantering

Du bör fånga och hantera eventuella fel om ssoSilent() misslyckas. Framför allt:

  • InteractionRequiredError: utlöses om medgivande krävs, användaren måste utföra MFA och så vidare. Det här felet kan ofta hanteras genom att bara initiera ett interaktivt API.
  • BrowserAuthError: utlöses om inget eller ogiltigt kontotips tillhandahålls, popup-fönster blockeras och så vidare. Du måste inspektera errorCode och hantera dessa på rätt sätt.
    myMSALObj.ssoSilent({
        sid: sid
    }).then((response) => {
            // do something with response
        }).catch(error => {
            if (error instanceof msal.InteractionRequiredAuthError) {
                myMSALObj.loginPopup()
                    .then((response) => {
                        // do something with response
                    });
            } else if (error instanceof msal.BrowserAuthError) {
                if (error.errorCode === "silent_sso_error") {
                    // e.g. username is null
                }
                if (error.errorCode === "popup_window_error") {
                    // e.g. popups are blocked
                }
            } else {
                console.log(error);
            }
        });

Användarinteraktion

Om du vill minimera kommunikationen med IdP som kräver användarinteraktion, eller om du har problem med popup-fönster av någon anledning, finns det några alternativ som du kan överväga:

  • Bevilja administratörsmedgivande. Detta säkerställer att det inte finns några medgivandemeddelanden om behörigheter som krävs av din app när användarna loggar in för första gången.

  • Förauktorisera klientappar. Detta säkerställer att det inte finns några medgivandefrågor om behörigheter som krävs av webb-API:et när det anropas av dina klientappar.

Enkel utloggning

Du kan använda MSAL.js med en utloggnings-URI för frontkanalen för att uppnå en enkel utloggningseffekt mellan iframerade och överordnade appar. Om du till exempel vill att användare automatiskt ska loggas ut från appar i iframes när de loggar ut från den överordnade appen, bör du aktivera utloggning via frontkanalen för apparna i iframes. Det gör du genom att läsa: Så här konfigurerar du en utloggnings-URI för frontkanalen.