Настройка проверки подлинности в примере одностраничного приложения с помощью Azure AD B2C

В этой статье используется пример одностраничного приложения (SPA) JavaScript для демонстрации того, как добавить проверку подлинности Azure Active Directory B2C (Azure AD B2C) в одностраничные приложения.

Обзор

OpenID Connect (OIDC) представляет собой протокол проверки подлинности, основанный на OAuth 2.0. Его можно использовать для безопасного входа пользователя в приложение. В этом примере одностраничного приложения используется MSAL.js и поток OIDC PKCE. MSAL.js — это предоставляемая корпорацией Майкрософт библиотека, упрощающая добавление поддержки проверки подлинности и авторизации в одностраничные приложения.

Поток входа в систему

Процесс входа включает следующие шаги:

  1. Пользователи переходят к веб-приложению и выбирают Вход.
  2. Приложение инициирует запрос на проверку подлинности и перенаправляет пользователей в Azure AD B2C.
  3. Пользователи регистрируются или входят в систему и сбрасывают пароль. Либо они могут использовать для входа учетную запись социальной сети.
  4. После входа пользователей Azure AD B2C возвращает приложению код авторизации.
  5. Одностраничное приложение проверяет маркер идентификатора, считывает утверждения, а затем позволяет пользователям вызывать защищенные ресурсы и API-интерфейсы.

Обзор регистрации приложений

Чтобы обеспечить вход в приложение с помощью Azure AD B2C и вызов веб-API, зарегистрируйте два приложения в каталоге Azure AD B2C.

  • Регистрация веб-приложения позволяет приложению выполнять вход с помощью Azure AD B2C. Во время регистрации вы указываете URI перенаправления. URI перенаправления — это конечная точка, в которую пользователи перенаправляются службой Azure AD B2C после завершения проверки подлинности с помощью Azure AD B2C. В процессе регистрации приложения создается идентификатор приложения, который также называется идентификатором клиента. Он однозначно идентифицирует ваше приложение.

  • Регистрация веб-API позволяет приложению вызывать безопасный веб-API. Регистрация включает области веб-API. Области предоставляют возможностью управления разрешениями для защищенных ресурсов, например веб-API. Вы предоставляете веб-приложению разрешения для областей веб-API. При запросе маркера доступа приложению необходимо указать нужные разрешения в параметре scope запроса.

Архитектура и регистрация приложения показаны на следующей схеме:

Схема веб-приложения с регистрациями и маркерами вызова веб-API.

Вызов веб-API

После завершения проверки подлинности пользователи взаимодействуют с приложением, которое вызывает защищенный веб-API. Этот веб-API использует проверку подлинности посредством маркера носителя. Маркер носителя — это маркер доступа, полученный приложением от Azure AD B2C. Приложение передает маркер в заголовке авторизации HTTPS-запроса.

Authorization: Bearer <access token>

Если область действия токена доступа не соответствует областям веб-API, библиотека аутентификации получает новый токен доступа с правильными областями.

Поток выхода

Поток выхода включает следующие шаги:

  1. В приложении пользователь выполняет выход.
  2. Приложение очищает объекты сеанса, а библиотека проверки подлинности очищает свой кэш маркеров.
  3. Приложение перенаправляет пользователя в конечную точку выхода Azure AD B2C, чтобы завершить сеанс Azure AD B2C.
  4. Пользователи перенаправляются обратно в приложение.

Необходимые компоненты

Компьютер, на котором работает:

Шаг 1. Настройка потока пользователя

Если пользователи пытаются войти в приложение, оно инициирует запрос проверки подлинности к конечной точке авторизации через поток пользователя. Соответствующий поток пользователя определяет и контролирует взаимодействие с пользователем. Когда пользователи завершают поток пользователя, Azure AD B2C создает маркер и перенаправляет пользователя обратно в приложение.

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

  • Объединенный пользовательский поток входа и регистрации, например susi. Этот пользовательский поток также поддерживает функцию Забыли пароль?.
  • Пользовательский поток редактирования профиля, например edit_profile.
  • Пользовательский поток сброса пароля, например reset_password.

Azure AD B2C добавляет B2C_1_ в начало имени пользовательского потока. Например, susi преобразуется в B2C_1_susi.

Шаг 2. Регистрация одностраничного приложения и API

На этом шаге вы создадите одностраничное приложение и регистрации приложения веб-API, а также укажете области веб-API.

Шаг 2.1. Регистрация приложения веб-API

