Поддержка клиентского пакета SDK для Azure IoT для сторонних серверов маркеров

Azure IoT
Центр Интернета вещей Azure

В статье управление доступом к Центр Интернета вещей показано, как сторонняя служба маркеров может быть интегрирована с Центр Интернета вещей. В этой статье описывается поддержка проверки подлинности маркера подписанного URL-адреса (SAS) в каждом из пакетов SDK клиента Интернета вещей Azure. В нем также описывается, что необходимо реализовать в приложении устройства с помощью соответствующего пакета SDK для каждого языка, а также как использовать маркеры с область устройства или модуля область для политик общего доступа устройства Подключение или модуля Подключение.

Контекст и проблема

В текущей документации по безопасности Центр Интернета вещей Azure рассматривается шаблон стороннего сервера маркеров для проверки подлинности SAS с Центр Интернета вещей устройствами Интернета вещей с помощью пакетов SDK клиента Интернета вещей Azure. Однако неверные предположения, сделанные клиентом во время недавнего корпоративного взаимодействия, свидетельствуют о том, что без дальнейшего уточнения вы можете разработать вводящее впечатление о уровне поддержки, реализованной по умолчанию в пакетах SDK клиента Интернета вещей Azure.

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

Решение

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

Частота оценки маркера зависит от выбранного транспортного протокола— MQTT, AMQP или HTTPS. Вариант зависит от возможностей протокола для поддержки упреждающего обновления маркеров и времени ожидания сеанса. Только AMQP реализует поддержку упреждающего продления. Это означает, что другие транспорты закроют подключение к сбою проверки подлинности маркера SAS, а затем потребуется выполнить новую операцию подключения. Это потенциально дорогостоящая операция подключения для клиента.

Если проверка подлинности SAS завершается ошибкой, возникает ошибка, которая может обрабатываться в приложении устройства обработчиком событий Подключение ion Status Changed. Сбой реализации такого обработчика, как правило, приведет к остановке приложения устройства из-за ошибки. С правильной реализацией функции обработчика событий и обновления маркеров транспорт может повторно попытаться подключиться.

На следующем рисунке показан шаблон стороннего сервера token-server:

Illustration of the third-party token-server pattern

На следующем рисунке показана поддержка реализации в пакете SDK клиента Интернета вещей Azure с интеграцией оператора Mobile Net.

Flowchart of implementation support in the Azure IoT client SDK with Mobile Net Operator integration

Примеры реализаций включены в репозиторий примеров Azure на GitHub.

Проблемы и рекомендации

При принятии решения о том, следует ли реализовать этот шаблон, следует учитывать следующие моменты:

  • Пакеты SDK для клиента Центр Интернета вещей Azure службы подготовки устройств (Azure DPS) не поддерживают проверку подлинности маркера SAS. REST APIAzure DPS поддерживает проверку подлинности маркера SAS. Таким образом, чтобы использовать Azure DPS с сторонней службой маркеров для проверки подлинности SAS, приложение устройства должно реализовать процесс DPS устройства с помощью REST API Azure DPS.

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

Ссылки:

Когда следует использовать этот шаблон

Этот шаблон следует использовать всякий раз, когда вы хотите пройти проверку подлинности для Центр Интернета вещей Azure с устройств Интернета вещей с помощью различных пакетов SDK клиента Интернета вещей Azure. Вместо использования клиентских пакетов SDK для проверки подлинности маркера SAS используйте REST API Azure DPS, чтобы обеспечить поддержку упреждающего продления для всех механизмов транспорта.

Примеры

В следующих разделах приведены примеры, которые можно использовать для различных языков программирования, таких как Embedded C, .NET, Java и Python.

пакет SDK для устройств Центр Интернета вещей Azure для C и пакета SDK для устройств Центр Интернета вещей Azure для Embedded C

