Добавление функции единого входа в бот

ОБЛАСТЬ ПРИМЕНЕНИЯ: ПАКЕТ SDK версии 4

В этой статье показано, как использовать функцию единого входа в боте. Для этого эта функция использует бот-получатель (также известный как корневойили родительский бот) для взаимодействия с навыком или дочерним ботом. В этой статье используются термины корневого бота и бота навыка.

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

Корневые и навыки боты — это отдельные боты, работающие на потенциально разных серверах, каждый из которых имеет отдельную память и состояние. Дополнительные сведения о навыках см. в разделе "Навыки" и "Реализация навыка". Дополнительные сведения о проверке подлинности пользователей см. в статье "Основы проверки подлинности Bot Framework", "Проверка подлинности пользователей" и "Добавление проверки подлинности в бот".

Важно!

При использовании проверки подлинности azure AI Служба Bot с Веб-чат необходимо учитывать некоторые важные аспекты безопасности. См. сведения о безопасности в руководстве по проверке подлинности REST.

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

Сведения о примере

В этой статье содержатся ссылки на два бота: RootBot и SkillBot. RootBot пересылает действия в SkillBot. Они моделируют этот типичный сценарий использования навыка.

  • Корневой бот вызывает один или несколько ботов навыка.
  • Корневой бот и боты навыка реализуют обычную проверку подлинности, описанную в статье Добавление проверки подлинности в бот.
  • Пользователь входит в корневой бот.
  • Из-за единого входа и входа в корневой бот они вошли в бот навыка, не требуя повторного взаимодействия с пользователем.

Общие сведения о том, как Bot Framework обрабатывает проверку подлинности, см. в разделе "Проверка подлинности пользователей". Общие сведения о едином входе см. в разделе "Единый вход".

RootBot поддерживает единый вход. Он взаимодействует с Приложением SkillBot от имени пользователя без необходимости повторной проверки подлинности в _SkillBot.

Для каждого проекта в примере необходимо следующее.

  1. Приложение идентификатора Microsoft Entra для регистрации ресурса бота в Azure.
  2. Приложение поставщика удостоверений Microsoft Entra ID для проверки подлинности.

    Примечание.

    В настоящее время поддерживается только поставщик удостоверений Идентификатора Microsoft Entra.

Создание ресурса Azure RootBot

  1. Создайте ресурс бота Azure в портал Azure для RootBot. Выполните действия, описанные в статье "Создание ресурса бота Azure".
  2. Скопируйте и сохраните идентификатор приложения и секрет клиента для регистрации бота.

Создание удостоверения идентификатора Microsoft Entra для RootBot

Идентификатор Microsoft Entra — это облачная служба удостоверений, которая позволяет создавать приложения, безопасные для входа пользователей с использованием стандартных отраслевых протоколов, таких как OAuth2.0.

  1. Создайте приложение удостоверения для RootBot идентификатора, использующего идентификатор Microsoft Entra для проверки подлинности пользователя. Выполните действия, описанные в разделе "Создание поставщика удостоверений Идентификатора Microsoft Entra".

  2. В левой области выберите "Манифест".

  3. Задайте для accessTokenAcceptedVersion значение 2.

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

  5. В левой области выберите "Предоставить API".

  6. В правой области выберите "Добавить область".

  7. В правом углу раздела "Добавить область" нажмите кнопку "Сохранить" и продолжить.

  8. В отображаемом окне в разделе Кто может предоставить согласие?выберите Администратор и пользователей.

  9. Введите остальные необходимые сведения.

  10. Выберите Добавить область.

  11. Скопируйте и сохраните значение области.

Создание параметра подключения OAuth для RootBot

  1. Создайте подключение идентификатора Microsoft Entra в регистрации бота RootBot и введите значения, как описано в идентификаторе Microsoft Entra и описанном ниже значении.

  2. Оставьте значение URL-адреса обмена маркерами пустым.

  3. В поле "Области" введите RootBot значение область, сохраненное на предыдущих шагах.

    Примечание.

    Области содержат URL-адрес, который пользователь изначально входит в корневой бот, а URL-адрес обмена маркерами остается пустым.

    Например, предположим, что корневой бот appid является rootAppId, а идентификатор бота навыка — skillAppId. Область корневого бота будут выглядеть как api://rootAppId/customScope, которая используется для входа пользователя. Затем область этого корневого бота обмениваются api://skillAppId/customобласть во время единого входа.

  4. Скопируйте и сохраните имя подключения.

