Kontrollera åtkomsten till Azure IoT Hub Device Provisioning Service (DPS) med signaturer för delad åtkomst och säkerhetstoken

I den här artikeln beskrivs tillgängliga alternativ för att skydda din Azure IoT Hub Device Provisioning Service (DPS). Etableringstjänsten använder autentisering och behörigheter för att bevilja åtkomst till varje slutpunkt. Med behörigheter kan autentiseringsprocessen begränsa åtkomsten till en tjänstinstans baserat på funktioner.

I den här artikeln beskrivs:

  • Autentiseringsprocessen och token som etableringstjänsten använder för att verifiera behörigheter mot både REST-API:er för tjänst och enhet.

  • De olika behörigheter som du kan bevilja till en serverdelsapp för att få åtkomst till tjänst-API:et.

Autentisering

Enhets-API:et stöder nyckelbaserad och X.509-certifikatbaserad enhetsautentisering.

Tjänst-API:et stöder nyckelbaserad autentisering för serverdelsappar.

När du använder nyckelbaserad autentisering använder Enhetsetableringstjänsten säkerhetstoken för att autentisera tjänster för att undvika att skicka nycklar på kabeln. Dessutom är säkerhetstoken begränsade i tids giltighet och omfång. Azure IoT Device Provisioning SDK:er genererar automatiskt token utan att kräva någon särskild konfiguration.

I vissa fall kan du behöva använda REST-API:erna för HTTP Device Provisioning Service direkt, utan att använda SDK:erna. I följande avsnitt beskrivs hur du autentiserar direkt mot REST-API:erna.

Autentisering med enhets-API

Enhets-API:et används av enheter för att intyga enhetsetableringstjänsten och ta emot en IoT Hub-anslutning.

Kommentar

För att kunna ta emot en autentiserad anslutning måste enheterna först registreras i Device Provisioning Service via en registrering. Använd tjänst-API:et för att programmatiskt registrera en enhet via en registrering.

En enhet måste autentisera till enhets-API:et som en del av etableringsprocessen. Metoden som en enhet använder för att autentisera definieras när du konfigurerar en registreringsgrupp eller enskild registrering. Oavsett autentiseringsmetod måste enheten utfärda en HTTPS PUT till följande URL för att etablera sig själv.

    https://global.azure-devices-provisioning.net/[ID_Scope]/registrations/[registration_id]/register?api-version=2021-06-01

Om du använder nyckelbaserad autentisering skickas en säkerhetstoken i rubriken FÖR HTTP-auktoriseringsbegäran i följande format:

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

Struktur för säkerhetstoken för nyckelbaserad autentisering

Säkerhetstoken skickas i rubriken FÖR HTTP-auktoriseringsbegäran i följande format:

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

De förväntade värdena är:

Värde Description
{signature} En HMAC-SHA256-signatursträng i formuläret: {URL-encoded-resourceURI} + "\n" + expiry. Viktigt: Nyckeln avkodas från base64 och används som nyckel för att utföra HMAC-SHA256-beräkningen.
{expiry} UTF8-strängar för antal sekunder sedan epoken 00:00:00 UTC den 1 januari 1970.
{URL-encoded-resourceURI} Gemener URL-kodning av {ID_Scope}/registrations/{registration_id}
{policyName} För enhets-API:et är den här principen alltid "registrering".

Följande Python-kodfragment visar en funktion med namnet generate_sas_token som beräknar token från indata uri, key, policy_name, expiry för en enskild registrering med en symmetrisk nyckelautentiseringstyp.


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"))

Resultatet bör likna följande utdata:


SharedAccessSignature sr=myIdScope%2Fregistrations%2Fmydeviceregistrationid&sig=SDpdbUNk%2F1DSjEpeb29BLVe6gRDZI7T41Y4BPsHHoUg%3D&se=1630175722&skn=registration 

I följande exempel visas hur signaturen för delad åtkomst sedan används för att autentisera med enhets-API:et.


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 

