Azure IoT Client SDK-ondersteuning voor tokenservers van derden

In het artikel Toegang tot IoT Hub wordt beschreven hoe een tokenservice van derden kan worden geïntegreerd met IoT Hub. Dit artikel bevat een overzicht van de ondersteuning voor SAS-tokenverificatie (Shared Access Signature) in elk van de SDK's van de Azure IoT-client. Ook wordt beschreven wat er moet worden geïmplementeerd in een apparaattoepassing met behulp van de bijbehorende SDK voor elke taal en hoe u tokens binnen het apparaatbereik of modulebereik gebruikt voor het beleid voor gedeelde toegang van DeviceConnect of ModuleConnect.

Context en probleem

In de Azure IoT Hub-beveiligingsdocumentatie wordt het patroon van de tokenserver van derden voor SAS-verificatie met IoT Hub door IoT-apparaten besproken met behulp van de Azure IoT-client-SDK's. Onjuiste veronderstellingen van een klant tijdens een recente enterprise-betrokkenheid doen echter vermoeden dat u zonder verdere uitleg een misleidende indruk kunt ontwikkelen over het ondersteuningsniveau dat standaard is geïmplementeerd in de SDK's van de Azure IoT-client.

In dit artikel wordt het leren van die betrokkenheid besproken en wordt verduidelijkt wat er in elke SDK moet worden gedaan voor apparaten om verificatie van een externe tokenserver te bereiken. Dit artikel moet ook voorkomen dat u vergelijkbare onjuiste veronderstellingen doet over ondersteuning voor het token-serverpatroon van derden in de SDK van de Azure IoT-client.

Oplossing

De SDK's van de Azure IoT-client bieden verschillende ondersteuningsniveaus voor verificatie van SAS-tokens, waarbij elk aangepaste code nodig is om de functionaliteit voor verificatie en tokenbeheer te voltooien.

De evaluatiefrequentie van het token is afhankelijk van het gekozen transportprotocol: MQTT, AMQP of HTTPS. De variatie is afhankelijk van de mogelijkheid van het protocol om proactieve verlenging van tokens en sessie-time-outs te ondersteunen. Alleen AMQP implementeert proactieve verlengingsondersteuning. Dit betekent dat de andere transporten de verbinding bij een verificatiefout met een SAS-token sluiten en vervolgens een nieuwe verbindingsbewerking moeten uitvoeren. Dit is een mogelijk dure verbindingsbewerking voor de client.

Als DE SAS-verificatie mislukt, wordt er een foutmelding weergegeven door de transport-implementatie die in de apparaattoepassing kan worden verwerkt door een gebeurtenis-handler 'Verbindingsstatus gewijzigd'. Als een dergelijke handler niet wordt geïmplementeerd, wordt de apparaattoepassing meestal gestopt vanwege de fout. Met de juiste implementatie van de functionaliteit voor gebeurtenis-handler en tokenvernieuwing, kunnen de transporten de verbinding opnieuw proberen.

In de volgende afbeelding ziet u het token-serverpatroon van derden:

Afbeelding van het patroon van de tokenserver van derden

In de volgende afbeelding ziet u implementatieondersteuning in de Azure IoT client-SDK met Mobile Net Operator-integratie:

Stroomdiagram van implementatieondersteuning in de Azure IoT-client-SDK met Mobile Net Operator-integratie

Voorbeeld implementaties zijn opgenomen in de opslagplaats Azure Samples op GitHub.

Problemen en overwegingen

Houd rekening met de volgende punten bij het bepalen of dit patroon moet worden geïmplementeerd:

  • De Azure IoT Hub SDK's van de Device Provisioning Service -client (Azure DPS) bieden geen ondersteuning voor verificatie van SAS-tokens. De Azure DPS-REST API ondersteunt sas-tokenverificatie. Als u Azure DPS wilt gebruiken met een tokenservice van derden voor SAS-verificatie, moet een apparaattoepassing daarom het DPS-proces van het apparaat implementeren met behulp van de Azure DPS-REST API.

  • Dit bestaat uit het maken van een eerste registratieaanvraagbewerking en vervolgens het peilen van de API voor de operationele status totdat het DPS-proces slaagt of mislukt. Als dit is gelukt, kunnen de inrichtingsgegevens van het apparaat worden verkregen door ze aan te vragen bij de Azure DPS-REST API Runtime-registratie.

Verwijzingen:

Wanneer dit patroon gebruiken

U moet dit patroon gebruiken wanneer u zich wilt verifiëren voor Azure IoT Hub van IoT-apparaten met behulp van de verschillende Azure IoT Client-SDK's. In plaats van de client-SDK's te gebruiken voor verificatie van SAS-tokens, gebruikt u de Azure DPS-REST API om te zorgen voor de implementatie van proactieve verlengingsondersteuning voor alle transportmechanismen.

Voorbeelden

De volgende secties bieden voorbeelden die u kunt gebruiken voor verschillende programmeertalen, zoals Embedded C, .NET, Java en Python.

Azure IoT Hub device SDK voor C en Azure IoT Hub device SDK voor Embedded C

De volgende aanpak kan worden gebruikt in apparaattoepassingen die zijn gebouwd met behulp van de Azure IoT C SDK of de Azure IoT Embedded C SDK. Geen van beide SDK's biedt levensduurbeheer voor SAS-tokens. Daarom moet u de mogelijkheid voor levensduurbeheer van een SAS-token implementeren.

SAS-tokens kunnen worden gebruikt via de IOTHUB _ CLIENT _ CONFIG-structuur door het deviceSasToken-lid in te stellen op het token en de deviceKey null te maken. Andere niet-gebruikte waarden, zoals protocolGatewayHostName, moeten ook worden ingesteld op null.

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;

De gemaakte IOTHUB CLIENT-CONFIGURATIE kan vervolgens worden opgegeven voor de _ _ functie IoTHubDeviceClient Create om een _ DeviceClient-exemplaar tot stand te gebracht.

IF ((IOTHUBCLIENTHANDLE = IOTHUBDEVICECLIENT\_CREATE(CONFIG)) == NULL)

{

(VOID)PRINTF("ERROR: IOTHUBCLIENTHANDLE IS NULL!\\R\\N");

}

Als u verificatiefouten met een SAS-token wilt vastleggen, moet er een handler worden geïmplementeerd voor de IoTHubDeviceClient _ SetConnectionStatusCallback.

(VOID)IOTHUBDEVICECLIENT\_SETCONNECTIONSTATUSCALLBACK(IOTHUBCLIENTHANDLE,
CONNECTION\_STATUS\_CALLBACK, NULL);

De callback van de verbindingsstatus kan de reden van de IOTHUB CLIENT CONNECTION EXPIRED SAS TOKEN ondervangen om een verlenging van het _ _ _ _ _ _ _ _ _ _ SAS-token via de _ tokenservice van derden te activeren. Dit is vereist voor alle transporten om verbindingsproblemen vast te leggen, maar is specifiek vereist voor transporten die geen ondersteuning bieden voor proactieve verlenging van sas-tokens. Proactief levensduurbeheer van SAS-token kan worden geïmplementeerd als een functie die herhaaldelijk wordt uitgevoerd tijdens de lus 'operationele' apparaattoepassingen. Ervoor zorgen dat de levensduur van het token regelmatig wordt geëvalueerd en dat tokenvernieuwing proactief kan worden uitgevoerd wanneer dat nodig is.

Samenvatting van implementatie van SAS-tokenverificatie voor C-SDK's:

  1. Implementeert een ConnectionStatusCallback-handler om de gebeurtenis IOTHUB CLIENT CONNECTION EXPIRED SAS TOKEN vast te leggen _ _ en _ _ _ tokenvernieuwing te activeren.

  2. Gebruik een IOTHUB CLIENT-CONFIGURATIE om het SAS-token van het apparaat op te geven voor _ _ IoTHubDeviceClient _ Create.

  3. Implementeert proactief levensduurbeheer van SAS-token als onderdeel van de bewerkingslus van de apparaattoepassing.

Verwijzingen:

Azure IoT Hub device SDK voor .Net

De Azure IoT-client-SDK voor .Net implementeert ondersteuning voor levensduurbeheer van SAS-tokens via de abstracte DeviceAuthenticationWithTokenRefresh-klasse. Een concrete implementatie van deze klasse, waarbij functionaliteit voor tokenvernieuwing wordt toegevoegd, kan worden opgegeven als verificatiemethode voor een DeviceClient.Create-methode. De transport-implementaties vernieuwen het token automatisch via de verificatiemethode, indien nodig. Een ConnectionStatusChangesHandler is vereist om verbindingswijzigingen vast te leggen en te voorkomen dat uitzonderingen worden veroorzaakt door de transporten.

Voorbeeld van implementatie op basis van de DeviceAuthenticationWithTokenRefreash-klasse

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 TASK\<STRING\> SAFECREATENEWTOKEN(STRING IOTHUB, INT
SUGGESTEDTIMETOLIVE)

{

STRING RESULT;

STRING URL = STRING.FORMAT(\_STSCONNECTURL, IOTHUB, DEVICEID);

HTTPCLIENTHANDLER HANDLER = NEW HTTPCLIENTHANDLER();

HTTPCLIENT = NEW HTTPCLIENT(HANDLER);

TRY

{

VAR APIRESPONSE = HTTPCLIENT.GETASYNC(URL).RESULT;

IF (APIRESPONSE.ISSUCCESSSTATUSCODE)

{

RESULT = APIRESPONSE.CONTENT.READASSTRINGASYNC().RESULT;

}

ELSE

{

THROW NEW HTTPREQUESTEXCEPTION();

}

}

CATCH (HTTPREQUESTEXCEPTION)

{

RESULT = NULL;

}

RETURN TASK.FROMRESULT(RESULT);

}

}

Samenvatting van implementatie van SAS-tokenverificatie Azure IoT Hub apparaat-SDK voor .Net:

  1. Implementeert een concrete klasse op basis van de abstracte deviceAuthenticationWithTokenRefresh-klasse, waarmee de functionaliteit voor tokenvernieuwing wordt geïmplementeerd.

  2. Implementeert een ConnectionStatusChangesHandler om de status van de transportverbinding vast te leggen en uitzonderingen te voorkomen die worden veroorzaakt door transport-implementatie.