Создание ресурса Azure SkillBot

  1. Создайте ресурс бота Azure в портал Azure для SkillBot. Выполните действия, описанные в статье "Создание ресурса бота Azure".
  2. Скопируйте и сохраните идентификатор приложения и секрет клиента для регистрации бота.

Создание удостоверения идентификатора Microsoft Entra для SkillBot

Идентификатор Microsoft Entra — это облачная служба удостоверений, которая позволяет создавать приложения, безопасные для входа пользователей с использованием стандартных отраслевых протоколов, таких как OAuth2.0.

  1. Создайте приложение удостоверения для SkillBot идентификатора, использующего идентификатор Microsoft Entra для проверки подлинности бота. Выполните действия, описанные в разделе "Создание поставщика удостоверений Идентификатора Microsoft Entra".

  2. В левой области выберите "Манифест".

  3. Задайте для accessTokenAcceptedVersion значение 2.

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

  5. В левой области выберите "Предоставить API".

  6. В правой области выберите "Добавить область".

  7. В правом правом углу раздела "Добавить область" нажмите кнопку "Сохранить" и продолжить.

  8. В появившемся окне в разделе Кто может давать согласие? выберите Администраторы и пользователи.

  9. Введите остальные необходимые сведения.

  10. Выберите Добавить область.

  11. Скопируйте и сохраните значение области.

  12. Выберите Добавить клиентское приложение. В крайнем правом разделе в поле Идентификатор клиента введите идентификатор RootBot, сохраненный ранее. Убедитесь, что используется идентификатор RootBot, а не идентификатор приложения регистрации.

    Примечание.

    Для клиентских приложений azure AI Служба Bot не поддерживает единый вход с поставщиком удостоверений Microsoft Entra ID B2C.

  13. В разделе Authorized scope (Разрешенная область) установите флажок для значения области.

  14. Выберите Добавить приложение.

  15. В области навигации слева выберите разрешения API. Рекомендуется явно задать разрешения API для приложения.

    1. В правой области выберите "Добавить разрешение".

    2. Выберите API Майкрософт, затем щелкните Microsoft Graph.

    3. Выберите Делегированные разрешения и убедитесь, что выбраны все разрешения, Ниже перечислены разрешения, требуемые для этого примера.

      Примечание.

      Для любого разрешения, отмеченного как Требуется согласие администратора, необходимо, чтобы пользователь и администратор арендатора вошли в систему.

      • openid
      • profile
      • User.Read
      • User.ReadBasic.All
    4. Выберите Добавить разрешения.

Создание параметра подключения OAuth для SkillBot

  1. Создайте подключение идентификатора Microsoft Entra в регистрации бота SkillBot и введите значения, как описано в идентификаторе Microsoft Entra и значениях, описанных ниже.

  2. В поле URL-адрес Exchange токенов введите SkillBot значение область, сохраненное на предыдущих шагах.

  3. В поле "Области" введите следующие значения, разделенные пустым пробелом: profileUser.ReadUser.ReadBasic.Allopenid

  4. Скопируйте и сохраните имя файла подключения.

Проверка подключения

  1. Выберите запись подключения, чтобы открыть созданное соединение.
  2. Выберите "Тестировать Подключение" в верхней части области параметров поставщика услуг Подключение ion.
  3. При выполнении данного действия в первый раз должна открыться новая вкладка браузера с перечисленными разрешениями, которые запрашивает приложение, и предложение их принять.
  4. Выберите Принять.
  5. Затем необходимо перенаправить вас на страницу "Тестовый Подключение" на <страницу "Успешное подключение>".

