Миграция из MSAL Browser версии 4 в версию 5

Если вы не знакомы с MSAL, вы должны начать здесь.

Если вы поступаете из MSAL версии 2, сначала ознакомьтесь с этим руководством , чтобы перейти на MSAL версии 3. Если вы поступаете из MSAL версии 3, сначала проверьте это руководство , чтобы перейти на MSAL версии 4, а затем выполните следующие действия.

Если вы поступаете из MSAL версии 4, вы можете следовать этому руководству, чтобы обновить код для использования MSAL версии 5.

Критические изменения API

Тип возвращаемого значения SignedHttpRequest.removeKeys изменился

Функция removeKeys в SignedHttpRequest классе теперь возвращается Promise<void> вместо Promise<boolean>. Успешное выполнение промиса теперь эквивалентно прежнему возвращаемому значению true. Если происходит сбой, он теперь создается как ошибка, а не возвращается 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 и loadExternalTokens

API MSAL JS для loadExternalTokens изменяется. Ниже представлены изменения.

  • TokenCache объект и getTokenCache() удалены
  • loadExternalTokens() API теперь является отдельным экспортом и требуется Configuration в качестве параметра
// BEFORE

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

//AFTER

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

handleRedirectPromise Сигнатура API изменилась

Ранее PublicClientApplication.handleRedirectPromise принимал необязательный хеш-параметр. Был введен новый тип HandleRedirectPromiseOptions параметров. Начиная с MSAL Browser v5, необязательный объект типа HandleRedirectPromiseOptions — единственный параметр, который принимает handleRedirectPromise().

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

Удаление некоторых функций в PublicClientApplication

Были удалены следующие функции PublicClientApplication :

  1. enableAccountStorageEvents() и disableAccountStorageEvents(): события хранения учетных записей теперь всегда включены. Эти вызовы функций больше не требуются.

  2. getAccountByHomeId(), getAccountByLocalId()и getAccountByUsername(): используйте getAccount() вместо него.

    // 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(): используйте logoutRedirect() или logoutPopup() вместо этого.

Удаление startPerformanceMeasurement()

startPerformanceMeasurement() удален. Взамен рекомендуется использовать startMeasurement().

Удаление PublicClientNext

Класс и его статический PublicClientNext метод createPublicClientApplication() были удалены в MSAL версии 5. В зависимости от требований приложения следует использовать один из следующих вариантов:

  • PublicClientApplication: используйте это для стандартных сценариев с одним приложением. Это значение по умолчанию и наиболее распространенное использование.
  • createNestablePublicClientApplication: используйте это, если необходимо поддерживать вложенные приложения (NAA). Эта функция автоматически возвращается к стандартной версии PublicClientApplication, если вложенный мост приложения недоступен или Концентратор не настроен для поддержки вложенной проверки подлинности приложения. Дополнительные сведения см. в разделе "Конфигурация вложенных приложений ".
  • createStandardPublicClientApplication: Используйте это, чтобы создать и инициализировать стандартный экземпляр PublicClientApplication (не NAA).

Пример миграции

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

Для большинства приложений замены PublicClientNext.createPublicClientApplication(config) на new PublicClientApplication(config) достаточно. Если вы ранее использовали параметр конфигурации supportsNestedAppAuth, перейдите на createNestablePublicClientApplication(config).

Удаление статической функции PublicClientApplication.createPublicClientApplication

Статическая createPublicClientApplication функция PublicClientApplication удалена и заменена отдельно экспортируемой createStandardPublicClientApplicationфункцией.

Пример миграции

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

Изменения конфигурации

Изменения в BrowserAuthOptions

  1. Параметр skipAuthorityMetadataCache удален из BrowserAuthOptions в конфигурации.

  2. Параметр protocolMode был перемещен в SystemOptions вместо BrowserAuthOptions в конфигурации.

  3. Параметр supportsNestedAppAuth удален. createNestablePublicClientApplication Вместо этого используйте API для вложенных приложений. Дополнительные сведения о вложенных приложениях см. здесь.

  4. Параметр navigateTologinRequestUrl был удален из BrowserAuthOptions в конфигурации и теперь может быть предоставлен внутри объекта options в качестве параметра для вызова handleRedirectPromise:

    pca.handleRedirectPromise({ navigateToLoginRequestUrl: false });
    
  5. Параметр encodeExtraQueryParams удален. Все дополнительные параметры запроса кодируются.

  6. Параметр supportsNestedAppAuth удален. Вместо этого используйте createNestablePublicClientApplication().

        // 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. Теперь параметр OIDCOptions принимает ResponseMode вместо ServerResponseType. Используйте ResponseMode.QUERY вместо ServerResponseType.QUERY и ResponseMode.FRAGMENT вместо ServerResponseType.FRAGMENT.

Изменения в CacheOptions