Следующий подход можно использовать в приложениях устройств, созданных с помощью пакета SDK Azure IoT C или пакета SDK Для Azure IoT Embedded C. Ни пакет SDK не предоставляет управление временем существования маркера SAS, поэтому вам потребуется реализовать возможность диспетчера времени существования маркеров SAS.

Маркеры SAS можно использовать через структуру IOTHUB_CLIENT_CONFIG, задав член deviceSasToken маркеру и указав значение null deviceKey. Другие неиспользуемые значения, такие как protocolGatewayHostName, также должны иметь значение NULL.

IOTHUB_CLIENT_CONFIG* CONFIG = (IOTHUB_CLIENT_CONFIG*)malloc(sizeof(IOTHUB_CLIENT_CONFIG));

CONFIG->PROTOCOL = PROTOCOL;
CONFIG->DEVICEID = DEVICEID;
CONFIG->IOTHUBNAME = IOTHUBNAME;
CONFIG->IOTHUBSUFFIX = IOTHUBSUFFIX;
CONFIG->DEVICEKEY = 0;
CONFIG->DEVICESASTOKEN = TOKEN;
CONFIG->PROTOCOLGATEWAYHOSTNAME = 0;

// The created IOTHUB_CLIENT_CONFIG can then be provided to the IoTHubDeviceClient_Create function to establish a DeviceClient instance.
if ((IOTHUBCLIENTHANDLE = IoTHubDeviceClient_Create(CONFIG)) == NULL) {
    (void)printf("ERROR: IOTHUBCLIENTHANDLE IS NULL!\r\n");
}

// To capture SAS token authentication failures, a handler needs to be implemented for the IoTHubDeviceClient_SetConnectionStatusCallback.
(void)IoTHubDeviceClient_SetConnectionStatusCallback(IOTHUBCLIENTHANDLE, CONNECTION_STATUS_CALLBACK, NULL);

Connection_status_callback может перехватывать IOTHUB_CLIENT_CONNECTION_STATUS_REASON IOTHUB_CLIENT_CONNECTION_EXPIRED_SAS_TOKEN, чтобы активировать продление маркера SAS через стороннюю службу маркеров. Это необходимо для всех транспортных средств для отслеживания проблем подключения, но специально требуется транспортом, который не поддерживает упреждающее продление маркера SAS. Упреждающее управление временем существования маркеров SAS можно реализовать как функцию, многократно выполняемую во время цикла "операционных" приложений устройства. Обеспечение частого вычисления времени существования маркера, а продление маркера может выполняться заранее при необходимости.

Сводка по реализации проверки подлинности маркера SAS для пакетов SDK для C:

  1. Реализуйте обработчик Подключение ionStatusCallback для записи события IOTHUB_CLIENT_CONNECTION_EXPIRED_SAS_TOKEN и возобновления маркера триггера.

  2. Используйте IOTHUB_CLIENT_CONFIG для предоставления маркера SAS устройства IoTHubDeviceClient_Create.

  3. Реализуйте упреждающее управление временем существования маркера SAS в рамках цикла операций приложения устройства.

пакет SDK для устройств Центр Интернета вещей Azure для .NET

Пакет SDK клиента Интернета вещей Azure для .NET реализует поддержку управления временем существования маркеров SAS через абстрактный класс DeviceAuthenticationWithTokenRefresh. Конкретная реализация этого класса, добавляя функции продления маркеров, может быть предоставлена в качестве метода проверки подлинности в метод DeviceClient.Create. Реализация транспорта автоматически продлевает маркер с помощью метода проверки подлинности по мере необходимости. Требуется Подключение ionStatusChangesHandler для записи изменений подключения и предотвращения возникновения исключений транспортом.

Пример реализации на основе класса DeviceAuthenticationWithTokenRefreash:

internal class StsDeviceAuthenticationWithTokenRefresh : DeviceAuthenticationWithTokenRefresh
{

    private readonly string _stsConnectUrl = "http://localhost:8080/sts/azure/token/operations?sr={0}/devices/{1}";

    private const int DEFAULTTIMETOLIVESECONDS = 1 * 60 * 60;

