Migración de MSAL Browser v4 a v5

Si no está familiarizado con MSAL, debería empezar aquí.

Si procede de MSAL v2, primero debe consultar esta guía para migrar a MSAL v3. Si procede de MSAL v3, primero debe consultar esta guía para migrar a MSAL v4 y, a continuación, siga los pasos siguientes.

Si procede de MSAL v4, puede seguir esta guía para actualizar el código para usar MSAL v5.

Cambios importantes en API

El tipo de retorno de SignedHttpRequest.removeKeys ha cambiado

La removeKeys función de la SignedHttpRequest clase ahora devuelve Promise<void> en lugar de Promise<boolean>. Una resolución satisfactoria de la promesa equivale ahora a lo que anteriormente era un valor de retorno de true. Si se produce un fallo, ahora se lanza como un error en lugar de devolver false.

// BEFORE
const shr = new SignedHttpRequest(shrParameters, shrOptions);
const result = await shr.removeKeys(thumbprint);
if (result) {
    // do something on success
} else {
    // do something on failure
}

// AFTER
const shr = new SignedHttpRequest(shrParameters, shrOptions);
await shr
    .removeKeys(thumbprint)
    .then(() => {
        // do something on success
    })
    .catch((e) => {
        // do something on failure
        console.log(e);
    });

TokenCache y loadExternalTokens

Se modifica la API de MSAL JS para loadExternalTokens . Los cambios son:

  • TokenCache el objeto y getTokenCache() se han eliminado
  • La loadExternalTokens() API ahora es una exportación independiente y requiere Configuration como parámetro
// BEFORE

const pca = new PublicClientApplication(config);
await pca
    .getTokenCache()
    .loadExternalTokens(silentRequest, serverResponse, loadTokenOptions);

//AFTER

await loadExternalTokens(
    config,
    silentRequest,
    serverResponse,
    loadTokenOptions
);

handleRedirectPromise La firma de API ha cambiado

Anteriormente, PublicClientApplication.handleRedirectPromise aceptaba un parámetro hash opcional. Se ha introducido un nuevo tipo de opciones llamado HandleRedirectPromiseOptions . A partir de MSAL Browser v5, un objeto opcional con tipo HandleRedirectPromiseOptions es el único parámetro handleRedirectPromise() que acepta.

// BEFORE
const hash = window.location.hash; // Arbitrary example value
pca.handleRedirectPromise(hash);

// AFTER
pca.handleRedirectPromise({
    hash: window.location.hash, // Option nested inside a `HandleRedirectPromiseOptions` object
    navigateToLoginRequestUrl: true, // Additional option
});

Eliminación de algunas funciones en PublicClientApplication

Se han quitado las siguientes funciones de PublicClientApplication :

  1. enableAccountStorageEvents() y disableAccountStorageEvents(): los eventos de almacenamiento de la cuenta ahora siempre están habilitados. Estas llamadas de función ya no son necesarias.

  2. getAccountByHomeId(), getAccountByLocalId()y getAccountByUsername(): use getAccount() en su lugar.

    // BEFORE
    const account1 = accountManager.getAccountByHomeId(yourHomeAccountId);
    const account2 = accountManager.getAccountByLocalId(yourLocalAccountId);
    const account3 = accountManager.getAccountByUsername(yourUsername);
    
    // AFTER
    const account1 = accountManager.getAccount({
        homeAccountId: yourHomeAccountId,
    });
    const account2 = accountManager.getAccount({
        localAccountId: yourLocalAccountId,
    });
    const account3 = accountManager.getAccount({ username: yourUsername });
    
  3. logout(): use logoutRedirect() o logoutPopup() en su lugar.

Eliminación de startPerformanceMeasurement()

Se ha eliminado startPerformanceMeasurement(). Utilice startMeasurement() en su lugar.

Eliminación de PublicClientNext

