Что такое модель безопасности бот-фреймворка? - PullRequest
1 голос
/ 18 июня 2020

Я изучаю SDK Microsoft Bot Builder для создания чат-бота, который интегрируется с MS Teams. Большинство предоставленных образцов не имеют каких-либо механизмов аутентификации, а образцы, которые ссылаются на OAuth, похоже, делают это для того, чтобы бот мог получить доступ к ресурсу с использованием потока от имени. Правильно ли думать о модели безопасности, что бот должен считаться publi c, а любая информация, не относящаяся к publi c, осуществляется из контекста вызывающего пользователя?

1 Ответ

1 голос
/ 23 июня 2020

В Bot Framework необходимо учитывать три типа аутентификации / авторизации:

  1. Бот-аутентификация - идентификатор и пароль приложения Microsoft
  2. Клиентская аутентификация - секрет / токен прямой линии или различные механизмы для других каналов
  3. авторизация пользователя - карты / подсказки / токены OAuth

К сожалению, есть некоторая несогласованность в документации о том, что есть что, но я только что поднял здесь проблему: https://github.com/MicrosoftDocs/bot-docs/issues/1745

В любом случае нет необходимости думать обо всех ботах как о «publi c. " Пакет SDK для создания ботов аутентифицирует как входящие, так и исходящие сообщения, используя свой идентификатор приложения и пароль. Это означает, что любые неавторизованные сообщения, отправленные на конечную точку бота, будут отклонены, и никакой другой бот не сможет выдать себя за ваше.

В общем, вы должны сделать так, чтобы пользователь вошел в систему, если вы хотите, чтобы бот получал доступ к защищенной информации от имени пользователя. . Но поскольку вы упомянули, что хотите ограничить доступ ботов к определенным c клиентам, я могу кратко объяснить, как это сделать. Вы можете найти промежуточное ПО здесь , которое делает это в C#, а вот модифицированная версия кода, которая, как мне кажется, улучшает его за счет использования набора ha sh вместо словаря:

public class TeamsTenantFilteringMiddleware : IMiddleware
{
    private readonly HashSet tenantMap;
 
    public TeamsTenantFilteringMiddleware(IEnumerable allowedTenantIds)
    {
        if (allowedTenantIds == null)
        {
            throw new ArgumentNullException(nameof(allowedTenantIds));
        }
 
        this.tenantMap = new HashSet(allowedTenantIds);
    }
 
    public async Task OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken = default(CancellationToken))
    {
        if (!turnContext.Activity.ChannelId.Equals(Channels.Msteams, StringComparison.OrdinalIgnoreCase))
        {
            await next(cancellationToken).ConfigureAwait(false);
            return;
        }
 
        TeamsChannelData teamsChannelData = turnContext.Activity.GetChannelData();
        string tenantId = teamsChannelData?.Tenant?.Id;
 
        if (string.IsNullOrEmpty(tenantId))
        {
            throw new UnauthorizedAccessException("Tenant Id is missing.");
        }
 
        if (!this.tenantMap.Contains(tenantId))
        {
            throw new UnauthorizedAccessException("Tenant Id '" + tenantId + "' is not allowed access.");
        }
 
        await next(cancellationToken).ConfigureAwait(false);
    }
}
...