    private const int DEFAULTBUFFERPERCENTAGE = 15;

    public StsDeviceAuthenticationWithTokenRefresh(string deviceId, int suggestedTimeToLiveSeconds, int timeBufferPercentage) : BASE(deviceId, suggestedTimeToLiveSeconds, timeBufferPercentage)
    {
        If(String.IsNullOrWhitespace(deviceId)){
            throw new ArgumentNullException(nameof(deviceId));
        }
    }

    protected override async Task<string> SafeCreateNewToken(string iotHub, int suggestedTimeToLive)
    {
        string result;
        string url = string.Format(_stsConnectUrl, iotHub, deviceId);

        using (HttpClientHandler handler = new HttpClientHandler())
        using (HttpClient client = new HttpClient(handler))
        {
            try
            {
                HttpResponseMessage response = await client.GetAsync(url);
                if (response.IsSuccessStatusCode)
                {
                    result = await response.Content.ReadAsStringAsync();
                }
                else
                {
                    throw new HttpRequestException($"Request failed with status code {response.StatusCode}.");
                }
            }
            catch (HttpRequestException)
            {
                result = null;
            }
        }

        return result;
    }
}

Сводка по реализации проверки подлинности маркера SAS для пакета SDK для устройств Центр Интернета вещей Azure для .NET:

  1. Реализуйте конкретный класс на основе абстрактного класса DeviceAuthEnticationWithTokenRefresh, который реализует функции обновления маркеров.

  2. Реализуйте Подключение ionStatusChangesHandler для записи состояния подключения к транспорту и предотвращения исключений, вызванных реализацией транспорта.

Ссылки:

пакет SDK для устройств Центр Интернета вещей Azure для Java

Пакет SDK для клиента Интернета вещей Azure для Java реализует поддержку управления временем существования маркеров SAS через интерфейс SasTokenProvider. Класс, реализующий этот интерфейс с функциональностью продления маркера SAS, можно использовать в качестве класса SecurityProvider в конструкторе DeviceClient. Реализация транспорта автоматически продлевает маркер через поставщика безопасности по мере необходимости. Необходимо зарегистрировать Подключение ionStatusChangeCallback для записи изменений подключения и предотвращения исключений, создаваемых транспортом.

Пример реализации поставщика безопасности, реализующего интерфейс SasTokenProvider:

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;

public class StsSecurityProvider implements SasTokenProvider {
    private final String hostname;
    private final String deviceId;
    private int renewalBufferSeconds;
    private long expiryTimeSeconds;
    private char[] sasToken;

    public StsSecurityProvider(String hostname, String deviceId) {
        this.hostname = hostname;
        this.deviceId = deviceId;
        this.renewalBufferSeconds = 120;
        this.expiryTimeSeconds = (System.currentTimeMillis() / 1000);
    }

    @Override
    public char[] getSasToken() {
        long currentTimeSeconds = (System.currentTimeMillis() / 1000);
        try {
            if (this.sasToken == null || this.expiryTimeSeconds + this.renewalBufferSeconds >= currentTimeSeconds) {
                this.sasToken = stsGetToken();
                assert this.sasToken != null;
                String t = String.copyValueOf(this.sasToken);
                String[] bits = t.split("SE=");
                long l = Long.parseLong(bits[1]);
                this.expiryTimeSeconds = l; // the SE= number
                this.renewalBufferSeconds = (int)(l * 0.15); // renew within 15% of expiry
            }
        } catch (InterruptedException | IOException e) {
            e.printStackTrace();
        }
        return this.sasToken;
    }