Следующие параметры устарели в MSAL Browser версии 4 и удалены из CacheOptions версии 5:

  1. temporaryCacheLocation
  2. claimsBasedCachingEnabled — Токены доступа больше не сохраняются в зависимости от запрошенных утверждений.
  3. storeAuthStateInCookie
  4. secureCookies - Все файлы cookie теперь всегда безопасно отправляются по протоколу HTTPS.
  5. cacheMigrationEnabled

Параметры системы

  1. Параметр protocolMode был перемещен из BrowserAuthOptions в SystemOptions в разделе «Конфигурация». Изменения его параметров или функциональных возможностей отсутствуют.
  2. Параметр navigateFrameWait удален. Ранее это было необходимо старым браузерам, которые больше не поддерживаются MSAL.js.
  3. Параметры iframeHashTimeout и windowHashTimeout были заменены на iframeBridgeTimeout и popupBridgeTimeout соответственно. Теперь эти тайм-ауты определяют время ожидания ответа от моста перенаправления через API BroadcastChannel.

asyncPopups

Параметр asyncPopups был переименован navigatePopups в SystemOptions и изменены параметры. Этот параметр определяет, открываются ли всплывающие окна и выполняется ли переход к ним позже. Если установлено значение true, открываются пустые всплывающие окна и выполняется переход на домен входа. Если задано значение false, всплывающие окна открываются непосредственно в домене входа. Это значение может иметь значение false для сценариев, где about:blank не поддерживается, например классические приложения или прогрессивные веб-приложения.

Important

По умолчанию navigatePopups теперь имеет значение true. Если вы использовали asyncPopups раньше, вам придется изменить его на navigatePopups и отменить конфигурацию.

Дополнительные сведения см. в документации по конфигурации .

Изменения по запросу

onRedirectNavigate Удаление параметра

Параметр onRedirectNavigateподдерживается только начиная с объекта Configuration и удалён из объектов RedirectRequest и EndSessionRequest. Убедитесь, что установите его в msal config, если его нужно использовать.

Консолидация дополнительных параметров запроса

Были удалены следующие параметры запроса:

  • authorizePostBodyParams
  • tokenBodyParameters
  • tokenQueryParameters

Чтобы упростить дополнительные параметры запроса, универсальные дополнительные параметры следует использовать в новом extraParameters параметре запроса. Если в запросе заданы extraParameters, они отправляются при всех вызовах службы токенов либо в строке запроса URL, либо в теле запроса — в зависимости от значения httpMethod, заданного в запросе (по умолчанию — GET). Чтобы отправить дополнительные параметры, которые обязательно должны передаваться в строке URL-запроса, extraQueryParameters по-прежнему доступен.

Note

Если вы не уверены, в extraQueryStringParameters или extraParameters следует поместить дополнительный параметр, то, скорее всего, его следует поместить в extraParameters.

Пример запроса версии 4 (предыдущая версия):

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

Пример запроса версии 5

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

В случаях, когда MSAL определяет, что extraParameters необходимо закодировать в строке URL, extraParameters объединяется с extraQueryParams таким образом, что одноимённые параметры перезаписываются. В таких случаях значение параметра в extraParameters имеет приоритет над значением в extraQueryParams.

Поддержка Cross-Origin-Opener-Policy (COOP)

MSAL Browser v5 добавляет встроенную поддержку Cross-Origin-Opener-Policy (COOP), что повышает безопасность за счет изоляции контекстов браузера. Если служба аутентификации (Microsoft Entra ID или Azure AD B2C) возвращает заголовки COOP, традиционные потоки аутентификации через всплывающее окно и скрытый iframe ограничены. MSAL v5 предоставляет механизм моста переадресации для обработки аутентификации в средах с поддержкой COOP.

Note

Microsoft Entra ID (прежнее Azure AD) включает COOP по умолчанию. Для Azure AD B2C доступность COOP зависит от конфигурации серверной части и используемых конечных точек проверки подлинности.

Что изменилось

Если в ответе службы аутентификации присутствуют заголовки COOP (например, Cross-Origin-Opener-Policy: same-origin), традиционные потоки аутентификации через всплывающее окно и скрытый iframe не работают, поскольку окно аутентификации не может обмениваться данными с основным окном приложения. MSAL v5 решает эту проблему за счёт внедрения паттерна моста перенаправления.

Все потоки проверки подлинности (acquireTokenSilent(), иssoSilent()loginPopup()loginRedirect()) теперь используют мост перенаправления. Мост перенаправления обрабатывает ответ проверки подлинности по-разному в зависимости от потока:

  • Всплывающие и автоматические потоки: мост перенаправления передает ответ проверки подлинности в главное окно приложения с помощью API BroadcastChannel
  • Поток перенаправления: мост перенаправления возвращается на страницу приложения, которая инициировала перенаправление с ответом проверки подлинности в URL-адресе