Om du använder en symmetrisk nyckelbaserad registreringsgrupp måste du först generera en device symmetric nyckel med hjälp av registreringsgruppsnyckeln. Använd registreringsgruppens primära eller sekundära nyckel för att beräkna en HMAC-SHA256 av registrerings-ID:t för enheten. Resultatet konverteras sedan till Base64-format för att hämta den härledda enhetsnyckeln. Information om hur du visar kodexempel finns i Så här etablerar du enheter med hjälp av symmetriska nyckelregistreringsgrupper. När enhetens symmetriska nyckel har härletts kan du registrera enheten med hjälp av föregående exempel.

Varning

För att undvika att inkludera grupphuvudnyckeln i enhetskoden bör processen med att härleda enhetsnyckeln utföras utanför enheten.

Certifikatbaserad autentisering

Om du har konfigurerat en enskild registrerings- eller registreringsgrupp för X.509-certifikatbaserad autentisering måste enheten använda sitt utfärdade X.509-certifikat för att intyga enhets-API:et. Se följande artiklar om hur du konfigurerar registreringen och genererar enhetscertifikatet.

När registreringen har konfigurerats och enhetscertifikatet har utfärdats visar följande exempel hur du autentiserar till enhets-API:et med enhetens X.509-certifikat.


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 

Tjänst-API-autentisering

Tjänst-API:et används för att hämta registreringstillstånd och ta bort enhetsregistreringar. Tjänsten används också av serverdelsappar för att programmatiskt hantera både enskilda grupper och registreringsgrupper. Tjänst-API:et stöder nyckelbaserad autentisering för serverdelsappar.

Du måste ha rätt behörighet för att få åtkomst till någon av tjänst-API:ets slutpunkter. En serverdelsapp måste till exempel innehålla en token som innehåller säkerhetsautentiseringsuppgifter tillsammans med varje meddelande den skickar till tjänsten.

Azure IoT Hub Device Provisioning Service ger åtkomst till slutpunkter genom att verifiera token mot principerna för delad åtkomst. Säkerhetsautentiseringsuppgifter, till exempel symmetriska nycklar, skickas aldrig via kabeln.

Åtkomstkontroll och behörigheter

Du kan bevilja behörigheter på följande sätt:

  • Auktoriseringsprinciper för delad åtkomst. Principer för delad åtkomst kan ge valfri kombination av behörigheter. Du kan definiera principer i Azure-portalen eller programmatiskt med hjälp av REST-API:erna för Enhetsetableringstjänsten. En nytableringstjänst har följande standardprincip:

  • provisioningserviceowner: Princip med alla behörigheter. Mer information finns i behörigheter .

Kommentar

Resursprovidern Device Provisioning Service skyddas via din Azure-prenumeration, liksom alla leverantörer i Azure Resource Manager.

Mer information om hur du skapar och använder säkerhetstoken finns i nästa avsnitt.

HTTP är det enda protokoll som stöds och implementerar autentisering genom att inkludera en giltig token i rubriken auktoriseringsbegäran .

Exempel

