Migrar do MSAL Browser v4 para v5

Se és novo no MSAL, deves começar por aqui.

Se vens do MSAL v2, deves consultar este guia primeiro para migrar para o MSAL v3. Se vens do MSAL v3, deves consultar este guia primeiro para migrar para o MSAL v4 e depois seguir os próximos passos.

Se vens do MSAL v4, podes seguir este guia para atualizar o teu código e usar o MSAL v5.

Alterações incompatíveis da API

O tipo de retorno SignedHttpRequest.removeKeys foi alterado

A função na removeKeys classe agora retorna SignedHttpRequest em vez de Promise<void>.Promise<boolean> Uma resolução bem-sucedida da promessa é agora equivalente ao que anteriormente era um valor de retorno de true. Se ocorrer uma falha, é agora apresentado como um erro em vez 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 e loadExternalTokens

A API do MSAL JS para loadExternalTokens foi modificada. As alterações incluem:

  • TokenCache objeto e getTokenCache() foram removidos
  • A loadExternalTokens() API é agora uma exportação separada e requer 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 A assinatura da API mudou

Anteriormente, PublicClientApplication.handleRedirectPromise incluía um parâmetro de hash opcional. Foi introduzido um novo tipo de opções HandleRedirectPromiseOptions chamado. A partir do MSAL Browser v5, um objeto opcional do tipo HandleRedirectPromiseOptions é o único parâmetro que handleRedirectPromise() aceita.

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

Remoção de algumas funções em PublicClientApplication

As seguintes funções em PublicClientApplication foram removidas:

  1. enableAccountStorageEvents() e disableAccountStorageEvents(): os eventos de armazenamento da conta estão agora sempre ativados. Estas chamadas de função já não são necessárias.

  2. getAccountByHomeId(), getAccountByLocalId(), e getAccountByUsername(): usa getAccount() em vez disso.

    // 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(): usar logoutRedirect() ou logoutPopup() em vez disso.

Remoção de startPerformanceMeasurement()

startPerformanceMeasurement() foi removido. Por favor, use startMeasurement() em vez disso.

Remoção de PublicClientNext

A PublicClientNext classe e o seu método createPublicClientApplication() estático foram removidos na MSAL v5. Deve utilizar uma das seguintes alternativas, dependendo dos requisitos da sua candidatura:

  • PublicClientApplication: Use isto para cenários padrão de aplicação única. Este é o uso padrão e mais comum.
  • createNestablePublicClientApplication: Utilize esta opção se precisar de suportar aplicações aninhadas (NAA). Esta função reverte automaticamente para uma PublicClientApplication padrão se o bridge da aplicação aninhada não estiver disponível ou se o Hub não estiver configurado para suportar a autenticação de aplicação aninhada. Consulte Configuração de Aplicação Incorporada para mais detalhes.
  • createStandardPublicClientApplication: Use isto para instanciar e inicializar uma instância PublicClientApplication padrão (não NAA).

Exemplo de Migração

// 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 a maioria das aplicações, substituir PublicClientNext.createPublicClientApplication(config) por new PublicClientApplication(config) é suficiente. Se já usou a supportsNestedAppAuth opção de configuração, migre para createNestablePublicClientApplication(config) em vez disso.

Remoção da função estática PublicClientApplication.createPublicClientApplication

A função estática createPublicClientApplication de PublicClientApplication foi removida e substituída por uma createStandardPublicClientApplication exportada separadamente.

Exemplo de Migração

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

Alterações de configuração

Alterações no BrowserAuthOptions

  1. O skipAuthorityMetadataCache parâmetro foi removido do BrowserAuthOptions na Configuração.

  2. O protocolMode parâmetro foi movido para SystemOptions em vez de BrowserAuthOptions em Configuration.

  3. O supportsNestedAppAuth parâmetro foi removido. Utilize a createNestablePublicClientApplication API para Nested Apps em alternativa. Leia mais sobre as Apps Nested aqui.

  4. O parâmetro navigateTologinRequestUrl foi removido de BrowserAuthOptions em Configuration e pode agora, em vez disso, ser fornecido num objeto de opções como parâmetro na chamada a handleRedirectPromise:

    pca.handleRedirectPromise({ navigateToLoginRequestUrl: false });
    
  5. O encodeExtraQueryParams parâmetro foi removido. Todos os parâmetros de consulta extra são codificados.

  6. O supportsNestedAppAuth parâmetro foi removido. Utilize createNestablePublicClientApplication() em substituição.

        // 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. O OIDCOptions parâmetro agora assume um ResponseMode em vez de um ServerResponseType. Por favor, use ResponseMode.QUERY no lugar de ServerResponseType.QUERY e ResponseMode.FRAGMENT em vez de ServerResponseType.FRAGMENT.

Alterações no CacheOptions

Os seguintes parâmetros foram obsoletos no MSAL Browser v4 e foram removidos na CacheOptions v5:

  1. temporaryCacheLocation
  2. claimsBasedCachingEnabled - Os tokens de acesso deixaram de ser armazenados com base em reivindicações solicitadas.
  3. storeAuthStateInCookie
  4. secureCookies - Todos os cookies são agora enviados apenas de forma segura via HTTPS.
  5. cacheMigrationEnabled