La PublicClientNext clase y su método createPublicClientApplication() estático se han quitado en MSAL v5. Debe usar una de las siguientes alternativas en función de los requisitos de la aplicación:

  • PublicClientApplication: Úselo para escenarios estándar de aplicación única. Este es el uso predeterminado y más común.
  • createNestablePublicClientApplication: Use esta opción si necesita admitir aplicaciones anidadas (NAA). Esta función recurre automáticamente a una PublicClientApplication estándar si el puente de aplicación integrada no está disponible o si Hub no está configurado para admitir la autenticación de aplicaciones integradas. Consulte Configuración de aplicaciones anidadas para obtener más información.
  • createStandardPublicClientApplication: Use esto para crear e inicializar una instancia estándar (no NAA) de PublicClientApplication.

Ejemplo de migración

// BEFORE (using PublicClientNext)
import { PublicClientNext } from "@azure/msal-browser";

const pca = PublicClientNext.createPublicClientApplication(config);
// AFTER (standard usage)
import { PublicClientApplication } from "@azure/msal-browser";

const pca = new PublicClientApplication(config);
await pca.initialize();
// AFTER (nested app support)
import { createNestablePublicClientApplication } from "@azure/msal-browser";

const pca = await createNestablePublicClientApplication(config);
// AFTER (standard)
import { createStandardPublicClientApplication } from "@azure/msal-browser";

const pca = await createStandardPublicClientApplication(config);

Para la mayoría de las aplicaciones, reemplazar PublicClientNext.createPublicClientApplication(config) por new PublicClientApplication(config) es suficiente. Si usó anteriormente la supportsNestedAppAuth opción de configuración, migre a createNestablePublicClientApplication(config) en su lugar.

Eliminación de la función estática PublicClientApplication.createPublicClientApplication

La función estática createPublicClientApplication de PublicClientApplication se ha eliminado y sustituido por createStandardPublicClientApplication, que se exporta por separado.

Ejemplo de migración

// BEFORE
import { PublicClientApplication } from "@azure/msal-browser";

const pca = await PublicClientApplication.createPublicClientApplication(config);
// AFTER
import { createStandardPublicClientApplication } from "@azure/msal-browser";

const pca = await createStandardPublicClientApplication(config);

Cambios en la configuración

Cambios en BrowserAuthOptions

  1. El skipAuthorityMetadataCache parámetro se ha quitado de BrowserAuthOptions en Configuración.

  2. El protocolMode parámetro se ha movido a SystemOptions en lugar de BrowserAuthOptions en Configuration.

  3. El parámetro supportsNestedAppAuth se ha quitado. En su lugar, use la createNestablePublicClientApplication API para aplicaciones anidadas. Obtenga más información sobre las aplicaciones anidadas aquí.

  4. El parámetro navigateTologinRequestUrl se ha eliminado de BrowserAuthOptions en Configuration y ahora puede proporcionarse dentro de un objeto de opciones como parámetro en la llamada a handleRedirectPromise:

    pca.handleRedirectPromise({ navigateToLoginRequestUrl: false });
    
  5. El parámetro encodeExtraQueryParams se ha quitado. Todos los parámetros de consulta adicionales están codificados.

  6. El parámetro supportsNestedAppAuth se ha quitado. Utilice createNestablePublicClientApplication() en su lugar.

        // BEFORE
        const pca = new PublicClientApplication({
            auth: {
                clientId: "your-client-id",
                authority: "https://login.microsoftonline.com/common"
                supportsNestedAppAuth: true
            },
        });
    
        // AFTER
        const pca = await createNestablePublicClientApplication({
            auth: {
                clientId: "your-client-id",
                authority: "https://login.microsoftonline.com/common"
            }
        });
    
  7. El parámetro OIDCOptions ahora acepta un ResponseMode en lugar de un ServerResponseType. ResponseMode.QUERY Use en lugar de ServerResponseType.QUERY y ResponseMode.FRAGMENT en lugar de ServerResponseType.FRAGMENT.