Чтобы создать регистрацию приложения веб-API (идентификатор приложения: 2), выполните следующие действия.

  1. Войдите на портал Azure.

  2. Убедитесь, что вы используете каталог, содержащий клиент Azure AD B2C. На панели инструментов портала выберите значок Каталоги и подписки.

  3. В настройках портала на странице Каталоги и подписки найдите свой каталог Azure AD B2C в списке Имя каталога и выберите Переключить.

  4. В портале Azure найдите и выберите Azure AD B2C.

  5. Щелкните Регистрация приложений и выберите Новая регистрация.

  6. В поле Имя введите имя приложения (например, my-api1). Оставьте значения по умолчанию для URI перенаправления и поддерживаемых типов учетных записей.

  7. Выберите Зарегистрировать.

  8. Когда регистрация приложения завершится, выберите Обзор.

  9. Запишите значение идентификатора приложения (клиента) для дальнейшего использования при настройке веб-приложения.

    Снимок экрана, демонстрирующий, как получить идентификатор приложения веб-API

Шаг 2.2. Настройка областей

  1. Выберите созданное приложение my-api1 (идентификатор приложения: 2), чтобы открыть страницу Обзор.

  2. В разделе Управление выберите Предоставление API.

  3. Рядом с полем URI идентификатора приложения щелкните ссылку Задать. Замените значение по умолчанию (уникальный идентификатор) уникальным именем (например, tasks-api), а затем нажмите Сохранить.

    Когда веб-приложение запрашивает маркер доступа для веб-API, оно должно добавить этот URI в качестве префикса для каждой области, определяемой для API.

  4. В разделе Области, определенные этим API выберите Добавление области.

  5. Чтобы создать область, определяющую доступ для чтения к API, сделайте следующее.

    1. В поле Имя области введите tasks.read.
    2. В качестве отображаемого имени согласия администратора укажите Доступ на чтение к API задач.
    3. В качестве описания согласия администратора введите Предоставляет доступ на чтение к API задач.
  6. Выберите Добавить область.

  7. Выберите Добавить область и добавьте область, определяющую доступ для записи к API:

    1. В поле Имя области введите tasks.write.
    2. В качестве отображаемого имени согласия администратора укажите Доступ на запись к API задач.
    3. В качестве описания согласия администратора введите Предоставляет доступ на запись к API задач.
  8. Выберите Добавить область.

Шаг 2.3. Регистрация одностраничного приложения

Чтобы создать регистрацию одностраничного приложения, выполните следующие действия:

  1. Войдите на портал Azure.
  2. Если у вас есть доступ к нескольким клиентам, щелкните значок "Параметры " в верхнем меню, чтобы переключиться на клиент Azure AD B2C из меню каталогов и подписок .
  3. Найдите и выберите Azure AD B2C.
  4. Щелкните Регистрация приложений и выберите Новая регистрация.
  5. Введите Имя приложения (например, MyApp).
  6. В области Поддерживаемые типы учетных записей выберите Учетные записи в любом поставщике удостоверений или в организационном каталоге (для аутентификации пользователей с помощью потока пользователей).
  7. В разделе URI перенаправления выберите Одностраничное приложение (SPA), а затем введите http://localhost:6420 в текстовом поле URL-адреса.
  8. В разделе Разрешения установите флажок Предоставьте согласие администратора для разрешений openid и offline_access.
  9. Выберите Зарегистрировать.

Запишите значение параметра Идентификатор приложения (клиент) для использования на более позднем этапе при настройке веб-приложения.

Снимок экрана: страница обзора веб-приложения для записи идентификатора веб-приложения.

Шаг 2.4. Включение потока неявного предоставления разрешения

Вы можете включить неявный поток предоставления по двум причинам, если вы используете MSAL.js версии 1.3 или более ранней версии или при использовании регистрации приложения для тестирования потока пользователя.

Чтобы включить поток неявного предоставления для приложения, выполните следующие действия.

  1. Выберите созданную регистрацию приложения.

  2. В разделе Управление выберите Проверка подлинности.

  3. В разделе Потоки неявного предоставления разрешений и гибридные потоки установите флажки Маркеры доступа (используемые для потоков неявного предоставления разрешений) и Маркеры идентификатора (используемые для потоков неявного предоставления разрешений и гибридных потоков).

  4. Выберите Сохранить.

Примечание.

Если приложение использует MSAL.js версии 2.0 или более поздней версии, не включите неявный поток предоставления, так как MSAL.js 2.0+ поддерживает поток кода авторизации OAuth 2.0 (с PKCE). Если включить неявное предоставление для тестирования потока пользователя, убедитесь, что вы отключите параметры неявного потока предоставления перед развертыванием приложения в рабочей среде.

