Mengontrol akses ke Azure IoT Hub Device Provisioning Service (DPS) dengan tanda tangan akses bersama dan token keamanan

Artikel ini menjelaskan opsi yang tersedia untuk mengamankan Azure IoT Hub Device Provisioning Service (DPS) Anda. Layanan provisi menggunakan autentikasi dan izin untuk memberikan akses ke setiap titik akhir. Izin memungkinkan proses autentikasi untuk membatasi akses ke instans layanan berdasarkan fungsionalitas.

Artikel ini membahas:

  • Proses autentikasi dan token yang digunakan layanan provisi untuk memverifikasi izin terhadap API REST Layanan dan Perangkat.

  • Berbagai izin yang dapat Anda berikan ke aplikasi backend untuk mengakses API Layanan.

Autentikasi

API Perangkat mendukung autentikasi perangkat berbasis kunci dan sertifikat X.509.

API Layanan mendukung autentikasi berbasis kunci untuk aplikasi backend.

Saat menggunakan autentikasi berbasis kunci, Device Provisioning Service menggunakan token keamanan untuk mengautentikasi layanan guna menghindari pengiriman kunci melalui kabel. Selain itu, token keamanan dibatasi dalam masa berlaku dan cakupan. Azure IoT Device Provisioning SDK secara otomatis menghasilkan token tanpa memerlukan konfigurasi khusus apa pun.

Dalam beberapa kasus, Anda mungkin perlu menggunakan REST API Device Provisioning Service HTTP secara langsung, tanpa menggunakan SDK. Bagian berikut menjelaskan cara mengautentikasi secara langsung terhadap REST API.

Autentikasi API Perangkat

API Perangkat digunakan oleh perangkat untuk membuktikan Device Provisioning Service dan menerima koneksi IoT Hub.

Catatan

Untuk menerima koneksi yang diautentikasi, perangkat harus terlebih dahulu didaftarkan di Device Provisioning Service melalui pendaftaran. Gunakan API Layanan untuk mendaftarkan perangkat secara terprogram melalui pendaftaran.

Perangkat harus mengautentikasi ke API Perangkat sebagai bagian dari proses provisi. Metode yang digunakan perangkat untuk mengautentikasi ditentukan ketika Anda menyiapkan grup pendaftaran atau pendaftaran individu. Apa pun metode autentikasinya, perangkat harus mengeluarkan HTTPS PUT ke URL berikut untuk memprovisikan sendiri.

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

Jika menggunakan autentikasi berbasis kunci, token keamanan diteruskan di header permintaan Otorisasi HTTP dalam format berikut:

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

Struktur token keamanan untuk autentikasi berbasis kunci

Token keamanan diteruskan di header permintaan Otorisasi HTTP dalam format berikut:

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

Nilai yang diharapkan adalah:

Nilai Deskripsi
{signature} Untai (karakter) tanda tangan HMAC-SHA256 formulir: {URL-encoded-resourceURI} + "\n" + expiry. Penting: Kunci didekodekan dari base64 dan digunakan sebagai kunci untuk melakukan perhitungan HMAC-SHA256.
{expiry} String UTF8 untuk jumlah detik sejak masa 00:00:00 UTC pada 1 Januari 1970.
{URL-encoded-resourceURI} Pengodean URL huruf kecil dari {ID_Scope}/registrations/{registration_id}
{policyName} Untuk API Perangkat, kebijakan ini selalu "pendaftaran".

Cuplikan Python berikut menunjukkan fungsi yang disebut generate_sas_token yang menghitung token dari input uri, , key, policy_nameexpiry untuk pendaftaran individu menggunakan jenis autentikasi kunci konten.


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

Hasilnya akan menyerupai output berikut:


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

Contoh berikut menunjukkan cara tanda tangan akses bersama digunakan untuk mengautentikasi dengan API Perangkat.


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 