Opções do Sistema

  1. O protocolMode parâmetro foi movido para SystemOptions de BrowserAuthOptions em Configuração. Não há alterações nas suas opções ou funcionalidades.
  2. O navigateFrameWait parâmetro foi removido. Isto era anteriormente necessário para navegadores mais antigos que já não são suportados pela MSAL.js.
  3. Os iframeHashTimeout parâmetros e windowHashTimeout foram substituídos por iframeBridgeTimeout e popupBridgeTimeout respetivamente. Estes tempos limite passam agora a controlar quanto tempo se deve esperar por uma resposta da ponte de redirecionamento através da API BroadcastChannel.

asyncPopups

O parâmetro asyncPopups foi renomeado para navigatePopups em SystemOptions e as opções foram invertidas. Isto define se os pop-ups são abertos e acedidos mais tarde. Quando definido como true, surgem popups em branco e navegam até ao domínio de login. Quando definido como falso, os pop-ups são abertos diretamente no domínio de login. Isto pode ser definido como falso em cenários onde about:blank não é suportado, por exemplo, aplicações de ambiente de trabalho ou aplicações web progressivas.

Importante

Por defeito, navigatePopups está agora definido para true. Se usava asyncPopups antes, agora terá de mudar para navigatePopups e inverter a configuração.

Consulte o documento de Configuração para mais detalhes.

Alterações a pedido

Remoção do onRedirectNavigate parâmetro

O parâmetro onRedirectNavigateapenas é suportado no objeto Configuration daqui em diante e foi removido dos objetos RedirectRequest e EndSessionRequest. Por favor, certifica-te de o definir na configuração MSAL se precisares de o usar.

Consolidação de parâmetros adicionais do pedido

Os seguintes parâmetros de pedido foram removidos:

  • authorizePostBodyParams
  • tokenBodyParameters
  • tokenQueryParameters

Para simplificar os parâmetros adicionais do pedido, os parâmetros adicionais genéricos devem ser colocados na nova opção de pedido extraParameters. Quando extraParameters são definidos num pedido, são enviados em todas as chamadas ao serviço de token, quer na cadeia de consulta do URL quer no corpo do pedido, dependendo da configuração httpMethod definida no pedido (o padrão é GET). Para submeter parâmetros adicionais que DEVEM ir na cadeia de consulta do URL, extraQueryParameters continua disponível.

Note

Se não tem a certeza se o parâmetro extra deve ser inserido extraQueryStringParameters ou extraParameters, provavelmente deve ser inserido extraParameters.

Exemplo de pedido 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
    }
}

Exemplo de Pedido 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

Nos casos em que o MSAL determina que extraParameters deve ser codificado na string de URL, extraParameters é combinado com extraQueryParams de uma forma que faz com que os parâmetros com o mesmo nome sejam sobrescritos. Nestes casos, o valor do parâmetro em extraParameters tem precedência sobre o valor em extraQueryParams.

Cross-Origin-Opener-Policy (Suporte COOP)

O MSAL Browser v5 introduz suporte incorporado para Cross-Origin-Opener-Policy (COOP), que reforça a segurança ao isolar os contextos de navegação. Quando o serviço de autenticação (Microsoft Entra ID ou Azure AD B2C) envia cabeçalhos COOP, os fluxos tradicionais de autenticação com pop-up e com iframe silencioso ficam restringidos. O MSAL v5 fornece um mecanismo de ponte de redirecionamento para gerir a autenticação em ambientes com compatibilidade com COOP.

Note

O Microsoft Entra ID (anteriormente Azure AD) tem o COOP ativado por defeito. Para Azure AD B2C, a disponibilidade do COOP depende da configuração do backend e dos endpoints de autenticação utilizados.

O que mudou

Quando os cabeçalhos COOP estão presentes na resposta do serviço de autenticação (por exemplo, Cross-Origin-Opener-Policy: same-origin), os fluxos tradicionais de autenticação iframe e popup silencioso falham porque a janela de autenticação não consegue comunicar de volta à janela principal da aplicação. O MSAL v5 resolve este problema ao introduzir um padrão de ponte de redirecionamento.

Todos os fluxos de autenticação (acquireTokenSilent(), ssoSilent(), loginPopup(), e loginRedirect()) usam agora a ponte de redirecionamento. A ponte de redirecionamento trata a resposta de autenticação de forma diferente consoante o fluxo:

  • Janela pop-up e fluxos silenciosos: A ponte de redirecionamento difunde a resposta de autenticação para a janela principal da aplicação através da API BroadcastChannel
  • Fluxo de redirecionamento: A ponte de redirecionamento navega de volta para a página da sua aplicação que iniciou o redirecionamento com a resposta de autenticação na URL

