使用共用存取簽章控制對 IoT 中樞的存取

IoT 中樞 使用共用存取簽章 (SAS) 令牌來驗證裝置和服務,以避免在網路上傳送密鑰。 您可以使用 SAS 令牌,將裝置和服務的時間限定存取權授與 IoT 中樞 中的特定功能。 若要取得連線到 IoT 中樞的授權,裝置和服務必須傳送使用共用存取或對稱密鑰簽署的 SAS 令牌。 對稱金鑰會以裝置身分識別儲存在身分識別登錄中。

介紹:

  • 您可以授與用戶端以存取IoT中樞的不同許可權。
  • IoT 中樞 用來驗證許可權的令牌。
  • 如何設定認證範圍,以限制對特定資源的存取。
  • 使用現有裝置身分識別登錄或驗證配置的自定義裝置驗證機制。

注意

本文所述的一些功能,例如雲端到裝置傳訊、裝置對應項和裝置管理,僅適用於標準層 IoT 中樞。 如需基本和標準/免費 IoT 中樞 層的詳細資訊,請參閱為您的解決方案選擇正確的 IoT 中樞 層。

IoT 中樞 會使用許可權來授與每個IoT中樞端點的存取權。 許可權會根據功能限制對IoT中樞的存取。 您必須具有適當的許可權,才能存取任何 IoT 中樞 端點。 例如,裝置必須包含包含安全性認證的令牌,以及傳送給 IoT 中樞 的每個訊息。 不過,簽署密鑰就像裝置對稱密鑰一樣,永遠不會透過網路傳送。

驗證與授權

驗證 是證明您是誰的程式。 驗證會驗證使用者或裝置的身分識別,以 IoT 中樞。 它有時會縮短為 AuthN授權是確認 IoT 中樞 上已驗證使用者或裝置許可權的程式。 它會指定您可以存取哪些資源和命令,以及您可以使用這些資源和命令執行的動作。 授權有時會縮短為 AuthZ

本文說明使用 共用存取簽章的驗證和授權,可讓您使用存取密鑰和已簽署的安全性令牌將許可權分組並授與應用程式。 您也可以使用對稱金鑰或共用存取金鑰,以 IoT 中樞 驗證裝置。 SAS 令牌會藉由將對稱密鑰與每個呼叫產生關聯,為裝置進行的每個呼叫提供驗證,以 IoT 中樞。

存取控制及權限

使用共用存取原則進行 IoT 中樞層級存取,並使用個別裝置認證將存取範圍僅限於該裝置。

IoT 中樞層級共用存取原則

共用存取原則可以授與權限的任意組合。 您可以使用 IoT 中樞 資源 REST API 或使用 Azure CLI az iot hub policy 命令,以程式設計方式在 Azure 入口網站 中定義原則。 新建立的 IoT 中樞具有下列預設原則:

共用存取原則 權限
iothubowner 所有許可權
服務 服務 連線許可權
device 裝置 連線許可權
登錄讀取 RegistryRead 許可權
登錄讀取寫入 RegistryReadRegistryWrite 許可權

您可以使用下列權限來控制 IoT 中樞的存取權:

  • 後端雲端服務會使用服務 連線許可權,並授與下列存取權:

    • 存取雲端服務對向通訊和監視端點。
    • 接收裝置到雲端訊息、傳送雲端到裝置訊息,並擷取對應的傳遞通知。
    • 擷取檔案上傳的傳遞通知。
    • 存取對應項以更新標記和所需的屬性、擷取報告的屬性,以及執行查詢。
  • 裝置會使用 Device 連線 許可權,並授與下列存取權:

    • 存取面向裝置的端點。
    • 傳送裝置到雲端訊息,並接收雲端到裝置訊息。
    • 執行檔案上傳。
    • 接收裝置對應項所需的屬性通知,並更新裝置對應項報告屬性。
  • 後端 雲端服務會使用 RegistryRead 許可權,並授與下列存取權:

  • 後端 雲端服務會使用 RegistryReadWrite 許可權,並授與下列存取權:

    • 識別登錄的讀取和寫入存取權。 如需詳細資訊,請參閱 身分識別登錄