SharedAccessSignature sr = 
   mydps.azure-devices-provisioning.net&sig=kPszxZZZZZZZZZZZZZZZZZAhLT%2bV7o%3d&se=1487709501&skn=provisioningserviceowner`\

Kommentar

Azure IoT Device Provisioning Service SDK:er genererar automatiskt token när du ansluter till tjänsten.

Säkerhetstoken

Device Provisioning Service använder säkerhetstoken för att autentisera tjänster för att undvika att skicka nycklar på kabeln. Dessutom är säkerhetstoken begränsade i tids giltighet och omfång. Azure IoT Device Provisioning Service SDK:er genererar automatiskt token utan att kräva någon särskild konfiguration. Vissa scenarier kräver att du genererar och använder säkerhetstoken direkt. Sådana scenarier omfattar direkt användning av HTTP-ytan.

Struktur för säkerhetstoken

Du använder säkerhetstoken för att bevilja tidsbegränsad åtkomst för tjänster till specifika funktioner i IoT Device Provisioning Service. För att få auktorisering för att ansluta till etableringstjänsten måste tjänsterna skicka säkerhetstoken som är signerade med antingen delad åtkomst eller symmetrisk nyckel.

En token som är signerad med en nyckel för delad åtkomst ger åtkomst till alla funktioner som är associerade med behörigheterna för principen för delad åtkomst.

Säkerhetstoken har följande format:

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

Här är de förväntade värdena

Värde Description
{signature} En HMAC-SHA256-signatursträng i formuläret: {URL-encoded-resourceURI} + "\n" + expiry. Viktigt: Nyckeln avkodas från base64 och används som nyckel för att utföra HMAC-SHA256-beräkningen.
{expiry} UTF8-strängar för antal sekunder sedan epoken 00:00:00 UTC den 1 januari 1970.
{URL-encoded-resourceURI} Gemener URL-kodning för URI:n för gemener. URI-prefix (efter segment) för de slutpunkter som kan nås med den här token, från och med värdnamnet för IoT Device Provisioning Service (inget protokoll). Till exempel mydps.azure-devices-provisioning.net.
{policyName} Namnet på den princip för delad åtkomst som denna token refererar till.

Kommentar

URI-prefixet beräknas efter segment och inte efter tecken. Till exempel /a/b är ett prefix för /a/b/c men inte för /a/bc.

Följande Node.js-kodfragment visar en funktion med namnet generateSasToken som beräknar token från indata resourceUri, signingKey, policyName, expiresInMins. I nästa avsnitt beskrivs hur du initierar de olika indata för de olika tokenanvändningsfallen.

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;
};

Som jämförelse är motsvarande Python-kod för att generera en säkerhetstoken:

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)

Kommentar

Eftersom tids giltigheten för token verifieras på IoT Device Provisioning Service-datorer måste driften på klockan på den dator som genererar token vara minimal.

Använda säkerhetstoken från tjänstkomponenter

Tjänstkomponenter kan bara generera säkerhetstoken med hjälp av principer för delad åtkomst som beviljar lämpliga behörigheter enligt beskrivningen tidigare.

Här är tjänstfunktionerna som exponeras på slutpunkterna:

Slutpunkt Funktioner
{your-service}.azure-devices-provisioning.net/enrollments Tillhandahåller enhetsregistreringsåtgärder med device provisioning-tjänsten.
{your-service}.azure-devices-provisioning.net/enrollmentGroups Tillhandahåller åtgärder för att hantera enhetsregistreringsgrupper.
{your-service}.azure-devices-provisioning.net/registrations/{id} Tillhandahåller åtgärder för att hämta och hantera status för enhetsregistreringar.

Till exempel skulle en tjänst som genererats med hjälp av en i förväg skapad princip för delad åtkomst med namnet enrollmentread skapa en token med följande parametrar:

  • resurs-URI: {mydps}.azure-devices-provisioning.net,
  • signeringsnyckel: en av principernas enrollmentread nycklar,
  • principnamn: enrollmentread,
  • någon förfallotid.backn

Create a shared access policy for your Device Provisioning Service instance in the portal

var endpoint ="mydps.azure-devices-provisioning.net";
var policyName = 'enrollmentread'; 
var policyKey = '...';

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

Resultatet, som skulle ge åtkomst till att läsa alla registreringsposter, skulle vara:

SharedAccessSignature sr=mydps.azure-devices-provisioning.net&sig=JdyscqTpXdEJs49elIUCcohw2DlFDR3zfH5KqGJo4r4%3D&se=1456973447&skn=enrollmentread

SDK:er och exempel

Referensämnen:

Följande referensavsnitt innehåller mer information om hur du styr åtkomsten till din IoT Device Provisioning-tjänst.

Behörigheter för enhetsetableringstjänsten

I följande tabell visas de behörigheter som du kan använda för att styra åtkomsten till din IoT Device Provisioning-tjänst.

Behörighet OBS!
ServiceConfig Ger åtkomst till att ändra tjänstkonfigurationerna.
Den här behörigheten används av serverdelsmolntjänster.
EnrollmentRead Ger läsbehörighet till enhetsregistreringar och registreringsgrupper.
Den här behörigheten används av serverdelsmolntjänster.
EnrollmentWrite Ger skrivåtkomst till enhetsregistreringar och registreringsgrupper.
Den här behörigheten används av serverdelsmolntjänster.
RegistrationStatusRead Beviljar läsbehörighet till enhetens registreringsstatus.
Den här behörigheten används av serverdelsmolntjänster.
RegistrationStatusWrite Beviljar borttagningsåtkomst till enhetens registreringsstatus.
Den här behörigheten används av serverdelsmolntjänster.