Como funciona

  1. Aplicação principal: A sua aplicação inicia a autenticação usando loginPopup(), ssoSilent(), ou loginRedirect()
  2. Redirecionamento: MSAL abre um popup/iframe/janela para uma página de autoridade
  3. Fluxo de autenticação: A página de autoridade completa o fluxo OAuth e recebe a resposta de autenticação
  4. Gestão de respostas: A página de redirecionamento utiliza a nova broadcastResponseToMainFrame() função que:
    • Para fluxos popup/silenciosos: Transmite a resposta para a janela principal via API do BroadcastChannel
    • Para fluxos de redirecionamento: Navega até à página a partir da qual o acquireTokenRedirect é iniciado com a resposta de autenticação
  5. Aquisição de tokens: A aplicação principal recebe a resposta e conclui a aquisição de tokens

Etapas de migração

1. Configurar a página da ponte de redirecionamento

Crie uma página que chame broadcastResponseToMainFrame() a partir de @azure/msal-browser/redirect-bridge. Esta página NÃO deve ser servida com cabeçalhos COOP.

A configuração varia consoante o sistema de construção — veja o guia Redirect Bridge — Framework-Specific Setup :

Framework Approach
Angular Componente de rota + ativos opcionais angular.json
Vite Várias páginas rollupOptions.input
Webpack Entrada separada + HtmlWebpackPlugin
Next.js Componente da página excluído de MsalProvider
CRA (Criar Aplicação React) Página estática public/redirect.html
Express.js Exclusão de cabeçalhos COOP do lado do servidor

Ver também:Considerações sobre o URI de redirecionamento | Erros de interaction_in_progress em janelas de pop-up | MDN: COOP

2. Atualize a sua configuração MSAL

Aponte redirectUri para uma nova página de ponte de redirecionamento:

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

Importante

DEVE também atualizar o URI de redirecionamento no registo da sua aplicação Entra ID. O URI deve corresponder exatamente — incluindo caminho, protocolo e porta. Não o fazer resulta em redirect_uri_mismatch erros.

Mudanças de Quebra Comportamental

Tipos de eventos e alterações de InteractionStatus

Consolidámos os tipos de eventos e o InteractionStatus para refletir o que aconteceu, em vez de em que API aconteceu.

  1. SSO_SILENTe ACQUIRE_TOKEN_BY_CODE os eventos foram substituídos por ACQUIRE_TOKEN eventos (START/SUCCESS/FAILUREvariantes)
  2. ACCOUNT_ADDED e ACCOUNT_REMOVED foram substituídos por LOGIN_SUCCESS e LOGOUT_SUCCESS, respetivamente.
  3. LOGIN_START e LOGIN_FAILURE foram substituídos por ACQUIRE_TOKEN_START e ACQUIRE_TOKEN_FAILURE, respetivamente.
  4. A carga útil de LOGIN_SUCCESS é agora um objeto AccountInfo.
  5. Qualquer início de sessão bem-sucedido emite agora um evento LOGIN_SUCCESS e um evento ACQUIRE_TOKEN_SUCCESS.

LOGIN_SUCCESS Migração do tipo de carga útil

Se o callback do seu evento atualmente faz a conversão de cargas úteis LOGIN_SUCCESS para AuthenticationResult, atualize-o para utilizar AccountInfo para LOGIN_SUCCESS e 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);
    }
});

Alterações no formato da mensagem de erro

Para reduzir o tamanho do bundle, as mensagens de erro foram movidas para fora do bundle. Quando um erro é lançado, a message propriedade devolve agora um link genérico para a documentação de erro em vez de uma mensagem de erro descritiva:

// 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";

A errorCode propriedade mantém-se inalterada e ainda pode ser usada para identificar o erro específico. Para descrições detalhadas de erros, consulte a documentação de erros.

Importante

Se a sua aplicação depender da análise ou exibição da error.message propriedade, poderá precisar de atualizar o seu código de gestão de erros para usar o errorCode instead ou direcionar os utilizadores para o link de documentação.

Atualização do Código de Gestão de Erros

Se mostrar erros aos utilizadores, mapeie errorCode para mensagens fáceis de usar em vez de mostrar error.message diretamente:

// 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.");

Se fizer o parsing de erros para lógica condicional, deixe de fazer correspondência de cadeias em message para comparar errorCode (esta já era a abordagem recomendada na versão 4):

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

Se registar erros para fins de diagnóstico, inclua ambos errorCode e message (a mensagem contém agora uma ligação direta para a documentação relevante):

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

Sugestão

Os errorCode valores são os mesmos entre v4 e v5 — apenas o message formato mudou. Se o seu código já se ramifica em errorCode, não são necessárias alterações.

Alterações no registo da consola

Para reduzir o tamanho do pacote, as mensagens de registo da consola são agora codificadas com hash. Em vez de ver as mensagens de registo completas na consola do navegador, verá um 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

A depuração na consola do navegador requer um passo adicional para decodificar os registos. Para descodificar registos com hash novamente em mensagens legíveis, use o script de descodificação. Para mais informações sobre a utilização do script de decodificação, consulte a documentação do script.