個別裝置安全性認證

每個 IoT 中樞都有一個身分識別登錄,可儲存允許連線的裝置和模組相關信息。 在裝置或模組可以連線之前,IoT 中樞的身分識別登錄中必須有該裝置或模組的專案。 裝置或模組會根據儲存在身分識別登錄中的認證,向IoT中樞進行驗證。

當您註冊裝置以使用SAS令牌驗證時,該裝置會取得兩個 對稱密鑰。 對稱金鑰會授與裝置 連線 相關聯裝置身分識別的許可權。

從服務使用SAS令牌

服務可以使用定義適當許可權的共用存取原則來產生 SAS 令牌,如訪問控制和許可權一節先前所述。

例如,使用名為 registryRead 之預先建立共用存取原則的服務會建立具有下列參數的令牌:

  • 資源 URI:{IoT hub name}.azure-devices.net,
  • 簽署金鑰:registryRead 原則的金鑰之一,
  • 原則名稱:registryRead
  • 任何到期時間。

例如,下列程式代碼會在 Node.js中建立 SAS 令牌:

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

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

結果會授與讀取身分識別登錄中所有裝置身分識別的存取權,其為:

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

如需更多範例,請參閱 產生 SAS 令牌

針對服務,SAS 令牌只會授與 IoT 中樞 層級的許可權。 也就是說,以服務原則為基礎的令牌進行驗證的服務將能夠執行服務授與的所有作業 連線許可權。 這些作業包括接收裝置到雲端訊息、傳送雲端到裝置訊息等等。 例如,如果您想要授與更細微的服務存取權,限制服務只傳送雲端到裝置訊息,您可以使用 Microsoft Entra ID。 若要深入瞭解,請參閱 使用 Microsoft Entra ID 進行驗證。

從裝置使用SAS令牌

有兩種方式可以取得具有 SAS 令牌 IoT 中樞 的 Device 連線 許可權:使用身分識別登錄中的對稱裝置密鑰,或使用共用存取密鑰

從裝置存取的所有功能都是透過設計在具有 前置 /devices/{deviceId}詞 的端點上公開。

面向裝置的端點是 (無論通訊協定為何):

端點 功能
{iot hub name}/devices/{deviceId}/messages/events 傳送裝置到雲端的訊息。
{iot hub name}/devices/{deviceId}/messages/devicebound 接收雲端到裝置的訊息。

在身分識別登錄中使用對稱密鑰

使用裝置身分識別的對稱密鑰來產生令牌時,會省略令牌的 policyName (skn) 元素。

例如,建立來存取所有裝置功能的令牌應該具有下列參數:

  • 資源 URI:{IoT hub name}.azure-devices.net/devices/{device id},
  • 簽署金鑰:身分識別的任何對稱金鑰 {device id}
  • 沒有原則名稱,
  • 任何到期時間。

例如,下列程式代碼會在 Node.js中建立 SAS 令牌:

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

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

結果會授與 device1 之所有功能的存取權,其為:

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

如需更多範例,請參閱 產生 SAS 令牌

使用共用存取原則代表裝置存取

當您從共用存取原則建立令牌時,請將 skn 字段設定為原則的名稱。 此原則必須授與 Device 連線 許可權。

使用共用存取原則來存取裝置功能的兩個主要案例如下:

由於共用存取原則可能會將存取權授與連線為任何裝置,因此在建立 SAS 令牌時,請務必使用正確的資源 URI。 對於令牌服務而言,此設定特別重要,這些服務必須使用資源 URI 將令牌範圍設定為特定裝置。 這一點與通訊協定閘道較不相關,因為它們已經調解所有裝置的流量。

例如,使用預先建立的共用存取原則稱為 裝置 的令牌服務會建立具有下列參數的令牌:

  • 資源 URI:{IoT hub name}.azure-devices.net/devices/{device id},
  • 簽署金鑰:device 原則的金鑰之一,
  • 原則名稱:device
  • 任何到期時間。