Cambios en CacheOptions

Los siguientes parámetros quedaron obsoletos en MSAL Browser v4 y se han eliminado de CacheOptions en v5:

  1. temporaryCacheLocation
  2. claimsBasedCachingEnabled - Los tokens de acceso ya no se almacenan según las declaraciones solicitadas.
  3. storeAuthStateInCookie
  4. secureCookies - Todas las cookies ahora solo se envían de forma segura a través de HTTPS.
  5. cacheMigrationEnabled

Opciones del sistema

  1. El protocolMode parámetro se ha movido a SystemOptions desde BrowserAuthOptions en Configuración. No hay ningún cambio en sus opciones o funcionalidad.
  2. El parámetro navigateFrameWait se ha quitado. Anteriormente era necesario para los exploradores antiguos que ya no son compatibles con MSAL.js.
  3. Los iframeHashTimeout parámetros y windowHashTimeout se han reemplazado por iframeBridgeTimeout y popupBridgeTimeout respectivamente. Estos tiempos de espera ahora controlan cuánto tiempo se espera para recibir una respuesta del puente de redirección a través de la API BroadcastChannel.

asyncPopups

Se ha cambiado el nombre del asyncPopups parámetro a navigatePopups en SystemOptions y se han invertido las opciones. Esto establece si las ventanas emergentes se abren y se accede a ellas más tarde. Cuando se establece en verdadero, se abren ventanas emergentes en blanco y se navega al dominio de inicio de sesión. Cuando se establece en false, las ventanas emergentes se abren directamente en el dominio de inicio de sesión. Esto se puede establecer en false en aquellos casos en los que about:blank no es compatible, por ejemplo, aplicaciones de escritorio o aplicaciones web progresivas.

Importante

De forma predeterminada, navigatePopups ahora está establecido en true. Si estaba usando asyncPopups antes, tendrá que cambiarla a navigatePopups e invertir la configuración.

Consulte el documento de configuración para obtener más detalles.

Cambios en la solicitud

Eliminación del onRedirectNavigate parámetro

El parámetro onRedirectNavigatesolo se admite a partir del objeto Configuration y se elimina de los objetos RedirectRequest y EndSessionRequest. Asegúrese de establecerlo en msal config si necesita usarlo.

Consolidación de parámetros de solicitud adicionales

Se han quitado los siguientes parámetros de solicitud:

  • authorizePostBodyParams
  • tokenBodyParameters
  • tokenQueryParameters

Para simplificar los parámetros de solicitud adicionales, los parámetros adicionales genéricos deben ir en la nueva extraParameters opción de solicitud. Cuando se incluyen extraParameters en una solicitud, se envían en todas las llamadas al servicio de tokens, ya sea en la cadena de consulta de la URL o en el cuerpo de la solicitud, según el httpMethod configurado en la solicitud (el valor predeterminado es GET). Para enviar parámetros adicionales que DEBEN ir en la cadena de consulta url, extraQueryParameters todavía está disponible.

Note

Si no está seguro de si el parámetro adicional debe ir en extraQueryStringParameters o extraParameters, lo más probable es que vaya a extraParameters.

Ejemplo de solicitud v4 (anterior):

// Example of a GET request with extra parameters
const authRequest = {
    scopes: ["SAMPLE_SCOPE"],
    extraQueryParamters: {
        "dc": "DC_VALUE" // This was sent on the query string on GET /authorize
    },
    tokenBodyParameters: {
        "extra_parameters_assertion": "ASSERTION_VALUE" // This was sent on the POST body to /token
    },
    tokenQueryParamters: {
        "slice": "SLICE_VALUE" // This was sent on the query string on POST /token
    }
}