Принцип работы

  1. Основное приложение: приложение инициирует проверку подлинности с помощью loginPopup(), ssoSilent()или loginRedirect()
  2. Перенаправление: MSAL открывает всплывающее окно/iframe/отдельное окно для перехода на страницу центра авторизации
  3. Поток аутентификации: страница центра авторизации завершает поток OAuth и получает ответ аутентификации.
  4. Обработка ответов: страница перенаправления использует новую broadcastResponseToMainFrame() функцию, которая:
    • Для всплывающих и молчаливых потоков: передает ответ на главное окно через API BroadcastChannel
    • Для потоков перенаправления: выполняется переход на страницу, с которой инициируется acquireTokenRedirect, с ответом аутентификации.
  5. Получение токена: основное приложение получает ответ и завершает получение токена.

Этапы миграции

1. Настройте страницу-посредник для перенаправления

Создайте страницу, которая вызывает broadcastResponseToMainFrame() из @azure/msal-browser/redirect-bridge. Эта страница не должна обслуживаться заголовками COOP.

Настройка зависит от системы сборки— см. руководство по настройке моста перенаправления Framework-Specific :

Framework Approach
Angular Компонент маршрута + необязательные angular.json ресурсы
Vite Многостраничный rollupOptions.input
Webpack Отдельная запись + HtmlWebpackPlugin
Next.js Компонент страницы исключен из MsalProvider
CRA (создание приложения React) Статическая public/redirect.html страница
Express.js Исключение заголовка COOP на стороне сервера

См. также:Рекомендации по URI перенаправления | Ошибки interaction_in_progress во всплывающем окне | MDN: COOP

2. Обновление конфигурации MSAL

Направьте redirectUri на новую страницу-посредник перенаправления:

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

Important

Необходимо также обновить URI перенаправления в регистрации приложения Entra ID. Универсальный код ресурса (URI) должен соответствовать точно — включая путь, протокол и порт. Невыполнение этого приводит к redirect_uri_mismatch ошибкам.

Поведенческие критические изменения

Типы событий и изменения InteractionStatus

Мы объединили типы событий и InteractionStatus, чтобы отразить то, что произошло, а не то, что произошло в API.

  1. SSO_SILENTи ACQUIRE_TOKEN_BY_CODE события заменены событиями ACQUIRE_TOKEN (START/SUCCESS/FAILUREвариантами)
  2. ACCOUNT_ADDED и ACCOUNT_REMOVED были заменены на LOGIN_SUCCESS и LOGOUT_SUCCESSсоответственно.
  3. LOGIN_START и LOGIN_FAILURE были заменены на ACQUIRE_TOKEN_START и ACQUIRE_TOKEN_FAILUREсоответственно.
  4. Полезная нагрузка для LOGIN_SUCCESS теперь представляет собой объект AccountInfo.
  5. При каждом успешном входе теперь генерируются события LOGIN_SUCCESS и ACQUIRE_TOKEN_SUCCESS.

LOGIN_SUCCESS миграция типа полезной нагрузки

Если ваш обработчик события сейчас приводит данные полезной нагрузки LOGIN_SUCCESS к типу AuthenticationResult, обновите его: используйте AccountInfo для LOGIN_SUCCESS, а AuthenticationResult оставьте для 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);
    }
});

Изменения формата сообщения об ошибке

Чтобы уменьшить размер пакета, сообщения об ошибках были перемещены из пакета. При возникновении message ошибки свойство теперь возвращает универсальную ссылку на документацию об ошибке вместо описательного сообщения об ошибке:

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

Свойство errorCode остается неизменным и по-прежнему может использоваться для выявления конкретной ошибки. Подробные описания ошибок см. в документации по ошибкам.

Important

Если приложение использует синтаксический анализ или отображение error.message свойства, может потребоваться обновить код обработки ошибок, чтобы использовать errorCode вместо этого или направить пользователей на ссылку документации.

Обновление кода обработки ошибок

Если вы показываете ошибки пользователям, сопоставьте errorCode с понятными пользователю сообщениями вместо того, чтобы показывать error.message напрямую:

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

Если вы анализируете ошибки для условной логики, переключитесь с сопоставления message строк на сравнение errorCode (это уже рекомендуемый подход в версии 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);
}

Если вы регистрируете ошибки диагностики, включите оба errorCode и message (сообщение теперь содержит прямую ссылку на соответствующую документацию):

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

Значения errorCode одинаковы в версиях v4 и v5 — изменился только формат message. Если в существующем коде уже есть ветвление по errorCode, изменения не требуются.

Изменения ведения журнала консоли

Чтобы уменьшить размер пакета, сообщения журнала консоли теперь хэшируются. Вместо просмотра полных сообщений журнала в консоли браузера вы увидите хэш-значение:

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

Отладка в консоли браузера требует дополнительного шага для декодирования журналов. Чтобы декодировать хэшированные журналы обратно в доступные для чтения сообщения, используйте скрипт декодирования. Дополнительные сведения об использовании скрипта декодирования см. в документации по скрипту.