例如,下列程式代碼會在 Node.js中建立 SAS 令牌:

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

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

結果會授與 device1 之所有功能的存取權,其為:

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

通訊協定閘道可以將資源 URI myhub.azure-devices.net/devices設定為 ,為所有裝置使用相同的令牌。

如需更多範例,請參閱 產生 SAS 令牌

建立令牌服務以整合現有的裝置

您可以使用 IoT 中樞 身分識別登錄,使用令牌來設定個別裝置或每個模組的安全性認證和訪問控制。 如果 IoT 解決方案已經有自定義身分識別登錄和/或驗證配置,請考慮建立令牌服務來整合此基礎結構與 IoT 中樞。 如此一來,您就可以在解決方案中使用其他 IoT 功能。

令牌服務是自定義雲端服務。 它會使用 IoT 中樞 共用存取原則搭配Device 連線許可權來建立裝置範圍模組範圍的令牌。 這些令牌可讓裝置或模組連線到IoT中樞。

顯示令牌服務模式步驟的圖表。

以下是令牌服務模式的主要步驟:

  1. 使用IoT中樞的Device 連線許可權,建立IoT 中樞共用存取原則。 您可以在 Azure 入口網站 或以程序設計方式建立此原則。 令牌服務會使用此原則來簽署它所建立的令牌。

  2. 當裝置或模組需要存取IoT中樞時,它會向令牌服務要求已簽署的令牌。 裝置可以使用您的自定義身分識別登錄/驗證配置進行驗證,以判斷令牌服務用來建立令牌的裝置/模組身分識別。

  3. 令牌服務會傳回令牌。 令牌的建立方式是使用 /devices/{deviceId}/devices/{deviceId}/modules/{moduleId} 作為 resourceURI,做 deviceId 為要驗證的裝置,以及 moduleId 作為正在驗證的模組。 令牌服務會使用共用存取原則來建構令牌。

  4. 裝置/模組會直接使用令牌與IoT中樞。

注意

您可以使用 .NET 類別 SharedAccessSignatureBuilder 或 Java 類別 IotHubServiceSasToken 在令牌服務中建立令牌。

令牌服務可以視需要設定令牌到期。 令牌到期時,IoT 中樞會分割裝置/模組連線。 然後,裝置/模組必須向令牌服務要求新的令牌。 短暫的到期時間會增加裝置/模組和令牌服務的負載。

若要讓裝置/模組連線到您的中樞,您仍必須將它新增至 IoT 中樞 身分識別登錄,即使它使用的是令牌,而不是要連線的密鑰。 因此,您可以在身分識別登錄中啟用或停用裝置/模組身分識別,以繼續使用個別裝置/每個模組訪問控制。 這種方法可降低使用令牌長時間到期時間的風險。

與自定義閘道的比較

令牌服務模式是使用 IoT 中樞 實作自定義身分識別登錄/驗證配置的建議方式。 建議使用此模式,因為 IoT 中樞 會繼續處理大部分的解決方案流量。 不過,如果自定義驗證配置與通訊協定交織在一起,您可能需要 自定義網關 來處理所有流量。 這類案例的範例是使用 傳輸層安全性 (TLS) 和預先共用密鑰 (PSKs) 。 如需詳細資訊,請參閱 IoT Edge裝置如何作為閘道使用。

產生 SAS 權杖

Azure IoT SDK 會自動產生令牌,但某些案例會要求您直接產生和使用 SAS 令牌,包括:

  • 直接使用 MQTT、AMQP 或 HTTPS 介面。

  • 令牌服務模式的實作,如建立令牌服務一節中所述

使用共用存取金鑰簽署的權杖授與對與共用存取原則權限相關聯的所有功能之存取。 使用裝置身分識別對稱密鑰簽署的令牌只會授與相關聯裝置身分識別的 Device 連線 許可權。