Jika menggunakan grup pendaftaran berbasis kunci konten, Anda harus terlebih dahulu membuat kunci device symmetric menggunakan kunci grup pendaftaran. Gunakan kunci primer atau sekunder grup pendaftaran untuk menghitung HMAC-SHA256 dari ID pendaftaran untuk perangkat. Hasilnya kemudian diubah menjadi format Base64 untuk mendapatkan kunci perangkat turunan. Untuk melihat contoh kode, lihat Cara memprovisikan perangkat menggunakan grup pendaftaran kunci konten. Setelah kunci konten perangkat diturunkan, Anda dapat mendaftarkan perangkat menggunakan contoh sebelumnya.

Peringatan

Untuk menghindari memasukkan kunci master grup dalam kode perangkat Anda, proses penurunan kunci perangkat harus dilakukan dari perangkat.

Autentikasi berbasis sertifikat

Jika Anda telah menyiapkan pendaftaran individu atau grup pendaftaran untuk autentikasi berbasis sertifikat X.509, perangkat harus menggunakan sertifikat X.509 yang dikeluarkan untuk membuktikan API Perangkat. Lihat artikel berikut tentang cara menyiapkan pendaftaran dan membuat sertifikat perangkat.

Setelah pendaftaran telah disiapkan dan sertifikat perangkat dikeluarkan, contoh berikut menunjukkan cara mengautentikasi ke API Perangkat dengan sertifikat X.509 perangkat.


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 

Autentikasi API Layanan

API Layanan digunakan untuk mengambil status pendaftaran dan menghapus pendaftaran perangkat. Layanan ini juga digunakan oleh aplikasi backend untuk mengelola grup individu dan grup pendaftaran secara terprogram. API Layanan mendukung autentikasi berbasis kunci untuk aplikasi backend.

Anda harus memiliki izin yang sesuai untuk mengakses salah satu titik akhir API Layanan. Misalnya, aplikasi backend harus menyertakan token yang berisi info masuk keamanan bersama dengan setiap pesan yang dikirim ke layanan.

Azure IoT Hub Device Provisioning Service memberikan akses ke titik akhir dengan memverifikasi token terhadap kebijakan akses bersama. Info masuk keamanan, seperti kunci simetris, tidak pernah dikirim melalui kawat.

Kontrol akses dan izin

Anda bisa memberikan izin dengan cara berikut:

  • Kebijakan otorisasi akses bersama. Kebijakan akses bersama dapat memberikan kombinasi izin apa pun. Anda dapat menentukan kebijakan di portal Microsoft Azure, atau secara terprogram dengan menggunakan REST API Device Provisioning Service. Layanan provisi yang baru dibuat memiliki kebijakan default berikut:

  • provisioningserviceowner: Kebijakan dengan semua izin. Lihat izin untuk informasi selengkapnya.

Catatan

Penyedia sumber daya Layanan Provisi Perangkat diamankan melalui langganan Azure Anda, seperti halnya semua penyedia di Azure Resource Manager.

Untuk informasi selengkapnya tentang cara membuat dan menggunakan token keamanan, lihat bagian berikutnya.

HTTP adalah satu-satunya protokol yang didukung, dan menerapkan autentikasi dengan menyertakan token yang valid di header permintaan Otorisasi.

Contoh

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

Catatan

SDK Azure IoT Device Provisioning Service secara otomatis menghasilkan token saat menyambungkan ke layanan.

Token keamanan

Layanan Provisi Perangkat menggunakan token keamanan untuk mengautentikasi layanan untuk menghindari pengiriman kunci pada kawat. Selain itu, token keamanan dibatasi dalam masa berlaku dan cakupan. SDK Azure IoT Device Provisioning Service secara otomatis menghasilkan token tanpa memerlukan konfigurasi khusus apa pun. Beberapa skenario mengharuskan Anda untuk menghasilkan dan menggunakan token keamanan secara langsung. Skenario semacam itu mencakup penggunaan langsung permukaan HTTP.

Struktur token keamanan

Anda menggunakan token keamanan untuk memberikan akses terbatas waktu untuk layanan ke fungsionalitas tertentu di IoT Hub Device Provisioning Service. Agar otorisasi untuk terhubung ke layanan provisi, layanan harus mengirim token keamanan yang ditandatangani dengan akses bersama atau kunci simetris.

Token yang ditandatangani dengan kunci akses bersama memberi akses ke semua fungsionalitas yang terkait dengan izin kebijakan akses bersama.

Token keamanan memiliki format berikut:

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

Berikut adalah nilai yang diharapkan

Nilai Deskripsi
{signature} Untai (karakter) tanda tangan HMAC-SHA256 formulir: {URL-encoded-resourceURI} + "\n" + expiry. Penting: Kunci didekodekan dari base64 dan digunakan sebagai kunci untuk melakukan perhitungan HMAC-SHA256.
{kedaluwarsa} String UTF8 untuk jumlah detik sejak masa 00:00:00 UTC pada 1 Januari 1970.
{URL-encoded-resourceURI} Pengodean URL huruf kecil pada URI sumber daya huruf kecil. Awalan URI (berdasarkan segmen) titik akhir yang dapat diakses dengan token ini, dimulai dengan nama host IoT Hub Device Provisioning Service (tanpa protokol). Contohnya, mydps.azure-devices-provisioning.net.
{policyName} Nama kebijakan akses bersama yang menjadi rujukan token ini.

Catatan

Awalan URI dihitung berdasarkan segmen dan bukan berdasarkan karakter. Misalnya /a/b adalah awalan untuk /a/b/c tetapi tidak untuk /a/bc.

Cuplikan Node.js berikut menunjukkan fungsi yang disebut generateSasToken yang menghitung token dari input resourceUri, signingKey, policyName, expiresInMins. Bagian berikutnya menjelaskan cara menginisialisasi input yang berbeda untuk kasus penggunaan token yang berbeda.

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

Sebagai perbandingan, kode Python yang setara untuk menghasilkan token keamanan adalah:

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)

Catatan

Karena masa berlaku token divalidasi pada mesin IoT Device Provisioning Service, drift pada jam mesin yang menghasilkan token harus minimal.

Gunakan token keamanan dari komponen layanan

Komponen layanan hanya dapat menghasilkan token keamanan menggunakan kebijakan akses bersama yang memberikan izin yang sesuai seperti yang dijelaskan sebelumnya.

Berikut adalah fungsi layanan yang diekspos pada titik akhir:

Titik akhir Fungsionalitas
{your-service}.azure-devices-provisioning.net/enrollments Menyediakan operasi pendaftaran perangkat dengan Layanan Provisi Perangkat.
{your-service}.azure-devices-provisioning.net/enrollmentGroups Menyediakan operasi untuk mengelola grup pendaftaran perangkat.
{your-service}.azure-devices-provisioning.net/registrations/{id} Menyediakan operasi untuk mengambil dan mengelola status pendaftaran perangkat.

Sebagai contoh, layanan yang dihasilkan menggunakan kebijakan akses bersama yang telah dibuat sebelumnya yang disebut enrollmentread akan membuat token dengan parameter berikut:

  • URI sumber daya: {mydps}.azure-devices-provisioning.net,
  • kunci penandatanganan: salah satu kunci kebijakan enrollmentread,
  • nama Kebijakan: enrollmentread,
  • setiap waktu kedaluwarsa.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);

Hasilnya, yang akan memberikan akses untuk membaca semua catatan pendaftaran, adalah:

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

SDK dan sampel

Topik referensi:

Topik referensi berikut memberi Anda informasi selengkapnya tentang mengontrol akses ke Layanan Provisi Perangkat IoT Anda.

Izin Layanan Provisi Perangkat

Tabel berikut mencantumkan izin yang bisa Anda gunakan untuk mengontrol akses ke Layanan Provisi Perangkat IoT Anda.

Izin Catatan
ServiceConfig Memberikan akses untuk mengubah konfigurasi layanan.
Izin ini digunakan oleh layanan cloud backend.
EnrollmentRead Memberikan akses baca ke pendaftaran perangkat dan grup pendaftaran.
Izin ini digunakan oleh layanan cloud backend.
EnrollmentWrite Memberikan akses tulis ke pendaftaran perangkat dan grup pendaftaran.
Izin ini digunakan oleh layanan cloud backend.
RegistrationStatusRead Memberikan akses baca ke status pendaftaran perangkat.
Izin ini digunakan oleh layanan cloud backend.
RegistrationStatusWrite Memberikan akses hapus ke status pendaftaran perangkat.
Izin ini digunakan oleh layanan cloud backend.