// Example of a POST request with extra parameters
const authRequest = {
    scopes: ["SAMPLE_SCOPE"],
    httpMethod: "POST", // default is "GET" -> Determines method for "/authorize" call. Calls to "/token" are always POST
    extraQueryParamters: {
        "dc": "DC_VALUE" // This was sent on the query string on POST /authorize
    },
    authorizePostBodyParameters: {
        "extra_parameters_assertion": "ASSERTION_VALUE", // This was sent on the body on POST /authorize
    }
    tokenBodyParameters: {
        "extra_parameters_assertion": "ASSERTION_VALUE" // This was sent on the POST body to /token
    },
    tokenQueryParamters: {
        "slice": "SLICE_VALUE" // This was sent on the query string on POST /token
    }
}

Ejemplo de solicitud v5

// Example of a GET request with extra parameters
const authRequest = {
    scopes: ["SAMPLE_SCOPE"],
    extraQueryParamters: {
        // Will be sent in query string to /authorize and /token
        "dc": "DC_VALUE",
        "slice": "SLICE_VALUE"
    },
    extraParameters: {
        "extra_parameters_assertion": "ASSERTION_VALUE", // Will be sent in query string to /authorize and in body to /token
    },
};

// Example of a POST request with extra parameters
const authRequest = {
    scopes: ["SAMPLE_SCOPE"],
    httpMethod: "POST", // default is "GET" -> Determines method for "/authorize" call. Calls to "/token" are always POST
    extraQueryParamters: {
        // Will be sent in query string to /authorize and /token
        "dc": "DC_VALUE",
        "slice": "SLICE_VALUE"
    },
    extraParameters: {
        extra_parameter_assertion: "assertion_value", // Will be sent in post body to /authorize and /token
    },
};

Note

En los casos en que MSAL determina que extraParameters debe codificarse en la cadena URL, extraParameters se fusiona con extraQueryParams de modo que los parámetros con el mismo nombre se sobrescriben. En estos casos, el valor del parámetro de extraParameters tiene prioridad sobre el valor de .extraQueryParams

Compatibilidad con Cross-Origin-Opener-Policy (COOP)

MSAL Browser v5 introduce compatibilidad integrada con la directiva Cross-Origin-Opener-Policy (COOP), que mejora la seguridad al aislar los contextos de navegación. Cuando el servicio de autenticación (Microsoft Entra ID o Azure AD B2C) devuelve cabeceras COOP, los flujos tradicionales de autenticación mediante ventanas emergentes y de autenticación silenciosa mediante iframe quedan restringidos. MSAL v5 proporciona un mecanismo de puente de redirección para controlar la autenticación en entornos habilitados para COOP.

Note

Microsoft Entra ID (anteriormente Azure AD) tiene COOP habilitado de forma predeterminada. Para Azure AD B2C, la disponibilidad de COOP depende de la configuración de back-end y de los puntos de conexión de autenticación que se usan.

Qué ha cambiado

Cuando los encabezados COOP están incluidos en la respuesta del servicio de autenticación (p. ej., Cross-Origin-Opener-Policy: same-origin), los flujos tradicionales de autenticación mediante ventanas emergentes y iframes silenciosos fallan porque la ventana de autenticación no puede comunicarse con la ventana principal de la aplicación. MSAL v5 resuelve esto mediante la introducción de un patrón de redirección mediante puente.

Todos los flujos de autenticación (acquireTokenSilent(), ssoSilent(), loginPopup()y loginRedirect()) ahora usan el puente de redirección. El puente de redirección controla la respuesta de autenticación de forma diferente en función del flujo:

  • Flujos emergentes y silenciosos: el puente de redirección transmite la respuesta de autenticación a la ventana principal de la aplicación mediante la API BroadcastChannel.
  • Flujo de redirección: el puente de redirección vuelve a la página de la aplicación que inició la redirección con la respuesta de autenticación en la dirección URL.