    private char[] stsGetToken() throws IOException, InterruptedException {
        String stsUrl = String.format("http://localhost:8080/sts/azure/token/operations?sr=%s/devices/%s", this.hostname, this.deviceId);
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(stsUrl))
            .timeout(Duration.ofMinutes(2))
            .header("Content-Type", "application/json")
            .build();
        HttpClient client = HttpClient.newBuilder()
            .version(HttpClient.Version.HTTP_1_1)
            .connectTimeout(Duration.ofSeconds(20))
            .build();
        HttpResponse < String > response = client.send(request, HttpResponse.BodyHandlers.ofString());
        if (response.statusCode() < 200 || response.statusCode() >= 300) {
            return null;
        }
        if (response.body().isEmpty()) {
            return null;
        }
        return response.body().toCharArray();
    }
}

Сводка по реализации проверки подлинности маркера SAS для пакета SDK для устройств Центр Интернета вещей Azure для Java:

  1. Реализуйте интерфейс SasTokenProvider в классе и включите функции продления маркеров.

  2. Реализуйте обработчик Подключение ionStatusChangeCallback для записи изменений состояния подключения к транспорту и предотвращения исключений, вызванных реализацией транспорта.

Ссылки:

пакет SDK для устройств Центр Интернета вещей Azure для Python

Пакет SDK для устройств Центр Интернета вещей Azure для Python реализует поддержку маркера SAS с помощью методов в объекте IoTHubDeviceClient. Эти методы позволяют создавать клиент устройства с помощью маркера и предоставлять обновленный маркер после создания клиента устройства. Они не реализуют управление временем существования маркеров, но это можно легко реализовать как асинхронную операцию.

Пример реализации Python 3.7, показывающий только структуру функциональных возможностей:

import asyncio
import iothub_device_client

async def main():
    # Get a SAS token you generated
    sastoken = get_new_sastoken()
    # The client object is used to interact with your Azure IoT Hub.
    device_client = iothub_device_client.create_from_sastoken(sastoken)

    # Connect the client
    await device_client.connect()

    # Define behavior for providing new SAS tokens to prevent expiry
    async def sastoken_keepalive():
        while True:
            await asyncio.sleep(new_token_interval)
            sastoken = get_new_sastoken()
            await device_client.update_sastoken(sastoken)

    # Also run the SAS token keepalive in the event loop
    keepalive_task = asyncio.create_task(sastoken_keepalive())

    # Cancel the SAS token update task
    keepalive_task.cancel()

    # Finally, shut down the client
    await device_client.shutdown()

if __name__ == "main":
    asyncio.run(main())

Сводка по пакету SDK для устройств Центр Интернета вещей Azure для проверки подлинности маркера SAS Python:

  1. Создайте функцию создания маркера SAS.

  2. Создайте клиент устройства с помощью IoTHubDeviceClient.create_from_sastoken.

  3. Управление временем существования маркера в качестве отдельного действия, предоставляя клиенту устройства обновленный маркер при необходимости в методе IoTHubDeviceClient.update_sastoken.

Ссылки:

пакет SDK для устройств Центр Интернета вещей Azure для Node.JS/JavaScript

Azure IoT для Node.JS/JavaScript реализует sharedAccessSignatureAuthenticationProvider, который будет служить маркером SAS для клиента устройства и транспорта для проверки подлинности с помощью Центр Интернета вещей. Он не реализует никакие функции продления маркеров. Приложение устройства должно управлять временем существования маркера, обновляя маркер по мере необходимости.

Используйте методы клиента устройства изSharedAccessSignature и updateSharedAccessSignature, чтобы инициировать подключение к Центр Интернета вещей и предоставить обновленный маркер в SharedAccessSignatuteAuthenticationProvider, что приведет к тому, что поставщик проверки подлинности выдает новое событиеTokenAvailable для транспорта.

Базовый пример маркера SAS представлен в примере simple_sample_device_with_sas.js .

Сводка пакета SDK для устройств Центр Интернета вещей Azure для Node.JS/JavaScript:

  1. Реализуйте управление временем существования маркера SAS и продление.

  2. Используйте клиент устройства изSharedAccessSignature для создания экземпляра клиента устройства.

  3. Используйте обновление клиента устройстваSharedAccessSignature для предоставления обновленного маркера.

Ссылки:

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