Дополнительные сведения см. в обзоре идентификатора Microsoft Entra для разработчиков (версии 1.0) и платформа удостоверений Майкрософт (версия 2.0). См. сведения о различиях между конечными точками версий 1 и 2 в статье Зачем выполнять обновление до платформы удостоверений Майкрософт (версия 2.0)? Полные сведения см. в разделе платформа удостоверений Майкрософт (прежнее название — идентификатор Microsoft Entra для разработчиков).

Подготовка кода примеров

Необходимо обновить файл appsettings.json в обоих примерах, как описано ниже.

  1. Клонируйте единый вход с простым потребителем навыков и навыком из репозитория GitHub.

  2. Откройте файл appsettings.json проекта SkillBot. Назначьте следующие значения из сохраненного файла:

    {
        "MicrosoftAppId": "<SkillBot registration app ID>",
        "MicrosoftAppPassword": "<SkillBot registration password>",
        "ConnectionName": "<SkillBot connection name>",
        "AllowedCallers": [ "<RootBot registration app ID>" ]
    }
    
    
  3. Откройте файл appsettings.json проекта RootBot. Назначьте следующие значения из сохраненного файла:

    {
        "MicrosoftAppId": "<RootBot registration app ID>",
        "MicrosoftAppPassword": "<RootBot registration password>",
        "ConnectionName": "<RootBot connection name>",
        "SkillHostEndpoint": "http://localhost:3978/api/skills/",
        "BotFrameworkSkills": [
                {
                "Id": "SkillBot",
                "AppId": "<SkillBot registration app ID>",
                "SkillEndpoint": "http://localhost:39783/api/messages"
                }
            ]
    }
    

Тестирование примеров

Для тестирования используйте следующее.

  • Команды RootBot.

    • login позволяет пользователю войти в регистрацию идентификатора Microsoft Entra с помощью идентификатора RootBot. После входа единый вход заботится о входе в систему SkillBot . Пользователю не нужно входить снова.
    • Команда token отображает маркер пользователя.
    • Команда logout выполняет выход пользователя из RootBot.
  • Команды SkillBot.

    • Команда skill login позволяет RootBot войти в SkillBot от имени пользователя. Пользователь не отображается карта входа, если вход уже выполнен, если единый вход не завершается ошибкой.
    • Команда skill token отображает маркер пользователя из SkillBot.
    • Команда skill logout выполняет выход пользователя из SkillBot.

Примечание.

При первом использовании единого входа пользователям может быть предложено выполнить вход с помощью карты OAuth. Это связано с тем, что они еще не дали согласие на приложение идентификатора Microsoft Entra ID. Чтобы избежать этого, они могут предоставить согласие администратора для любых разрешений графа, запрошенных приложением идентификатора Microsoft Entra ID.

Если это еще не сделано, установите эмулятор Bot Framework. См. также отладку с помощью эмулятора.

Вам потребуется настроить эмулятор для работы примера входа бота. Выполните приведенные ниже действия, как показано в разделе "Настройка эмулятора для проверки подлинности".