本節提供以不同程式代碼語言產生 SAS 令牌的範例。 您也可以使用 CLI 擴充功能命令 az iot hub generate-sas-token 或 Visual Studio Code 的 Azure IoT 中樞 擴充功能來產生 SAS 令牌。

SAS 令牌結構

SAS 令牌的格式如下:

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

以下是預期值:

Description
{signature} 格式為 HMAC-SHA256 簽章字串: {URL-encoded-resourceURI} + "\n" + expiry重要事項:金鑰會從base64譯碼,並做為執行 HMAC-SHA256 計算的索引鍵。
{resourceURI} 可以使用此令牌存取之端點的 URI 前置詞(依區段),從 IoT 中樞的主機名開始(沒有通訊協定)。 授與後端服務的SAS令牌範圍設定為IoT中樞層級;例如, myHub.azure-devices.net。 授與裝置的SAS令牌必須限定為個別裝置;例如, myHub.azure-devices.net/devices/device1
{expiry} 從新紀元時間 (Epoch) 1970 年 1 月 1日 00:00:00 UTC 時間至今秒數的 UTF8 字串。
{URL-encoded-resourceURI} 小寫資源 URI 的小寫 URL 編碼
{policyName} 此權杖所參考的共用存取原則名稱。 如果令牌參考裝置登錄認證,則為缺席。

URI 首碼是依區段計算的,而不是依字元計算的。 例如, /a/b 是的 /a/b/c 前置詞,但不是的 /a/bc

下列程式代碼會使用資源 URI、簽署金鑰、原則名稱和到期期間來產生 SAS 令牌。 接下來的區段詳細介紹了如何為不同的權杖使用案例初始化不同的輸入。

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

通訊協議細節

每個支援的通訊協定,例如 MQTT、AMQP 和 HTTPS,會以不同方式傳輸令牌。

使用 MQTT 時,CONNECT 封包的 deviceId 會作為 ClientId、 {iothubhostname}/{deviceId} 在 [使用者名稱] 字段中,以及 [密碼] 字段中的 SAS 令牌。 {iothubhostname} 應該是IoT中樞的完整 CName(例如,myhub.azure-devices.net)。

使用AMQP時,IoT 中樞支援SASL PLAINAMQP宣告型安全性

如果您使用AMQP宣告型安全性,標準會指定如何傳輸這些令牌。

針對 SASL PLAIN, 使用者名稱 可以是:

  • {policyName}@sas.root.{iothubName} 如果使用IoT中樞層級令牌,
  • {deviceId}@sas.{iothubname} 如果使用裝置範圍的令牌。

在這兩種情況下,密碼欄位都包含令牌,如SAS令牌結構中所述

HTTPS 會實作驗證,方法是在授權要求標頭中包含有效的令牌。

例如,Username (DeviceId 區分大小寫): iothubname.azure-devices.net/DeviceId

密碼 (您可以使用 CLI 擴充功能命令 az iot hub generate-sas-token 或 Visual Studio Code 的 Azure IoT 中樞 延伸模組來產生 SAS 令牌):

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

注意

Azure IoT SDK 會在 連線到服務時自動產生令牌。 在某些情況下,Azure IoT SDK 不支援所有通訊協定或所有驗證方法。

SASL PLAIN 的特殊考慮

搭配AMQP使用SASL PLAIN時,連線到IoT中樞的用戶端可以使用每個TP連線的單一令牌。 令牌到期時,TCP 聯機會中斷與服務的連接,並觸發重新連線。 此行為雖然對後端應用程式沒有問題,但因下列原因而對裝置應用程式造成損害:

  • 閘道通常會代表許多裝置進行連線。 使用SASL PLAIN時,他們必須為每個連線到IoT中樞的裝置建立不同的TCP連線。 此案例可大幅增加電源和網路資源的耗用量,並增加每個裝置連線的延遲。

  • 資源限制的裝置會受到資源使用量增加而造成負面影響,以在每次令牌到期后重新連線。

下一步

既然您已瞭解如何控制存取 IoT 中樞,您可能對下列 IoT 中樞 開發人員指南主題感興趣: