Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Это важно
Начиная с 1 мая 2025 г. Azure AD B2C больше не будет доступен для приобретения для новых клиентов. Дополнительные сведения см. в разделе "Вопросы и ответы".
В этой статье показано, как добавить проверку подлинности Azure Active Directory B2C (Azure AD B2C) в собственное одностраничное приложение (SPA). Узнайте, как создать приложение SPA с помощью библиотеки проверки подлинности Майкрософт для JavaScript (MSAL.js).
Используйте эту статью с настройкой проверки подлинности в примере приложения SPA, заменив пример приложения SPA собственным приложением SPA.
Обзор
В этой статье используется Node.js и Express для создания базового веб-приложения Node.js. Express — это минимальная и гибкая платформа веб-приложений Node.js, которая предоставляет набор функций для веб-приложений и мобильных приложений.
Библиотека аутентификации MSAL.js от компании Microsoft упрощает добавление поддержки аутентификации и авторизации в SPA-приложения.
Подсказка
Весь MSAL.js код выполняется на стороне клиента. Вы можете заменить серверный код Node.js и Express другими решениями, такими как платформы .NET Core, Java и скриптовые языки, такие как гипертекстовый препроцессор (PHP).
Предпосылки
Сведения о предварительных требованиях и инструкциях по интеграции см. в разделе "Настройка проверки подлинности" в примере приложения SPA.
Шаг 1. Создание проекта приложения SPA
Вы можете использовать существующий проект приложения SPA или создать новый. Чтобы создать проект, сделайте следующее:
Откройте командную оболочку и создайте новый каталог (например, myApp). Этот каталог будет содержать код приложения, пользовательский интерфейс и файлы конфигурации.
Введите созданный каталог.
npm initИспользуйте команду для созданияpackage.jsonфайла для приложения. Эта команда содержит сведения о приложении (например, имя и версия приложения, а также имя начальной точки входа, файл index.js ). Выполните следующую команду и примите значения по умолчанию:
npm init
Шаг 2: Установите зависимости
Чтобы установить пакет Express, в командной оболочке выполните следующую команду:
npm install express
Чтобы найти статические файлы приложения, серверный код использует пакет Path .
Чтобы установить пакет Path, в командной оболочке выполните следующую команду:
npm install path
Шаг 3. Настройка веб-сервера
В папке myApp создайте файл с именем index.js, который содержит следующий код:
// Initialize express
const express = require('express');
const app = express();
// The port to listen to incoming HTTP requests
const port = 6420;
// Initialize path
const path = require('path');
// Set the front-end folder to serve public assets.
app.use(express.static('App'));
// Set up a route for the index.html
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname + '/index.html'));
});
// Start the server, and listen for HTTP requests
app.listen(port, () => {
console.log(`Listening on http://localhost:${port}`);
});
Шаг 4. Создание пользовательского интерфейса SPA
Добавьте файл SPA-приложения index.html. Этот файл реализует пользовательский интерфейс, созданный с помощью фреймворка Bootstrap, и импортирует файлы скриптов для конфигурации, проверки подлинности и вызовов веб-API.
Ресурсы, на которые ссылается файлindex.html , подробно описаны в следующей таблице:
| Справка | Определение |
|---|---|
| библиотека MSAL.js | MSAL.js библиотека JavaScript для аутентификации путь CDN. |
| Таблица стилей Bootstrap | Бесплатная интерфейсная платформа для ускорения и упрощения веб-разработки. Платформа включает шаблоны проектирования на основе HTML и CSS. |
Чтобы отобразить файл индекса SPA в папке myApp , создайте файл с именем index.html, содержащий следующий фрагмент HTML:
<!DOCTYPE html>
<html>
<head>
<title>My Azure AD B2C test app</title>
</head>
<body>
<h2>My Azure AD B2C test app</h2>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous" />
<button type="button" id="signIn" class="btn btn-secondary" onclick="signIn()">Sign-in</button>
<button type="button" id="signOut" class="btn btn-success d-none" onclick="signOut()">Sign-out</button>
<h5 id="welcome-div" class="card-header text-center d-none"></h5>
<br />
<!-- Content -->
<div class="card">
<div class="card-body text-center">
<pre id="response" class="card-text"></pre>
<button type="button" id="callApiButton" class="btn btn-primary d-none" onclick="passTokenToApi()">Call API</button>
</div>
</div>
<script src="https://alcdn.msauth.net/browser/2.14.2/js/msal-browser.min.js" integrity="sha384-ggh+EF1aSqm+Y4yvv2n17KpurNcZTeYtUZUvhPziElsstmIEubyEB6AIVpKLuZgr" crossorigin="anonymous"></script>
<!-- Importing app scripts (load order is important) -->
<script type="text/javascript" src="./apiConfig.js"></script>
<script type="text/javascript" src="./policies.js"></script>
<script type="text/javascript" src="./authConfig.js"></script>
<script type="text/javascript" src="./ui.js"></script>
<!-- <script type="text/javascript" src="./authRedirect.js"></script> -->
<!-- uncomment the above line and comment the line below if you would like to use the redirect flow -->
<script type="text/javascript" src="./authRedirect.js"></script>
<script type="text/javascript" src="./api.js"></script>
</body>
</html>
Шаг 5. Настройка библиотеки проверки подлинности
Настройте интеграцию библиотеки MSAL.js с Azure AD B2C. Библиотека MSAL.js использует общий объект конфигурации для подключения к конечным точкам проверки подлинности клиента Azure AD B2C.
Чтобы настроить библиотеку проверки подлинности, сделайте следующее:
В папке myApp создайте новую папку с именем App.
В папке приложения создайте новый файл с именем authConfig.js.
Добавьте следующий код JavaScript в файл authConfig.js :
const msalConfig = { auth: { clientId: "<Application-ID>", authority: b2cPolicies.authorities.signUpSignIn.authority, knownAuthorities: [b2cPolicies.authorityDomain], redirectUri: "http://localhost:6420", }, cache: { cacheLocation: "localStorage", . storeAuthStateInCookie: false, } }; const loginRequest = { scopes: ["openid", ...apiConfig.b2cScopes], }; const tokenRequest = { scopes: [...apiConfig.b2cScopes], forceRefresh: false };Замените
<Application-ID>идентификатором регистрации вашего приложения. Дополнительные сведения см. в разделе "Настройка проверки подлинности" в примере приложения SPA.
Подсказка
Дополнительные параметры конфигурации объектов MSAL см. в статье "Параметры проверки подлинности ".
Шаг 6. Указание потоков пользователей Azure AD B2C
Создайте файлpolicies.js , который предоставляет сведения о среде Azure AD B2C. Библиотека MSAL.js использует эти сведения для создания запросов проверки подлинности в Azure AD B2C.
Чтобы указать потоки пользователей Azure AD B2C, сделайте следующее:
В папке приложения создайте новый файл с именем policies.js.
Добавьте следующий код в файл policies.js :
const b2cPolicies = { names: { signUpSignIn: "B2C_1_SUSI", editProfile: "B2C_1_EditProfile" }, authorities: { signUpSignIn: { authority: "https://contoso.b2clogin.com/contoso.onmicrosoft.com/Your-B2C-SignInOrSignUp-Policy-Id", }, editProfile: { authority: "https://contoso.b2clogin.com/contoso.onmicrosoft.com/Your-B2C-EditProfile-Policy-Id" } }, authorityDomain: "contoso.b2clogin.com" }Замените
B2C_1_SUSIна имя политики Azure AD B2C для входа.Замените
B2C_1_EditProfileименем политики редактирования профиля Azure AD B2C.Замените все вхождения
contosoименем вашего клиента Azure AD B2C.
Шаг 7. Использование MSAL для входа пользователя
На этом шаге реализуйте методы для инициализации потока входа, получения маркера доступа API и методов выхода.
Для получения дополнительной информации см. статью Использование библиотеки аутентификации Microsoft (MSAL) для входа пользователя.
Чтобы войти в систему, выполните указанные ниже действия.
В папке приложения создайте новый файл с именем authRedirect.js.
В authRedirect.jsскопируйте и вставьте следующий код:
// Create the main myMSALObj instance // configuration parameters are located at authConfig.js const myMSALObj = new msal.PublicClientApplication(msalConfig); let accountId = ""; let idTokenObject = ""; let accessToken = null; myMSALObj.handleRedirectPromise() .then(response => { if (response) { /** * For the purpose of setting an active account for UI update, we want to consider only the auth response resulting * from SUSI flow. "tfp" claim in the id token tells us the policy (NOTE: legacy policies may use "acr" instead of "tfp"). * To learn more about B2C tokens, visit https://learn.microsoft.com/azure/active-directory-b2c/tokens-overview */ if (response.idTokenClaims['tfp'].toUpperCase() === b2cPolicies.names.signUpSignIn.toUpperCase()) { handleResponse(response); } } }) .catch(error => { console.log(error); }); function setAccount(account) { accountId = account.homeAccountId; idTokenObject = account.idTokenClaims; myClaims= JSON.stringify(idTokenObject); welcomeUser(myClaims); } function selectAccount() { /** * See here for more information on account retrieval: * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-common/docs/Accounts.md */ const currentAccounts = myMSALObj.getAllAccounts(); if (currentAccounts.length < 1) { return; } else if (currentAccounts.length > 1) { /** * Due to the way MSAL caches account objects, the auth response from initiating a user-flow * is cached as a new account, which results in more than one account in the cache. Here we make * sure we are selecting the account with homeAccountId that contains the sign-up/sign-in user-flow, * as this is the default flow the user initially signed-in with. */ const accounts = currentAccounts.filter(account => account.homeAccountId.toUpperCase().includes(b2cPolicies.names.signUpSignIn.toUpperCase()) && account.idTokenClaims.iss.toUpperCase().includes(b2cPolicies.authorityDomain.toUpperCase()) && account.idTokenClaims.aud === msalConfig.auth.clientId ); if (accounts.length > 1) { // localAccountId identifies the entity for which the token asserts information. if (accounts.every(account => account.localAccountId === accounts[0].localAccountId)) { // All accounts belong to the same user setAccount(accounts[0]); } else { // Multiple users detected. Logout all to be safe. signOut(); }; } else if (accounts.length === 1) { setAccount(accounts[0]); } } else if (currentAccounts.length === 1) { setAccount(currentAccounts[0]); } } // in case of page refresh selectAccount(); async function handleResponse(response) { if (response !== null) { setAccount(response.account); } else { selectAccount(); } } function signIn() { myMSALObj.loginRedirect(loginRequest); } function signOut() { const logoutRequest = { postLogoutRedirectUri: msalConfig.auth.redirectUri, }; myMSALObj.logoutRedirect(logoutRequest); } function getTokenRedirect(request) { request.account = myMSALObj.getAccountByHomeId(accountId); return myMSALObj.acquireTokenSilent(request) .then((response) => { // In case the response from B2C server has an empty accessToken field // throw an error to initiate token acquisition if (!response.accessToken || response.accessToken === "") { throw new msal.InteractionRequiredAuthError; } else { console.log("access_token acquired at: " + new Date().toString()); accessToken = response.accessToken; passTokenToApi(); } }).catch(error => { console.log("Silent token acquisition fails. Acquiring token using popup. \n", error); if (error instanceof msal.InteractionRequiredAuthError) { // fallback to interaction when silent call fails return myMSALObj.acquireTokenRedirect(request); } else { console.log(error); } }); } // Acquires and access token and then passes it to the API call function passTokenToApi() { if (!accessToken) { getTokenRedirect(tokenRequest); } else { try { callApi(apiConfig.webApi, accessToken); } catch(error) { console.log(error); } } } function editProfile() { const editProfileRequest = b2cPolicies.authorities.editProfile; editProfileRequest.loginHint = myMSALObj.getAccountByHomeId(accountId).username; myMSALObj.loginRedirect(editProfileRequest); }
Шаг 8. Настройка расположения и области веб-API
Чтобы разрешить приложению SPA вызывать веб-API, укажите расположение конечной точки веб-API и области , используемые для авторизации доступа к веб-API.
Чтобы настроить расположение и области веб-API, сделайте следующее:
В папке приложения создайте новый файл с именем apiConfig.js.
В apiConfig.jsскопируйте и вставьте следующий код:
// The current application coordinates were pre-registered in a B2C tenant. const apiConfig = { b2cScopes: ["https://contoso.onmicrosoft.com/tasks/tasks.read"], webApi: "https://mydomain.azurewebsites.net/tasks" };Замените
contosoименем своего клиента. Необходимое имя области можно найти, как описано в статье "Настройка областей ".Замените значение
webApiна адрес вашей конечной точки веб-API.
Шаг 9. Вызов веб-API
Определите HTTP-запрос к конечной точке API. HTTP-запрос настроен на передачу токена доступа, который был получен с MSAL.js, в заголовок HTTP Authorization в запросе.
Следующий код определяет HTTP-запрос GET к конечной точке API, передав маркер доступа в заголовке Authorization HTTP. Расположение API определяется ключом webApi в apiConfig.js.
Чтобы обратиться к вашему веб-API с помощью полученного токена, сделайте следующее:
В папке приложения создайте новый файл с именем api.js.
Добавьте следующий код в файл api.js :
function callApi(endpoint, token) { const headers = new Headers(); const bearer = `Bearer ${token}`; headers.append("Authorization", bearer); const options = { method: "GET", headers: headers }; logMessage('Calling web API...'); fetch(endpoint, options) .then(response => response.json()) .then(response => { if (response) { logMessage('Web API responded: ' + response.name); } return response; }).catch(error => { console.error(error); }); }
Шаг 10. Добавление ссылки на элементы пользовательского интерфейса
Приложение SPA использует JavaScript для управления элементами пользовательского интерфейса. Например, он показывает кнопки входа и выхода, а также выводит данные токена идентификатора пользователей на экран.
Чтобы добавить ссылку на элементы пользовательского интерфейса, сделайте следующее:
В папке приложения создайте файл с именем ui.js.
Добавьте следующий код в файл ui.js :
// Select DOM elements to work with const signInButton = document.getElementById('signIn'); const signOutButton = document.getElementById('signOut') const titleDiv = document.getElementById('title-div'); const welcomeDiv = document.getElementById('welcome-div'); const tableDiv = document.getElementById('table-div'); const tableBody = document.getElementById('table-body-div'); const editProfileButton = document.getElementById('editProfileButton'); const callApiButton = document.getElementById('callApiButton'); const response = document.getElementById("response"); const label = document.getElementById('label'); function welcomeUser(claims) { welcomeDiv.innerHTML = `Token claims: </br></br> ${claims}!` signInButton.classList.add('d-none'); signOutButton.classList.remove('d-none'); welcomeDiv.classList.remove('d-none'); callApiButton.classList.remove('d-none'); } function logMessage(s) { response.appendChild(document.createTextNode('\n' + s + '\n')); }
Шаг 11. Запуск приложения SPA
В командной оболочке выполните следующие команды:
npm install
npm ./index.js
- Перейдите по адресу https://localhost:6420.
- Выберите Вход.
- Завершите процесс регистрации или входа в систему.
После успешной проверки подлинности на экране отображается проанализированный токен идентификатора. Выберите Call API для вызова конечной точки API.
Дальнейшие шаги
- Дополнительные сведения о примере кода.
- Настройте параметры проверки подлинности в собственном приложении SPA с помощью Azure AD B2C.
- Включение проверки подлинности в собственном веб-API.