После настройки механизма проверки подлинности можно выполнить фактическое тестирование примера бота.

  1. В Visual Studio откройте решение SSOWithSkills.sln и настройте его для запуска отладки с несколькими процессами.

  2. Начните отладку на локальном компьютере. Обратите внимание, что вRootBot файле проекта appsettings.json есть следующие параметры:

    "SkillHostEndpoint": "http://localhost:3978/api/skills/"
    "SkillEndpoint": "http://localhost:39783/api/messages"
    

    Примечание.

    Эти параметры подразумевают, что на локальном компьютере будет выполняться и RootBot, и SkillBot. Эмулятор взаимодействует с портом 3978 и RootBot взаимодействует с RootBotSkillBot портом 39783. Как только вы начнете отладку, откроются два окна браузера по умолчанию. Одно будет использовать порт 3978, а другое — порт 39783.

  3. Запустите эмулятор Bot Framework.

  4. При подключении к боту введите RootBot идентификатор и пароль приложения регистрации.

  5. Введите hi, чтобы начать беседу.

  6. Введите login. RootBot отобразит карту аутентификации Sign In to AAD (Вход в AAD).

    Example of a sign-in card.

  7. Выберите Войти. Откроется всплывающее диалоговое окно Confirm Open URL (Подтверждение открытия URL-адреса).

    Screenshot of the 'open URL' confirmation message.

  8. Выберите Подтвердить. Вы войдете в систему и RootBot отобразится маркер.

  9. Введите token, чтобы снова отобразить маркер.

    Example of a message displaying the root token.

    Теперь вы готовы взаимодействовать с ним SkillBot. После того как вы выполнили вход с помощью RootBotэтого элемента, вам не нужно снова предоставлять учетные данные, пока не выйдите. В этом примере показано, что единый вход работает.

  10. Введите имя входа навыка в поле эмулятора. Вам не будет предложено войти снова. Вместо этого отобразится маркер SkillBot.

  11. Введите маркер навыка, чтобы снова отобразить маркер.

  12. Теперь вы можете ввести skill logout, чтобы выйти из SkillBot. Затем введите logout, чтобы выйти из SimpleRootBoot.

Дополнительные сведения

Приведенная ниже схема последовательности операций относится к примерам, используемым в этой статье, и показывает взаимодействие между различными компонентами. ABS обозначает azure AI Служба Bot.

Sequence diagram illustrating the skill token flow.

  1. Пользователь вводит команду login для RootBot в первый раз.
  2. RootBot отправляет карту OAuthCard, предлагая пользователю выполнить вход.
  3. Пользователь вводит учетные данные проверки подлинности, отправляемые в ABS (Azure AI Служба Bot).
  4. ABS отправляет маркер аутентификации, созданный на основе учетных данных пользователя, в RootBot.
  5. RootBot отображает маркер корневого бота пользователю.
  6. Пользователь вводит команду skill login для SkillBot.
  7. SkillBot отправляет OAuthCard в RootBot.
  8. RootBot запрашивает заменяемый маркер из ABS.
  9. Единый вход отправляет маркер навыка SkillBotв RootBot.
  10. RootBot отображает маркер навыка пользователю. Обратите внимание на то, что маркер навыка был создан без входа пользователя в SkillBot. Это возможно благодаря единому входу.

В следующем примере показано, как происходит обмен токенами. Код находится в файле TokenExchangeSkillHandler.cs .

private async Task<bool> InterceptOAuthCards(ClaimsIdentity claimsIdentity, Activity activity)
{
    var oauthCardAttachment = activity.Attachments?.FirstOrDefault(a => a?.ContentType == OAuthCard.ContentType);
    if (oauthCardAttachment != null)
    {
        var targetSkill = GetCallingSkill(claimsIdentity);
        if (targetSkill != null)
        {
            var oauthCard = ((JObject)oauthCardAttachment.Content).ToObject<OAuthCard>();

            if (!string.IsNullOrWhiteSpace(oauthCard?.TokenExchangeResource?.Uri))
            {
                using (var context = new TurnContext(_adapter, activity))
                {
                    context.TurnState.Add<IIdentity>("BotIdentity", claimsIdentity);

                    // AAD token exchange
                    try
                    {
                        var result = await _tokenExchangeProvider.ExchangeTokenAsync(
                            context,
                            _connectionName,
                            activity.Recipient.Id,
                            new TokenExchangeRequest() { Uri = oauthCard.TokenExchangeResource.Uri }).ConfigureAwait(false);

                        if (!string.IsNullOrEmpty(result?.Token))
                        {
                            // If token above is null, then SSO has failed and hence we return false.
                            // If not, send an invoke to the skill with the token. 
                            return await SendTokenExchangeInvokeToSkill(activity, oauthCard.TokenExchangeResource.Id, result.Token, oauthCard.ConnectionName, targetSkill, default).ConfigureAwait(false);
                        }
                    }
                    catch
                    {
                        // Show oauth card if token exchange fails.
                        return false;
                    }

                    return false;
                }
            }
        }
    }
    return false;
}