Funcionamiento

  1. Aplicación principal: la aplicación inicia la autenticación mediante loginPopup(), ssoSilent()o loginRedirect()
  2. Redirección: MSAL abre una ventana emergente, un iframe o una ventana a una página de autoridad.
  3. Flujo de autenticación: la página de autoridad completa el flujo de OAuth y recibe la respuesta de autenticación.
  4. Control de respuestas: la página de redireccionamiento usa la nueva broadcastResponseToMainFrame() función que:
    • Para flujos con ventana emergente o silenciosos: transmite la respuesta a la ventana principal a través de la API BroadcastChannel
    • Para flujos de redirección: navega a la página desde la que se inicia acquireTokenRedirect, con la respuesta de autenticación.
  5. Adquisición de tokens: la aplicación principal recibe la respuesta y completa la adquisición de tokens.

Pasos de migración

1. Configurar la página del puente de redirección

Cree una página que llame a broadcastResponseToMainFrame() desde @azure/msal-browser/redirect-bridge. Esta página NO debe servirse con encabezados COOP.

La configuración varía según el sistema de compilación( consulte la guía de configuración del puente de redirección: Framework-Specific :

Framework Approach
Angular Componente de ruta + recursos opcionales angular.json
Vite Multipágina rollupOptions.input
Webpack Entrada independiente + HtmlWebpackPlugin
Next.js Componente de página excluido de MsalProvider
CRA (Create React App) Página estática public/redirect.html
Express.js Exclusión del encabezado COOP del lado servidor

Consulte también:Consideraciones sobre redireccionamiento URI | errores en interaction_in_progress en ventanas emergentes | MDN: COOP

2. Actualización de la configuración de MSAL

Dirija redirectUri a una nueva página puente de redirección:

const msalConfig = {
    auth: {
        clientId: "{your-client-id}",
        authority: "https://login.microsoftonline.com/common",
        redirectUri: "https://{your-app-home-page}/redirect",
    },
};

Importante

También DEBE actualizar el URI de redirección en el registro de la aplicación de Entra ID. El URI debe coincidir exactamente , incluida la ruta de acceso, el protocolo y el puerto. Si no lo hace, se producirán errores en redirect_uri_mismatch.

Cambios importantes en el comportamiento

Tipos de eventos y cambios de InteractionStatus

Hemos consolidado los tipos de eventos y InteractionStatus para reflejar lo que ha ocurrido en lugar de lo que ha ocurrido en la API.

  1. SSO_SILENTy ACQUIRE_TOKEN_BY_CODE los eventos se han reemplazado por ACQUIRE_TOKEN eventos (START/SUCCESS/FAILURE variantes)
  2. ACCOUNT_ADDED y ACCOUNT_REMOVED se han reemplazado por LOGIN_SUCCESS y LOGOUT_SUCCESS, respectivamente.
  3. LOGIN_START y LOGIN_FAILURE se han reemplazado por ACQUIRE_TOKEN_START y ACQUIRE_TOKEN_FAILURE, respectivamente.
  4. La carga útil de LOGIN_SUCCESS ahora es un objeto AccountInfo.
  5. Ahora, cualquier inicio de sesión exitoso emite los eventos LOGIN_SUCCESS y ACQUIRE_TOKEN_SUCCESS.

LOGIN_SUCCESS Migración de tipos de carga

Si su callback de evento convierte actualmente las cargas útiles de LOGIN_SUCCESS a AuthenticationResult, actualícelo para usar AccountInfo para LOGIN_SUCCESS y reserve AuthenticationResult para ACQUIRE_TOKEN_SUCCESS.

// BEFORE (v4-style assumption)
import {
    EventType,
    AuthenticationResult,
} from "@azure/msal-browser";

pca.addEventCallback((event) => {
    if (event.eventType === EventType.LOGIN_SUCCESS) {
        const result = event.payload as AuthenticationResult;
        setAccount(result.account); // Will silently fail in v5 where payload is AccountInfo, not AuthenticationResult
    }
});
// AFTER (v5-safe handling)
import {
    EventType,
    AuthenticationResult,
    AccountInfo,
} from "@azure/msal-browser";

pca.addEventCallback((event) => {
    if (event.eventType === EventType.LOGIN_SUCCESS) {
        const account = event.payload as AccountInfo;
        setAccount(account);
    }

    if (event.eventType === EventType.ACQUIRE_TOKEN_SUCCESS) {
        const result = event.payload as AuthenticationResult;
        setAccessToken(result.accessToken);
    }
});

Cambios en el formato del mensaje de error

Para reducir el tamaño de la agrupación, los mensajes de error se han movido fuera de la agrupación. Cuando se produce un error, la message propiedad devuelve ahora un vínculo genérico a la documentación del error en lugar de un mensaje de error descriptivo:

// BEFORE (v4)
error.message = "Token request cannot be made without authorization code or refresh token.";

// AFTER (v5)
error.message = "See https://aka.ms/msal.js.errors#request_cannot_be_made for details";

La errorCode propiedad permanece sin cambios y todavía se puede usar para identificar el error específico. Para obtener descripciones detalladas de errores, consulte la documentación de errores.

Importante

Si la aplicación se basa en analizar o mostrar la propiedad error.message, es posible que tenga que actualizar su código de control de errores para usar errorCode en su lugar o remitir a los usuarios al enlace de la documentación.

Actualización del código de control de errores

Si muestra errores a los usuarios, asocie errorCode a mensajes comprensibles para el usuario en lugar de mostrar error.message directamente:

// BEFORE (v4)
showError(error.message);

// AFTER (v5) — use errorCode for user-facing messages
const userMessages = {
    request_cannot_be_made: "Please sign in again to continue.",
    interaction_required: "Additional verification is needed.",
    consent_required: "Administrator approval is required for this action.",
    login_required: "Your session has expired. Please sign in again.",
    // Add mappings for error codes your application encounters
};
showError(userMessages[error.errorCode] || "An authentication error occurred.");

Si analiza los errores de la lógica condicional, cambie de la coincidencia de cadenas en message a la comparación errorCode (este ya era el enfoque recomendado en v4):

// BEFORE (v4) — fragile, relied on message text
if (error.message.includes("interaction_required")) {
    await msalInstance.acquireTokenPopup(request);
}

// AFTER (v5) — use errorCode (stable across versions)
if (error.errorCode === "interaction_required") {
    await msalInstance.acquireTokenPopup(request);
}

Si registra errores con fines de diagnóstico, incluya tanto errorCode como message (el mensaje ahora contiene un enlace directo a la documentación pertinente):

// AFTER (v5) — log errorCode for programmatic use, message for the docs link
logger.error(`MSAL Error [${error.errorCode}]: ${error.message}`);
// Output: MSAL Error [request_cannot_be_made]: See https://aka.ms/msal.js.errors#request_cannot_be_made for details

Tip

Los errorCode valores son los mismos entre v4 y v5; solo ha cambiado el message formato. Si el código existente ya se bifurca en errorCode, no se necesitan cambios.

Cambios en el registro de la consola

Para reducir el tamaño del paquete, los mensajes del registro de la consola ahora se someten a hash. En lugar de ver los mensajes de registro completos en la consola del navegador, verá un valor de hash:

// BEFORE (v4)
[Wed, 15 Jan 2025 10:30:45 GMT] : abc-123 : @azure/msal-browser@4.27.0 : Info - Returning token from cache

// AFTER (v5)
[Wed, 15 Jan 2025 10:30:45 GMT] : abc-123 : @azure/msal-browser@5.0.0 : Info - 7f3a9b2c

La depuración en la consola del navegador requiere un paso adicional para decodificar registros. Para decodificar los logs con hash y volver a convertirlos en mensajes legibles, utilice el decode script. Para obtener más información sobre el uso del script de descodificación, consulte la documentación del script.