Шаг 2.5. Предоставление разрешений

Чтобы предоставить своему приложению (идентификатор приложения: 1) разрешения, выполните следующие действия.

  1. Выберите Регистрация приложений, а затем выберите созданное вами приложение (идентификатор приложения: 1).

  2. В разделе Управление выберите Разрешения API.

  3. В разделе Настроенные разрешения выберите Добавить разрешение.

  4. Выберите вкладку Мои API.

  5. Выберите API (идентификатор приложения: 2), к которому веб-приложению должен быть предоставлен доступ. Например, введите my-api1.

  6. В разделе Разрешение разверните узел tasks, а затем выберите определенные ранее области (например, tasks.read и tasks.write).

  7. Выберите Добавить разрешения.

  8. Выберите Предоставить согласие администратора для <имя арендатора>.

  9. Выберите Да.

  10. Выберите Обновить, а затем убедитесь, что Разрешено для... отображается в разделе Состояние для обеих областей.

  11. В списке настроенных разрешений выберите свою область, а затем скопируйте полное имя области.

    Снимок экрана настроенной панели разрешений, показывающий, что разрешения на чтение предоставлены

Шаг 3. Получение примера кода одностраничного приложения

В этом примере показано, как использовать Azure AD B2C в одностраничном приложении для регистрации и входа пользователя. Затем приложение получает маркер доступа и выполняет вызов к защищенному веб-API.

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

  • Скачайте ZIP-файл.

  • Клонируйте пример из GitHub, выполнив следующую команду:

    git clone https://github.com/Azure-Samples/ms-identity-b2c-javascript-spa.git
    

Шаг 3.1. Обновление примера одностраничного приложения

После скачивания примера одностраничного приложения обновите код, используя свои значения Azure AD B2C и веб-API. В папке примера в папке App откройте файлы JavaScript, перечисленные в следующей таблице, а затем измените их с использованием соответствующих значений.

Файлы Ключ Значение
authConfig.js clientId Идентификатор одностраничного приложения из шага 2.3.
policies.js Имена Потоки пользователей или настраиваемая политика из шага 1.
policies.js authorities Потоки пользователей Azure AD B2C или настраиваемые политики, такие как https://<your-tenant-name>.b2clogin.com/<your-tenant-name>.onmicrosoft.com/<your-sign-in-sign-up-policy>. Замените your-sign-in-sign-up-policy потоком пользователя или настраиваемой политикой из шага 1.
policies.js authorityDomain Домен центра Azure AD B2C, например <your-tenant-name>.b2clogin.com.
apiConfig.js b2cScopes Области веб-API, созданные на шаге 2.2 (например, b2cScopes: ["https://<your-tenant-name>.onmicrosoft.com/tasks-api/tasks.read"]).
apiConfig.js webApi URL-адрес веб-API — http://localhost:5000/hello.

Итоговый код должен выглядеть так, как в следующем примере:

authConfig.js:

const msalConfig = {
    auth: {
      clientId: "<your-MyApp-application-ID>", // This is the ONLY mandatory field; everything else is optional.
      authority: b2cPolicies.authorities.signUpSignIn.authority, // Choose sign-up/sign-in user-flow as your default.
      knownAuthorities: [b2cPolicies.authorityDomain], // You must identify your tenant's domain as a known authority.
      redirectUri: "http://localhost:6420", // You must register this URI on Azure Portal/App Registration. Defaults to "window.location.href".
    },
    cache: {
      cacheLocation: "sessionStorage",  
      storeAuthStateInCookie: false, 
    },
    system: {
      loggerOptions: {
        loggerCallback: (level, message, containsPii) => {
          if (containsPii) {
            return;
          }
          switch (level) {
            case msal.LogLevel.Error:
              console.error(message);
              return;
            case msal.LogLevel.Info:
              console.info(message);
              return;
            case msal.LogLevel.Verbose:
              console.debug(message);
              return;
            case msal.LogLevel.Warning:
              console.warn(message);
              return;
          }
        }
      }
    }
  };
};

const loginRequest = {
  scopes: ["openid", ...apiConfig.b2cScopes],
};

const tokenRequest = {
  scopes: [...apiConfig.b2cScopes],  // e.g. ["https://fabrikamb2c.onmicrosoft.com/helloapi/demo.read"]
  forceRefresh: false // Set this to "true" to skip a cached token and go to the server to get a new token
};

