Controllare l'accesso al servizio Device Provisioning in hub IoT di Azure con firme di accesso condiviso e token di sicurezza
Questo articolo illustra le opzioni disponibili per la protezione del servizio Device Provisioning in hub IoT di Azure. Il servizio di provisioning usa l'autenticazione e le autorizzazioni per concedere l'accesso a ogni endpoint. Le autorizzazioni consentono al processo di autenticazione di limitare l'accesso a un'istanza del servizio in base alle funzionalità.
Questo articolo illustra:
Il processo di autenticazione e i token usati dal servizio di provisioning per verificare le autorizzazioni per le API REST del servizio e del dispositivo.
Le diverse autorizzazioni che è possibile concedere a un'app back-end per accedere all'API del servizio.
Autenticazione
L'API del dispositivo supporta l'autenticazione basata su chiave e basata su certificati X.509.
L'API del servizio supporta l'autenticazione basata su chiave per le app back-end.
Quando si usa l'autenticazione basata su chiave, il servizio Device Provisioning usa token di sicurezza per autenticare i servizi, in modo da evitare l'invio di chiavi in transito. Inoltre, i token di sicurezza hanno una validità limitata in termini di tempo e portata. Gli SDK di Device Provisioning in Azure IoT generano automaticamente i token senza richiedere una configurazione speciale.
In alcuni casi può essere necessario usare direttamente le API REST HTTP del servizio Device Provisioning, senza usare gli SDK. Le sezioni seguenti descrivono come eseguire l'autenticazione direttamente nelle API REST.
Autenticazione con l'API del dispositivo
L'API del dispositivo viene usata dai dispositivi per attestare il servizio Device Provisioning e ricevere una connessione all'hub IoT.
Nota
Per ricevere una connessione autenticata, i dispositivi devono prima essere registrati nel servizio Device Provisioning mediante una registrazione. Usare l'API del servizio per registrare un dispositivo a livello di codice mediante una registrazione.
Un dispositivo deve eseguire l'autenticazione nell'API del dispositivo come parte del processo di provisioning. Il metodo che dispositivo userà per l'autenticazione si definisce quando si configura una registrazione singola o un gruppo di registrazioni. Indipendentemente dal metodo di autenticazione, il dispositivo deve inviare una richiesta HTTPS PUT all'URL seguente per effettuare il provisioning.
https://global.azure-devices-provisioning.net/[ID_Scope]/registrations/[registration_id]/register?api-version=2021-06-01
Se si usa l'autenticazione basata su chiave, un token di sicurezza viene passato nell'intestazione della richiesta HTTP Authorization nel formato seguente:
SharedAccessSignature sig={signature}&se={expiry}&skn={policyName}&sr={URL-encoded-resourceURI}
Struttura del token di sicurezza per l'autenticazione basata su chiave
Il token di sicurezza viene passato nell'intestazione della richiesta HTTP Authorization nel formato seguente:
SharedAccessSignature sig={signature}&se={expiry}&skn={policyName}&sr={URL-encoded-resourceURI}
I valori previsti sono:
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. |
{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 di {ID_Scope}/registrations/{registration_id} |
{policyName} |
Per l'API del dispositivo, questo criterio è sempre "registration". |
Il frammento di codice Python seguente mostra una funzione denominata generate_sas_token
che calcola il token dagli input uri
, key
, policy_name
, expiry
per una singola registrazione usando un tipo di autenticazione con chiave simmetrica.
from base64 import b64encode, b64decode, encode
from hashlib import sha256
from time import time
from urllib.parse import quote_plus, urlencode
from hmac import HMAC
def generate_sas_token(uri, key, policy_name, expiry=3600):
ttl = time() + expiry
sign_key = "%s\n%d" % ((quote_plus(uri)), int(ttl))
signature = b64encode(HMAC(b64decode(key), sign_key.encode('utf-8'), sha256).digest())
rawtoken = {
'sr' : uri,
'sig': signature,
'se' : str(int(ttl)),
'skn' : policy_name
}
return 'SharedAccessSignature ' + urlencode(rawtoken)
print(generate_sas_token("myIdScope/registrations/mydeviceregistrationid", "00mysymmetrickey", "registration"))
Il risultato dovrebbe essere simile all'output seguente:
SharedAccessSignature sr=myIdScope%2Fregistrations%2Fmydeviceregistrationid&sig=SDpdbUNk%2F1DSjEpeb29BLVe6gRDZI7T41Y4BPsHHoUg%3D&se=1630175722&skn=registration
L'esempio seguente mostra come viene usata la firma di accesso condiviso per l'autenticazione con l'API del dispositivo.
curl -L -i -X PUT -H 'Content-Type: application/json' -H 'Content-Encoding: utf-8' -H 'Authorization: [token]' -d '{"registrationId": "[registration_id]"}' https://global.azure-devices-provisioning.net/[ID_Scope]/registrations/[registration_id]/register?api-version=2021-06-01
Se si usa un gruppo di registrazioni basato su chiave simmetrica, sarà necessario generare prima una chiave device symmetric
usando la chiave del gruppo di registrazioni. Usare la chiave primaria o secondaria del gruppo di registrazioni per calcolare una firma HMAC-SHA256 dell'ID di registrazione per il dispositivo. Il risultato viene quindi convertito in formato Base64 per ottenere la chiave del dispositivo derivata. Per visualizzare esempi di codice, vedere Come effettuare il provisioning dei dispositivi usando i gruppi di registrazione con chiave simmetrica. Dopo aver derivato la chiave simmetrica del dispositivo, è possibile registrare il dispositivo usando gli esempi precedenti.
Avviso
Per evitare di includere la chiave master del gruppo nel codice del dispositivo, il processo di derivazione della chiave del dispositivo deve essere eseguito fuori dal dispositivo.
Autenticazione basata su certificati
Se è stata configurata una registrazione singola o un gruppo di registrazioni per l'autenticazione basata sul certificato X.509, il dispositivo dovrà usare il certificato X.509 rilasciato per attestare l'API del dispositivo. Per informazioni su come configurare la registrazione e generare il certificato del dispositivo, fare riferimento agli articoli seguenti.
Avvio rapido: Effettuare il provisioning di un dispositivo X.509 simulato nell'hub IoT di Azure
Avvio rapido: Registrare dispositivi X.509 nel servizio Device Provisioning di Azure
Una volta configurata la registrazione e rilasciato il certificato del dispositivo, l'esempio seguente illustra come eseguire l'autenticazione all'API del dispositivo con il certificato X.509 del dispositivo.
curl -L -i -X PUT –cert ./[device_cert].pem –key ./[device_cert_private_key].pem -H 'Content-Type: application/json' -H 'Content-Encoding: utf-8' -d '{"registrationId": "[registration_id]"}' https://global.azure-devices-provisioning.net/[ID_Scope]/registrations/[registration_id]/register?api-version=2021-06-01
Autenticazione con l'API del servizio
L'API del servizio viene usata per recuperare lo stato della registrazione e rimuovere le registrazioni del dispositivo. Il servizio viene usato anche dalle app back-end per gestire a livello di codice sia singoli gruppi che gruppi di registrazioni. L'API del servizio supporta l'autenticazione basata su chiave per le app back-end.
Per accedere a qualunque endpoint dell'API del servizio è necessario disporre delle autorizzazioni appropriate. Un'app back-end, ad esempio, deve includere un token contenente le credenziali di sicurezza con ogni messaggio inviato al servizio.
Il servizio Device Provisioning in hub IoT di Azure concede l'accesso agli endpoint tramite la verifica del token rispetto ai criteri di accesso condiviso. Le credenziali di sicurezza, ad esempio le chiavi asimmetriche, non vengono mai trasmesse in rete.
Controllo dell'accesso e autorizzazioni
Per concedere le autorizzazioni è possibile procedere nei modi seguenti:
Criteri di autorizzazione dell'accesso condiviso. I criteri di accesso condiviso possono concedere qualsiasi combinazione di autorizzazioni. È possibile definire i criteri nel portale di Azure o a livello di codice usando le API REST del servizio Device Provisioning. Un servizio di provisioning appena creato ha i criteri predefiniti seguenti:
provisioningserviceowner: criteri con tutte le autorizzazioni. Per informazioni dettagliate, vedere Autorizzazioni.
Nota
Il servizio Device Provisioning viene protetto tramite la sottoscrizione di Azure, analogamente a tutti i provider in Azure Resource Manager.
Per altre informazioni sulla creazione e sull'uso di token di sicurezza, vedere la sezione seguente.
Il protocollo HTTP è l'unico protocollo supportato e implementa l'autenticazione includendo un token valido nell'intestazione della richiesta Authorization.
Esempio
SharedAccessSignature sr =
mydps.azure-devices-provisioning.net&sig=kPszxZZZZZZZZZZZZZZZZZAhLT%2bV7o%3d&se=1487709501&skn=provisioningserviceowner`\
Nota
Gli SDK del servizio Device Provisioning in hub IoT generano automaticamente i token durante la connessione al servizio.
Token di sicurezza
Il servizio Device Provisioning usa i token di sicurezza per autenticare i servizi ed evitare l'invio in rete delle chiavi. Inoltre, i token di sicurezza hanno una validità limitata in termini di tempo e portata. Gli SDK del servizio Device Provisioning in hub IoT generano automaticamente i token senza richiedere una configurazione speciale. In alcuni scenari è necessario generare e usare direttamente i token di sicurezza. Questi scenari includono l'uso diretto di superfici HTTP.
Struttura dei token di sicurezza
I token di sicurezza consentono di concedere a servizi l'accesso con limite temporale a funzionalità specifiche del servizio Device Provisioning in hub IoT. Per ottenere l'autorizzazione per connettersi al servizio di provisioning, i dispositivi e i servizi devono inviare i token di sicurezza firmati con una chiave di accesso condiviso o una chiave simmetrica.
Un token firmato con una chiave di accesso condiviso concede l'accesso a tutte le funzionalità associate alle autorizzazioni dei criteri di accesso condiviso.
Il token di sicurezza ha il formato seguente:
SharedAccessSignature sig={signature}&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. |
{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 Prefisso URI (per segmento) degli endpoint a cui è possibile accedere tramite questo token e che inizia con il nome host del servizio Device Provisioning in hub IoT senza il protocollo. Ad esempio: mydps.azure-devices-provisioning.net . |
{policyName} | Nome del criterio di accesso condiviso a cui fa riferimento il token. |
Nota
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 frammento seguente di Node.js mostra una funzione denominata generateSasToken che calcola il token dagli input resourceUri, signingKey, policyName, expiresInMins
. 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', new Buffer(signingKey, 'base64'));
hmac.update(toSign);
var base64UriEncoded = encodeURIComponent(hmac.digest('base64'));
// Construct authorization string
var token = "SharedAccessSignature sr=" + resourceUri + "&sig="
+ base64UriEncoded + "&se=" + expires + "&skn="+ policyName;
return token;
};
Per fare un confronto, l'equivalente in termini di codice Python per generare un token di sicurezza è:
from base64 import b64encode, b64decode
from hashlib import sha256
from time import time
from urllib.parse import quote_plus, urlencode
from hmac import HMAC
def generate_sas_token(uri, key, policy_name, expiry=3600):
ttl = time() + expiry
sign_key = "%s\n%d" % ((quote_plus(uri)), int(ttl))
print sign_key
signature = b64encode(HMAC(b64decode(key), sign_key, sha256).digest())
rawtoken = {
'sr' : uri,
'sig': signature,
'se' : str(int(ttl)),
'skn' : policy_name
}
return 'SharedAccessSignature ' + urlencode(rawtoken)
Nota
Poiché la validità temporale del token viene verificata sui computer del servizio Device Provisioning in hub IoT, lo sfasamento dell'orologio del computer che genera il token deve essere minimo.
Usare token di sicurezza da componenti del servizio
I componenti del servizio possono generare token di sicurezza solo usando criteri di accesso condiviso che concedono le autorizzazioni appropriate, come illustrato prima.
Di seguito vengono indicate le funzioni del servizio esposte sugli endpoint:
Endpoint | Funzionalità |
---|---|
{your-service}.azure-devices-provisioning.net/enrollments |
Fornisce operazioni di registrazione del dispositivo con il servizio Device Provisioning. |
{your-service}.azure-devices-provisioning.net/enrollmentGroups |
Fornisce operazioni per la gestione dei gruppi di registrazione del dispositivo. |
{your-service}.azure-devices-provisioning.net/registrations/{id} |
Fornisce operazioni per il recupero e la gestione dello stato delle registrazioni dei dispositivi. |
Ad esempio, un servizio generato con il criterio di accesso condiviso già esistente denominato enrollmentread
creerebbe un token con i parametri seguenti:
- URI della risorsa:
{mydps}.azure-devices-provisioning.net
, - chiave di firma: una delle chiavi del criterio
enrollmentread
, - nome criterio:
enrollmentread
, - qualsiasi ora di scadenza time.backn
var endpoint ="mydps.azure-devices-provisioning.net";
var policyName = 'enrollmentread';
var policyKey = '...';
var token = generateSasToken(endpoint, policyKey, policyName, 60);
Il risultato, che concede l'accesso in lettura a tutti i record di registrazione, sarà:
SharedAccessSignature sr=mydps.azure-devices-provisioning.net&sig=JdyscqTpXdEJs49elIUCcohw2DlFDR3zfH5KqGJo4r4%3D&se=1456973447&skn=enrollmentread
SDK ed esempi
- Azure IoT SDK for Java Preview Release (Azure IoT SDK per la versione di anteprima di Java)
- Microsoft Azure IoT SDKs for .NET Preview Release (SDK di Microsoft Azure IoT per la versione di anteprima di .NET)
Argomenti di riferimento:
Gli argomenti di riferimento seguenti offrono altre informazioni sul controllo dell'accesso al servizio Device Provisioning in hub IoT.
Autorizzazioni per il servizio Device Provisioning
La tabella seguente elenca le autorizzazioni che è possibile usare per controllare l'accesso al servizio Device Provisioning in hub IoT.
Autorizzazione | Note |
---|---|
ServiceConfig | Concede l'accesso per la modifica delle configurazioni del servizio. Questa autorizzazione viene usata dai servizi cloud back-end. |
EnrollmentRead | Concede l'accesso in lettura alle registrazioni dei dispositivi e ai gruppi di registrazione. Questa autorizzazione viene usata dai servizi cloud back-end. |
EnrollmentWrite | Concede l'accesso in scrittura alle registrazioni dei dispositivi e ai gruppi di registrazione. Questa autorizzazione viene usata dai servizi cloud back-end. |
RegistrationStatusRead | Concede l'accesso in lettura allo stato della registrazione dei dispositivi. Questa autorizzazione viene usata dai servizi cloud back-end. |
RegistrationStatusWrite | Concede l'accesso con autorizzazione di eliminazione allo stato della registrazione dei dispositivi. Questa autorizzazione viene usata dai servizi cloud back-end. |