Uso de MSAL en aplicaciones iframed

De forma predeterminada, MSAL impide que el marco completo redirija a Microsoft Entra ID punto de conexión de autenticación cuando una aplicación se representa dentro de un iframe, lo que significa que no puede usar las API de redirección para la interacción del usuario con el IdP:

  • Esta restricción se impone, ya que Microsoft Entra ID rechazará representar cualquier petición que requiera interacción del usuario (por ejemplo, entrada de credenciales, consentimiento, cierre de sesión, etc.) en un iframe iniciando el X-FRAME OPTIONS SET TO DENYerror, una medida tomada para evitar ataques de robo de clic.
  • En su lugar, tendrá que confiar en las API emergentes de MSAL si se requiere la interacción del usuario o las API silenciosas (ssoSilent(), acquireTokenSilent()) si se puede evitar la interacción del usuario.
  • Del mismo modo, tendrás que usar la API logoutPopup() para los cierres de sesión (:warning: si la aplicación usa una versión anterior msal-browser a v2.13, asegúrate de actualizar y reemplazar la logout() API, ya que intentará un redireccionamiento de fotograma completo a Microsoft Entra ID).
  • Al usar las API emergentes, hay que tener en cuenta las restricciones de aislamiento impuestas por la aplicación principal. En concreto, la aplicación principal debe establecer el indicador allow-popups cuando el iframe se encuentre en un entorno de sandbox.

Azure AD B2C ofrece una experiencia de inicio de sesión incrustada, que permite representar una interfaz de usuario de inicio de sesión personalizada en un iframe. Dado que MSAL impide el redireccionamiento en iframes de forma predeterminada, deberá establecer la opción de configuración allowRedirectInIframe en true para poder usar esta característica. Tenga en cuenta que no se recomienda habilitar esta opción para las aplicaciones en Microsoft Entra ID, debido a la restricción anterior.

Restricciones del explorador

Dado que las cookies de sesión de Microsoft Entra dentro de un iframe se consideran cookies de terceros, determinados navegadores (por ejemplo, Safari o Chrome en modo de incógnito) bloquean o bien borran estas cookies de forma predeterminada. Esto afectará a la experiencia de inicio de sesión único para las aplicaciones iframed, ya que no tendrán acceso a las cookies de sesión de IdP (consulte: Inicio de sesión único).

Además, cuando las cookies de terceros están desactivadas en Chrome, las aplicaciones MSAL integradas en un iframe no tendrán acceso al almacenamiento local ni al de sesión. MSAL recurrirá al almacenamiento en memoria en este caso.

Autenticación única

puede lograr el inicio de sesión único entre aplicaciones enmarcadas en iframes y aplicaciones primarias del mismo origeny de origen cruzadosi pasa un indicio de cuenta de la aplicación primaria a la aplicación enmarcada en un iframe.

Aplicaciones con el mismo origen

Las aplicaciones primarias y iframed con el mismo origen pueden tener acceso a la misma instancia de caché de MSAL.js y poder iniciar sesión sin avisos, siempre que ambas aplicaciones configuren MSAL para usar el almacenamiento local para el almacenamiento en caché. Consulte más información en: Inicio de sesión único con MSAL.js

Aplicaciones con origen cruzado

Las aplicaciones en iframe y las aplicaciones principales con origen cruzado pueden utilizar la API ssoSilent() para lograr el inicio de sesión único. Para ello, la aplicación primaria debe pasar una cuenta, un loginHint (nombre de usuario) o un identificador de sesión (sid) a la aplicación iframed.

Las aplicaciones pueden intentar usar ssoSilent sin ninguno de los parámetros anteriores. Sin embargo, tenga en cuenta que hay consideraciones adicionales al usar ssoSilent sin proporcionar información sobre la sesión del usuario.

Para la comunicación de origen cruzado entre aplicaciones en iframe y aplicaciones principales, hay varias alternativas que puedes considerar:

  • Puede agregar cadenas de consulta a la fuente del iframe en la aplicación principal y recuperarlas más adelante en la aplicación hija:
// 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
    });
}
  • Puede utilizar la API postMessage() en la aplicación principal y escuchar los eventos de mensajes en la secundaria:
// 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
        });
    }
});

Gestión de errores

Debe detectar y gestionar cualquier error si ssoSilent() falla. En particular:

  • InteractionRequiredError: se producirá si se requiere consentimiento, el usuario debe realizar MFA y etc. Este error se puede controlar a menudo iniciando simplemente una API interactiva.
  • BrowserAuthError: se lanzará si no se proporciona ninguna pista de cuenta o esta es inválida, si se bloquean las ventanas emergentes, etc. Deberá inspeccionar el errorCode y administrar estos casos adecuadamente.
    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);
            }
        });

Interacción del usuario

Si desea minimizar la comunicación con el IdP que requiere interacción del usuario, o si tiene problemas con elementos emergentes por cualquier motivo, hay algunas opciones que puede considerar:

Cierre de sesión único

Puedes utilizar MSAL.js con un URI de cierre de sesión del canal frontal para lograr el efecto de cierre de sesión único entre la aplicación incrustada en iframe y la aplicación principal. Por ejemplo, si desea que los usuarios cierren sesión automáticamente en las aplicaciones integradas en iframes cuando cierren sesión en la aplicación principal, debe habilitar el cierre de sesión por canal frontal para esas aplicaciones. Para ello, consulte: Cómo configurar un URI de cierre de sesión del canal frontal.