policies.js:

const b2cPolicies = {
    names: {
        signUpSignIn: "b2c_1_susi",
        forgotPassword: "b2c_1_reset",
        editProfile: "b2c_1_edit_profile"
    },
    authorities: {
        signUpSignIn: {
            authority: "https://your-tenant-name.b2clogin.com/your-tenant-name.onmicrosoft.com/b2c_1_susi",
        },
        forgotPassword: {
            authority: "https://your-tenant-name.b2clogin.com/your-tenant-name.onmicrosoft.com/b2c_1_reset",
        },
        editProfile: {
            authority: "https://your-tenant-name.b2clogin.com/your-tenant-name.onmicrosoft.com/b2c_1_edit_profile"
        }
    },
    authorityDomain: "your-tenant-name.b2clogin.com"
}

apiConfig.js:

const apiConfig = {
  b2cScopes: ["https://your-tenant-name.onmicrosoft.com/tasks-api/tasks.read"],
  webApi: "http://localhost:5000/hello"
};

Шаг 4. Получение примера кода веб-API

Теперь, когда веб-API зарегистрирован и вы определили области, настройте код веб-API для работы с арендатором Azure AD B2C.

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

Шаг 4.1. Обновление веб-API

  1. Откройте файл config.json в редакторе кода.

  2. Измените значения переменных на значения из созданной ранее регистрации приложения. Также обновите policyName, указав поток пользователя, созданный в рамках предварительных требований (например, b2c_1_susi).

    "credentials": {
        "tenantName": "<your-tenant-name>",
        "clientID": "<your-webapi-application-ID>"
    },
    "policies": {
        "policyName": "b2c_1_susi"
    },
    "resource": {
        "scope": ["tasks.read"] 
    },
    

Шаг 4.2. Включение CORS

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

Чтобы включить CORS, используйте следующее ПО промежуточного слоя. В скачанном примере кода веб-API Node.js оно уже добавлено в файл index.js.

app.use((req, res, next) => {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Authorization, Origin, X-Requested-With, Content-Type, Accept");
    next();
});

Шаг 5. Запуск одностраничного приложения и веб-API

Теперь вы готовы протестировать ограниченный областью доступ одностраничного приложения к API. Запустите веб-API Node.js и пример одностраничного приложения JavaScript на локальном компьютере. Затем войдите в одностраничное приложение и нажмите кнопку Вызов API, чтобы инициировать запрос к защищенному API.

Запуск веб-API для Node.js

  1. Откройте окно консоли и перейдите в каталог, содержащий пример веб-API Node.js. Например:

    cd active-directory-b2c-javascript-nodejs-webapi
    
  2. Выполните следующие команды:

    npm install && npm update
    node index.js
    

    В окне консоли отобразится номер порта, на котором размещено приложение.

    Listening on port 5000...
    

Запуск одностраничного приложения

  1. Откройте еще одно окно консоли и перейдите в каталог, содержащий пример одностраничного приложения JavaScript. Например:

    cd ms-identity-b2c-javascript-spa
    
  2. Выполните следующие команды:

    npm install && npm update
    npm start
    

    В окне консоли отобразится номер порта, связанный с размещаемым приложением.

    Listening on port 6420...
    
  3. Для просмотра приложения перейдите к http://localhost:6420 в браузере.

    Снимок экрана: пример одностраничного приложения, отображаемого в окне браузера.

  4. Завершите процесс регистрации или входа в систему. Выполнив вход, вы увидите сообщение "User <ваше имя пользователя> logged in" (Пользователь вошел в систему).

  5. Нажмите кнопку вызова API. Одностраничное приложение отправляет маркер доступа в запрос к защищенному веб-API, который возвращает отображаемое имя вошедшего в систему пользователя:

    Снимок экрана: одностраничное приложение в окне браузера, показывающий результат JSON имени пользователя, возвращаемый API-интерфейсом.

Развертывание приложения

В рабочем приложении URI перенаправления регистрации приложения — это обычно общедоступная конечная точка, где выполняется приложение, например https://contoso.com/signin-oidc.

URI перенаправления в зарегистрированных приложениях можно добавлять и изменять в любое время. На URI перенаправления налагаются следующие ограничения.

  • URL-адрес ответа должен начинаться со схемы https.
  • В URL-адресе ответа учитывается регистр. Его регистр должен соответствовать регистру URL-пути выполняющегося приложения.

Следующие шаги

Дополнительные сведения о концепциях, рассматриваемых в данной статье: