Controllare l'accesso alle hub IoT con firme di accesso condiviso

hub IoT usa token di firma di accesso condiviso (SAS) per autenticare dispositivi e servizi per evitare l'invio di chiavi in transito. I token di firma di accesso condiviso vengono usati per concedere l'accesso limitato al tempo ai dispositivi e ai servizi a funzionalità specifiche in hub IoT. Per ottenere l'autorizzazione per connettersi a hub IoT, i dispositivi e i servizi devono inviare token di firma di accesso condiviso firmati con una chiave simmetrica o di accesso condiviso. Le chiavi simmetriche vengono archiviate con un'identità del dispositivo nel registro delle identità.

Questo articolo descrive:

  • Le diverse autorizzazioni che è possibile concedere a un client per accedere all'hub IoT.
  • I token hub IoT usano per verificare le autorizzazioni.
  • Come definire l'ambito delle credenziali per limitare l'accesso a risorse specifiche.
  • Meccanismo di autenticazione personalizzata del dispositivo che usa gli schemi di autenticazione o i registri di identità del dispositivo esistenti.

Nota

Alcune delle funzionalità indicate in questo articolo, come la messaggistica da cloud a dispositivo, i dispositivi gemelli e la gestione dei dispositivi, sono disponibili solo nel livello Standard dell'hub IoT. Per altre informazioni sui livelli di hub IoT basic e standard/gratuiti, vedere Scegliere il livello di hub IoT appropriato per la soluzione.

L'hub IoT usa le autorizzazioni per concedere l'accesso a ogni endpoint dell'hub stesso. Le autorizzazioni limitano l'accesso a un hub IoT in base alle funzionalità. È necessario avere le autorizzazioni appropriate per accedere agli endpoint dell'hub IoT. Un dispositivo, ad esempio, deve includere un token contenente le credenziali di sicurezza con ogni messaggio inviato all'hub IoT. Tuttavia, le chiavi di firma, come le chiavi simmetriche del dispositivo, non vengono mai inviate in transito.

Autenticazione e autorizzazione

L'autenticazione è il processo di dimostrazione di chi si dice di essere. L'autenticazione verifica l'identità di un utente o di un dispositivo per hub IoT. A volte viene abbreviato in AuthN. L'autorizzazione è il processo di conferma delle autorizzazioni per un utente o un dispositivo autenticato in hub IoT. Specifica le risorse e i comandi a cui è consentito l'accesso e le operazioni che è possibile eseguire con tali risorse e comandi. L'autorizzazione viene talvolta abbreviata in AuthZ.

Questo articolo descrive l'autenticazione e l'autorizzazione usando firme di accesso condiviso, che consente di raggruppare le autorizzazioni e concederle alle applicazioni usando chiavi di accesso e token di sicurezza firmati. È anche possibile usare chiavi simmetriche o chiavi di accesso condiviso per autenticare un dispositivo con hub IoT. I token di firma di accesso condiviso forniscono l'autenticazione per ogni chiamata effettuata dal dispositivo per hub IoT associando la chiave simmetrica a ogni chiamata.

Controllo dell'accesso e autorizzazioni

Usare i criteri di accesso condiviso per l'accesso a livello di hub IoT e le credenziali dei singoli dispositivi per limitare l'ambito dell'accesso solo a tale dispositivo.

Criteri di accesso condiviso a livello di hub IoT

I criteri di accesso condiviso possono concedere qualsiasi combinazione di autorizzazioni. È possibile definire i criteri nel portale di Azure a livello di codice usando le API REST delle risorse hub IoT o il comando az iot hub policy dell'interfaccia della riga di comando di Azure. Un hub IoT appena creato ha i criteri predefiniti seguenti:

Criteri di accesso condiviso Autorizzazioni
iothubowner Tutte le autorizzazioni
servizio Autorizzazioni ServiceConnect
dispositivo Autorizzazioni DeviceConnect
registryRead Autorizzazioni RegistryRead
registryReadWrite Autorizzazioni RegistryRead e RegistryWrite

È possibile usare le autorizzazioni seguenti per controllare l'accesso all'hub IoT:

  • L'autorizzazione Service Connessione viene usata dai servizi cloud back-end e concede l'accesso seguente:

    • Accesso agli endpoint di comunicazione e monitoraggio rivolti al servizio cloud.
    • Ricevere messaggi da dispositivo a cloud, inviare messaggi da cloud a dispositivo e recuperare i riconoscimenti di recapito corrispondenti.
    • Recuperare i riconoscimenti di recapito per i caricamenti di file.
    • Accedere ai dispositivi gemelli per aggiornare i tag e le proprietà desiderate, recuperare le proprietà segnalate ed eseguire query.
  • L'autorizzazione Device Connessione viene usata dai dispositivi e concede l'accesso seguente:

    • Accesso agli endpoint con connessione al dispositivo.
    • Inviare messaggi da dispositivo a cloud e ricevere messaggi da cloud a dispositivo.
    • Eseguire il caricamento di file.
    • Ricevere le notifiche delle proprietà desiderate del dispositivo gemello e aggiornare le proprietà segnalate del dispositivo gemello.
  • L'autorizzazione RegistryRead viene usata dai servizi cloud back-end e concede l'accesso seguente:

  • L'autorizzazione RegistryReadWrite viene usata dai servizi cloud back-end e concede l'accesso seguente:

Credenziali di sicurezza per dispositivo

Ogni hub IoT ha un registro delle identità che archivia le informazioni sui dispositivi e i moduli autorizzati a connettersi. Prima che un dispositivo o un modulo possa connettersi, deve essere presente una voce per tale dispositivo o modulo nel registro delle identità dell'hub IoT. Un dispositivo o un modulo esegue l'autenticazione con l'hub IoT in base alle credenziali archiviate nel registro delle identità.

Quando si registra un dispositivo per l'uso dell'autenticazione con token di firma di accesso condiviso, tale dispositivo ottiene due chiavi simmetriche. Le chiavi simmetriche concedono all'autorizzazione Device Connessione per l'identità del dispositivo associata.

Usare i token di firma di accesso condiviso dai servizi

I servizi possono generare token di firma di accesso condiviso usando criteri di accesso condiviso che definiscono le autorizzazioni appropriate come illustrato in precedenza nella sezione Controllo di accesso e autorizzazioni .

Ad esempio, un servizio che usa il criterio di accesso condiviso precreato denominato RegistryRead crea un token con i parametri seguenti:

  • URI della risorsa: {IoT hub name}.azure-devices.net,
  • chiave di firma: una delle chiavi del criterio registryRead ,
  • nome criterio: registryRead,
  • Qualsiasi ora di scadenza.

Ad esempio, il codice seguente crea un token di firma di accesso condiviso in Node.js:

var endpoint = "myhub.azure-devices.net";
var policyName = 'registryRead';
var policyKey = '...';

var token = generateSasToken(endpoint, policyKey, policyName, 60);

Il risultato, che concede l'accesso alla lettura di tutte le identità del dispositivo nel registro delle identità, sarà:

SharedAccessSignature sr=myhub.azure-devices.net&sig=JdyscqTpXdEJs49elIUCcohw2DlFDR3zfH5KqGJo4r4%3D&se=1456973447&skn=registryRead

Per altri esempi, vedere Generare token di firma di accesso condiviso.

Per i servizi, i token di firma di accesso condiviso concedono le autorizzazioni solo a livello di hub IoT. Ovvero, un servizio che esegue l'autenticazione con un token basato sui criteri del servizio sarà in grado di eseguire tutte le operazioni concesse dall'autorizzazione Service Connessione. Queste operazioni includono la ricezione di messaggi da dispositivo a cloud, l'invio di messaggi da cloud a dispositivo e così via. Se si vuole concedere l'accesso più granulare ai servizi, ad esempio limitando un servizio all'invio solo di messaggi da cloud a dispositivo, è possibile usare Microsoft Entra ID. Per altre informazioni, vedere Eseguire l'autenticazione con Microsoft Entra ID.

Usare i token di firma di accesso condiviso dai dispositivi

Esistono due modi per ottenere le autorizzazioni Device Connessione con hub IoT con token di firma di accesso condiviso: usare una chiave simmetrica del dispositivo dal registro delle identità o usare una chiave di accesso condiviso.

Tutte le funzionalità accessibili dai dispositivi vengono esposte dalla progettazione negli endpoint con il prefisso /devices/{deviceId}.

Gli endpoint per il dispositivo sono, indipendentemente dal protocollo:

Endpoint Funzionalità
{iot hub name}/devices/{deviceId}/messages/events Invio di messaggi da dispositivo a cloud.
{iot hub name}/devices/{deviceId}/messages/devicebound Ricezione di messaggi da cloud a dispositivo.

Usare una chiave simmetrica nel registro identità

Quando si usa una chiave simmetrica dell'identità del dispositivo per generare un token, l'elemento policyName (skn) del token viene omesso.

Ad esempio, un token creato per accedere a tutte le funzionalità del dispositivo deve avere i seguenti parametri:

  • URI della risorsa: {IoT hub name}.azure-devices.net/devices/{device id},
  • Chiave di firma: qualsiasi chiave simmetrica per l'identità {device id} ,
  • Nessun nome di criterio,
  • Qualsiasi ora di scadenza.

Ad esempio, il codice seguente crea un token di firma di accesso condiviso in Node.js:

var endpoint ="myhub.azure-devices.net/devices/device1";
var deviceKey ="...";

var token = generateSasToken(endpoint, deviceKey, null, 60);

Il risultato, che concede l'accesso a tutte le funzionalità per device1, sarà:

SharedAccessSignature sr=myhub.azure-devices.net%2fdevices%2fdevice1&sig=13y8ejUk2z7PLmvtwR5RqlGBOVwiq7rQR3WZ5xZX3N4%3D&se=1456971697

Per altri esempi, vedere Generare token di firma di accesso condiviso.

Usare un criterio di accesso condiviso per accedere per conto di un dispositivo

Quando si crea un token da criteri di accesso condiviso, impostare il campo skn sul nome dei criteri. Questi criteri devono concedere l'autorizzazione DeviceConnect.

I due scenari principali per l'uso di criteri di accesso condiviso per accedere alla funzionalità dei dispositivi sono:

Poiché i criteri di accesso condiviso possono concedere l'accesso alla connessione come qualsiasi dispositivo, è importante usare l'URI della risorsa corretto durante la creazione di token di firma di accesso condiviso. Questa impostazione è particolarmente importante per i servizi token, che devono limitare l'ambito del token a un dispositivo specifico usando l'URI risorsa. Questo punto è meno importante per i gateway di protocollo, in quanto già filtrano il traffico per tutti i dispositivi.

Ad esempio, un servizio token che usa i criteri di accesso condiviso precreati denominati dispositivo creerebbe un token con i parametri seguenti:

  • URI della risorsa: {IoT hub name}.azure-devices.net/devices/{device id},
  • chiave di firma: una delle chiavi del criterio device ,
  • nome criterio: device,
  • Qualsiasi ora di scadenza.

Ad esempio, il codice seguente crea un token di firma di accesso condiviso in Node.js:

var endpoint ="myhub.azure-devices.net/devices/device1";
var policyName = 'device';
var policyKey = '...';

var token = generateSasToken(endpoint, policyKey, policyName, 60);

Il risultato, che concede l'accesso a tutte le funzionalità per device1, sarà:

SharedAccessSignature sr=myhub.azure-devices.net%2fdevices%2fdevice1&sig=13y8ejUk2z7PLmvtwR5RqlGBOVwiq7rQR3WZ5xZX3N4%3D&se=1456971697&skn=device

Un gateway di protocollo può usare lo stesso token per tutti i dispositivi impostando l'URI della risorsa su myhub.azure-devices.net/devices.

Per altri esempi, vedere Generare token di firma di accesso condiviso.

Creare un servizio token per integrare i dispositivi esistenti

È possibile usare il registro delle identità di hub IoT per configurare le credenziali di sicurezza per dispositivo o per modulo e il controllo di accesso usando i token. Se una soluzione IoT ha già un registro personalizzato delle identità e/o uno schema di autenticazione, valutare la possibilità di creare un servizio token per integrare l'infrastruttura con l'hub IoT. In questo modo, è possibile usare altre funzionalità IoT nella soluzione.

Un servizio token è un servizio cloud personalizzato. Usa un criterio di accesso condiviso hub IoT con l'autorizzazione Device Connessione per creare token con ambito dispositivo o con ambito modulo. Questi token consentono a un dispositivo o a un modulo di connettersi all'hub IoT.

Diagramma che mostra i passaggi del modello di servizio token.

Di seguito vengono indicati i passaggi principali del modello del servizio token:

  1. Creare un hub IoT criteri di accesso condiviso con l'autorizzazione Device Connessione per l'hub IoT. È possibile creare questi criteri nel portale di Azure o a livello di programmazione. Il servizio token usa questi criteri per firmare i token creati.

  2. Quando un dispositivo o un modulo deve accedere all'hub IoT, richiede un token firmato dal servizio token. Il dispositivo può eseguire l'autenticazione con il registro delle identità personalizzato/lo schema di autenticazione per determinare l'identità del dispositivo/modulo usata dal servizio token per creare il token.

  3. Il servizio token restituisce un token. Il token viene creato usando /devices/{deviceId} o /devices/{deviceId}/modules/{moduleId} come resourceURI, con deviceId come dispositivo autenticato e moduleId come modulo da autenticare. Il servizio token usa i criteri di accesso condivisi per costruire il token.

  4. Il dispositivo/modulo usa il token direttamente con l'hub IoT.

Nota

È possibile usare la classe .NET SharedAccessSignatureBuilder o la classe Java IotHubServiceSasToken per creare un token nel servizio token.

Il servizio token può impostare la scadenza del token, in base alle esigenze. Quando il token scade, l'hub IoT interrompe la connessione del dispositivo/modulo. Il dispositivo/modulo deve quindi richiedere un nuovo token dal servizio token. Un intervallo di scadenza breve aumenta il carico sia sul dispositivo/modulo che sul servizio token.

Per consentire a un dispositivo/modulo di connettersi all'hub, è comunque necessario aggiungerlo al registro delle identità hub IoT, anche se usa un token e non una chiave per la connessione. È quindi possibile continuare a usare il controllo dell'accesso per ogni dispositivo/modulo abilitando o disabilitando le identità dei dispositivi/moduli nel registro delle identità. In questo modo si riduce il rischio che vengano usati token con intervalli di scadenza prolungati.

Confronto con un gateway personalizzato

Il modello di servizio token è il metodo consigliato per implementare uno schema di autenticazione/registro di identità personalizzato con l'hub IoT. Questo schema è consigliato perché l'hub IoT continua a gestire la maggior parte del traffico della soluzione. Tuttavia, se lo schema di autenticazione personalizzato è molto legato al protocollo, può essere necessario un gateway personalizzato per elaborare tutto il traffico. Un esempio di questo scenario è l'uso di Transport Layer Security (TLS) e delle chiavi precondivise (PSK). Per altre informazioni, vedere Come usare un dispositivo IoT Edge come gateway.

Genera token di firma di accesso condiviso

Gli SDK IoT di Azure generano automaticamente i token, ma alcuni scenari richiedono di generare e usare direttamente i token di firma di accesso condiviso, tra cui:

  • L'uso diretto di superfici MQTT, AMQP o HTTPS.

  • Implementazione del modello di servizio token, come illustrato nella sezione Creare un servizio token.

Un token firmato con una chiave di accesso condiviso concede l'accesso a tutte le funzionalità associate alle autorizzazioni dei criteri di accesso condiviso. Un token firmato con una chiave simmetrica dell'identità dispositivo concede solo l'autorizzazione DeviceConnect per l'identità del dispositivo associato.

In questa sezione vengono forniti esempi di generazione di token di firma di accesso condiviso in linguaggi di codice diversi. È anche possibile generare token di firma di accesso condiviso con il comando di estensione dell'interfaccia della riga di comando az iot hub generate-sas-token o l'estensione hub IoT di Azure per Visual Studio Code.

Struttura del token di firma di accesso condiviso

Un token di firma di accesso condiviso ha il formato seguente:

SharedAccessSignature sig={signature-string}&se={expiry}&skn={policyName}&sr={URL-encoded-resourceURI}

I valori previsti sono i seguenti:

Valore Descrizione
{signature} Stringa della firma HMAC-SHA256 nel formato: {URL-encoded-resourceURI} + "\n" + expiry. Importante: la chiave viene decodificata dalla codifica Base64 e usata come chiave per eseguire il calcolo di HMAC-SHA256.
{resourceURI} Prefisso URI (per segmento) degli endpoint a cui è possibile accedere tramite questo token e che inizia con il nome host dell'hub IoT senza il protocollo. I token di firma di accesso condiviso concessi ai servizi back-end hanno come ambito il livello dell'hub IoT; ad esempio . myHub.azure-devices.net I token di firma di accesso condiviso concessi ai dispositivi devono essere limitati a un singolo dispositivo; ad esempio . myHub.azure-devices.net/devices/device1
{expiry} Stringhe UTF8 per il numero di secondi trascorsi dalle 00:00:00 UTC dell'1 gennaio 1970.
{URL-encoded-resourceURI} Codifica URL con lettere minuscole dell'URI della risorsa con lettere minuscole
{policyName} Nome del criterio di accesso condiviso a cui fa riferimento il token. Assente se il token fa riferimento a credenziali del registro dei dispositivi.

il prefisso dell'URI viene calcolato in base al segmento e non in base al carattere. Ad esempio, /a/b è un prefisso per /a/b/c ma non per /a/bc.

Il codice seguente genera un token di firma di accesso condiviso usando l'URI della risorsa, la chiave di firma, il nome dei criteri e il periodo di scadenza. Nelle sezioni successive viene illustrato nel dettaglio come inizializzare gli input a seconda del caso d'uso.

var generateSasToken = function(resourceUri, signingKey, policyName, expiresInMins) {
    resourceUri = encodeURIComponent(resourceUri);

    // Set expiration in seconds
    var expires = (Date.now() / 1000) + expiresInMins * 60;
    expires = Math.ceil(expires);
    var toSign = resourceUri + '\n' + expires;

    // Use crypto
    var hmac = crypto.createHmac('sha256', Buffer.from(signingKey, 'base64'));
    hmac.update(toSign);
    var base64UriEncoded = encodeURIComponent(hmac.digest('base64'));

    // Construct authorization string
    var token = "SharedAccessSignature sr=" + resourceUri + "&sig="
    + base64UriEncoded + "&se=" + expires;
    if (policyName) token += "&skn="+policyName;
    return token;
};

Specifiche del protocollo

Ogni protocollo supportato, ad esempio MQTT, AMQP e HTTPS, trasporta i token in modo diverso.

Quando si usa MQTT, il pacchetto CONNECT ha deviceId come ClientId, {iothubhostname}/{deviceId} nel campo Username e un token di firma di accesso condiviso nel campo Password. {iothubhostname} deve essere il CName completo dell'hub IoT, ad esempio myhub.azure-devices.net.

Quando si usa AMQP, l'hub IoT supporta SASL PLAIN e la sicurezza basata sulle attestazioni AMQP.

Se si usa la sicurezza basata sulle attestazioni AMQP, lo standard specifica come trasmettere questi token.

Per SASL PLAIN username può essere:

  • {policyName}@sas.root.{iothubName} nel caso di token a livello di hub IoT.
  • {deviceId}@sas.{iothubname} ne caso di token con ambito relativo al dispositivo.

In entrambi i casi, il campo password contiene il token, come descritto in Struttura di token di firma di accesso condiviso.

Il protocollo HTTPS implementa l'autenticazione includendo un token valido nell'intestazione della richiesta Authorization .

Ad esempio, Nome utente (DeviceId fa distinzione tra maiuscole e minuscole): iothubname.azure-devices.net/DeviceId

Password (è possibile generare un token di firma di accesso condiviso con il comando di estensione dell'interfaccia della riga di comando az iot hub generate-sas-token o l'estensione hub IoT di Azure per Visual Studio Code):

SharedAccessSignature sr=iothubname.azure-devices.net%2fdevices%2fDeviceId&sig=kPszxZZZZZZZZZZZZZZZZZAhLT%2bV7o%3d&se=1487709501

Nota

Gli Azure IoT SDK generano automaticamente i token durante la connessione al servizio. In alcuni casi, gli Azure IoT SDK non supportano tutti i protocolli o tutti i metodi di autenticazione.

Considerazioni speciali su SASL PLAIN

Quando si usa SASL PLAIN con AMQP, un client che si connette a un hub IoT potrà usare un singolo token per ogni connessione TCP. Quando il token scade, la connessione TCP si disconnette dal servizio e attiva una riconnessione. Questo comportamento non genera problemi per un'app back-end, ma è dannoso per un'app per dispositivi per i motivi seguenti:

  • I gateway si connettono in genere per conto di molti dispositivi. Quando si usa SASL PLAIN, devono creare una connessione TCP distinta per ogni dispositivo che si connette a un hub IoT. Questo scenario aumenta in modo considerevole il consumo energetico e delle risorse di rete e incrementa la latenza della connessione di ogni dispositivo.

  • L'aumento dell'uso delle risorse per la riconnessione dopo la scadenza di ogni token influisce negativamente sui dispositivi vincolati alle risorse.

Passaggi successivi

In questa esercitazione si è appreso come controllare l'accesso all'hub IoT. Altri argomenti di interesse disponibili nella Guida per sviluppatori sono i seguenti: