Добавить аутентификацию в Azure Device Streams - PullRequest
0 голосов
/ 26 января 2020

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

Я бы предпочел использовать какой-либо токен аутентификации (JWT) для передачи запроса, который может быть проверен самим устройством. Если токен может быть проверен и использование имеет надлежащие права, то соединение принимается, а в противном случае оно отклоняется. Единственное значение, которое можно настроить, - это имя, поэтому мне нужно закодировать токен в имени. Код клиента может выглядеть примерно так:

Код клиента

var deviceStreamRequest = new DeviceStreamRequest(streamName: "WebAPI?token=<JWT-token here>");
var result = await serviceClient.CreateStreamAsync(deviceId, deviceStreamRequest, cancellationToken).ConfigureAwait(false);

Код устройства

var streamRequest = await deviceClient.WaitForDeviceStreamRequestAsync(cancellationToken).ConfigureAwait(false);
if (streamRequest != null)
{
   var token = GetTokenFromName(streamRequest.Name);
   if (!CheckClaim(token, "WebAPI"))
   {
       await deviceClient.RejectDeviceStreamRequestAsync(streamRequest, cancellationToken).ConfigureAwait(false);
       return;
   }

   await deviceClient.AcceptDeviceStreamRequestAsync(streamRequest, cancellationToken).ConfigureAwait(false);

   // ...
}

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

Есть лучший способ передать токен, используя имя?

1 Ответ

0 голосов
/ 27 января 2020

Текущая версия Microsoft. Azure .Devices.DeviceStreamRequest не позволяла заполнять полезную нагрузку запроса на устройство, как это было у нас в прямом методе устройства. Полезная нагрузка запроса - это лучшее место для отправки дополнительных (или служебных) данных на устройство, связанное с предварительной обработкой потоковой передачи, например решения B2B, и т. Д. c.

Обратите внимание, что при использовании streamName для передачи вашего токен не является правильным способом, см. следующий фрагмент кода из. Net Reflector:

public override Task<DeviceStreamResponse> CreateStreamAsync(string deviceId, DeviceStreamRequest deviceStreamRequest, CancellationToken cancellationToken)
{
    return this.CreateStreamAsync(GetDeviceStreamUri(deviceId, deviceStreamRequest.StreamName), deviceStreamRequest, cancellationToken);
}

где GetDeviceStreamUri имеет следующую реализацию:

private static Uri GetDeviceStreamUri(string deviceId, string streamName)
{
    deviceId = WebUtility.UrlEncode(deviceId);
    object[] args = new object[] { deviceId, streamName };
    return new Uri("/twins/{0}/streams/{1}?api-version=2018-08-30-preview".FormatInvariant(args), UriKind.Relative);
}

Как вы можете см. выше Uri, уже есть жестко заданный параметр запроса, такой как ? api-version = 2018-08-30-preview

Однако для вашего решения существует обходной путь, основанный на использовании базовая связь (без использования пакета SDK), например, API REST. Обратите внимание, что эта функция все еще находится в предварительном просмотре.

Для демонстрации потоковой передачи устройства iot я использую мой Azure IoT Hub Tester .

Следующее фрагмент экрана показывает POST-запрос invoker к IoT-хабу для потоковой передачи устройства:

enter image description here

Как видите, Microsoft. Azure .Devices.DeviceStreamRequest может обрабатывать только имя потока и два заголовка, такие как iothub-streaming-response-timeout-in-seconds и iothub-streaming-connect-timeout-in-seconds .

После публикации этого запроса IoT-концентратор отправит сообщение на устройство. В следующем фрагменте экрана показано полученное сообщение в моем виртуальном устройстве MQTT1:

enter image description here

Теперь устройство1 может оценить полезную нагрузку сообщения, чтобы принять решение для принимает (код 202) или отклоняет (код 4xx, et c.) процесс потоковой передачи. Обратите внимание, что существует ограничение по времени ответа (в моем примере это 15 секунд) на вызов invoker.

Как только устройство приняло этот процесс потоковой передачи, вызывающий получит ответ от IoT Hub с подробностями в заголовки для создания веб-сокета связи и полезной нагрузки с устройства. Ниже приведен пример заголовков:

    iothub-streaming-is-accepted: True
    iothub-streaming-url: wss://centralus.centralus-001.streams.azure-devices.net:443/bridges/ih/rk2019-iot/d/device1/sid/**** 
    iothub-streaming-auth-token: ***
    iothub-streaming-ip-address: 0.0.0.0

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...