Verwijzingen:

Azure IoT Hub device SDK voor Java

De Azure IoT Client SDK voor Java implementeert ondersteuning voor levensduurbeheer van SAS-tokens via sasTokenProvider Interface. Een klasse die deze interface implementeert met de functionaliteit voor het vernieuwen van SAS-tokens, kan worden gebruikt als SecurityProvider in een DeviceClient-constructor. De transport-implementaties vernieuwen het token automatisch via de beveiligingsprovider, indien nodig. Er moet een ConnectionStatusChangeCallback worden geregistreerd om verbindingswijzigingen vast te leggen en te voorkomen dat er uitzonderingen worden veroorzaakt door de transporten.

Voorbeeld van implementatie van de beveiligingsprovider die de SasTokenProvider-interface implementeert:

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();

}

}

Samenvatting van implementatie van SAS-tokenverificatie Azure IoT Hub apparaat-SDK voor Java:

  1. Implementeert de SasTokenProvider-interface in een klasse en bevat functionaliteit voor tokenvernieuwing.

  2. Implementeert een ConnectionStatusChangeCallback-handler om wijzigingen in de transportverbindingsstatus vast te leggen en uitzonderingen te voorkomen die worden veroorzaakt door transport-implementatie.

Verwijzingen:

Azure IoT Hub device SDK voor Python

De Azure IoT Hub device SDK voor Python implementeert ondersteuning voor SAS-tokens via methoden op het IoTHubDeviceClient-object. Met deze methoden kunt u een apparaatclient maken met behulp van een token en de mogelijkheid om een bijgewerkt token op te geven zodra de apparaatclient is gemaakt. Ze implementeren geen levensduurbeheer van tokens, maar dit kan eenvoudig worden geïmplementeerd als een asynchrone bewerking.

Een Python 3.7-voorbeeld van een implementatie met alleen de overzicht van functionaliteit:

ASYNC DEF MAIN():

\# GET A SASTOKEN YOU GENERATED

SASTOKEN = GET\_NEW\_SASTOKEN()

\# THE CLIENT OBJECT IS USED TO INTERACT WITH YOUR AZURE IOT HUB.

DEVICE\_CLIENT = IOTHUBDEVICECLIENT.CREATE\_FROM\_SASTOKEN(SASTOKEN)

\# CONNECT THE CLIENT.

AWAIT DEVICE\_CLIENT.CONNECT()

\# DEFINE BEHAVIOR FOR PROVIDING NEW SASTOKENS 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 SASTOKEN KEEPALIVE IN THE EVENT LOOP

KEEPALIVE\_TASK = ASYNCIO.CREATE\_TASK(SASTOKEN\_KEEPALIVE())

\# CANCEL THE SASTOKEN UPDATE TASK

KEEPALIVE\_TASK.CANCEL()

\# FINALLY, SHUT DOWN THE CLIENT

AWAIT DEVICE\_CLIENT.SHUTDOWN()

IF \_\_NAME\_\_ == "\_\_MAIN\_\_":

ASYNCIO.RUN(MAIN())

Samenvatting van Azure IoT Hub apparaat-SDK voor verificatie van Python SAS-token:

  1. Maak de functie voor het genereren van SAS-tokens.

  2. Maak een apparaatclient met behulp van IoTHubDeviceClient.create _ vanuit _ sastoken.

  3. De levensduur van het token beheren als een afzonderlijke activiteit, waarbij de apparaatclient wordt voorzien van een vernieuwd token wanneer dit wordt vereist door de sastoken-methode IoTHubDeviceClient.update. _

Verwijzingen:

Azure IoT Hub device SDK voor Node.JS/JavaScript

De Azure IoT voor Node.JS/JavaScript implementeert een SharedAccessSignatureAuthenticationProvider die een SAS-token aan de apparaatclient zal bedienen en transporteert om te verifiëren met IoT Hub. Er wordt geen functionaliteit voor tokenvernieuwing geïmplementeerd. De apparaattoepassing moet de levensduur van het token beheren en het token indien nodig vernieuwen.

Gebruik de apparaatclientmethoden vanSharedAccessSignature en updateSharedAccessSignature om een verbinding met IoT Hub te initiëren en een vernieuwd token op te geven aan de SharedAccessSignatureteAuthenticationProvider, waardoor de verificatieprovider een newTokenAvailable-gebeurtenis naar de transporten stuurt.

Een eenvoudig SAS-tokenvoorbeeld is beschikbaar in het eenvoudige _ _ voorbeeldapparaat _ met _sas.js voorbeeld.

Samenvatting van Azure IoT Hub apparaat-SDK voor Node.JS/JavaScript

  1. Levensduurbeheer en verlenging van SAS-token implementeren.

  2. Gebruik de apparaatclient fromSharedAccessSignature om een client-exemplaar van het apparaat te maken.

  3. Gebruik apparaatclientupdateSharedAccessSignature om een vernieuwd token op te geven.

Verwijzingen:

Volgende stappen