分享方式:


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

Azure IoT 中樞使用共用存取簽章 (SAS) 權杖來驗證裝置和服務,以避免透過線路傳送金鑰。 您可以使用 SAS 權杖,以將 IoT 中樞內特定功能的限時存取權限授與裝置和服務。 若要取得連線至 IoT 中樞的授權,裝置和服務必須傳送以共用存取或對稱金鑰所簽署的 SAS 權杖。 對稱金鑰會與裝置身分識別一起儲存至身分識別登錄。

本文將介紹:

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

注意

本文中提及的某些功能 (例如雲端對裝置傳訊、裝置對應項和裝置管理) 僅適用於 IoT 中樞的標準層。 如需有關基本和標準/免費 Azure IoT 中樞階層的詳細資訊,請參閱為您的解決方案選擇適合的 Azure IoT 中樞階層

IoT 中樞使用「權限」,授與每個 IoT 中樞端點的存取權。 根據功能限制存取 IoT 中樞的權限。 您必須具有適當權限才能存取任何 IoT 中樞端點。 例如,裝置必須包含權杖,其中包含安全性認證,以及傳送到 IoT 中樞的每個訊息。 不過,永遠不會透過網路傳送裝置對稱金鑰這類簽署金鑰。

驗證和授權

驗證是證明您確實是您本人的程序。 驗證會向 Azure IoT 中樞確認使用者或裝置的身分識別。 有時會簡稱為 AuthN (驗證)。 授權是在 Azure IoT 中樞上確認已驗證使用者或裝置權限的流程。 授權指定您可以存取哪些資源和命令,以及您可以使用這些資源和命令執行的動作。 授權 (Authorization) 有時會被簡稱為 AuthZ

本文說明驗證和授權使用共用存取簽章,讓您將權限分組,並使用存取金鑰和已簽署的安全性權杖將權限授與應用程式。 您也可以使用對稱金鑰或共用存取金鑰,以利用 Azure IoT 中樞來驗證裝置。 SAS 權杖透過建立每個呼叫與對稱金鑰的關聯,為 Azure IoT 中樞裝置發出的每個呼叫提供驗證。

存取控制及權限

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

IoT 中樞層級共用存取原則

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

共用存取原則 權限
iothubowner 所有權限
服務 ServiceConnect 權限
device DeviceConnect 權限
登錄讀取 RegistryRead 權限
登錄讀取寫入 RegistryReadRegistryWrite 權限

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

  • ServiceConnect 權限由後端雲端服務使用,並授與下列存取權:

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

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

    • 身分識別登錄的讀取權限。 如需詳細資訊,請參閱身分識別登錄
  • RegistryReadWrite 權限由後端雲端服務使用,並授與下列存取權:

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

每個裝置的安全性認證

每個 IoT 中樞都有身分識別登錄,可儲存允許連線至 IoT 中樞的裝置和模組相關資訊。 IoT 中樞的身分識別登錄中必須先有裝置或模組項目,該裝置或模組才可以連線。 裝置或模組是根據儲存在身分識別登錄中的認證,使用 IoT 中樞驗證。

當您註冊裝置以使用 SAS 權杖驗證時,該裝置會取得兩個 對稱金鑰。 對稱金鑰授與相關聯裝置身分識別 DeviceConnect 權限。

使用來自服務的 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 權杖只在 Azure IoT 中樞維度層級授與權限。 也就是說,根據「服務」原則使用權杖進行驗證的服務將能夠執行 ServiceConnect 權限所授與的所有作業。 這些作業包括接收裝置到雲端訊息、傳送雲端到裝置訊息等等。 如果您想要授與更細微的服務存取權 (例如,將服務限制為只傳送雲端到裝置的訊息),則可以使用 Microsoft Entra ID。 若要深入了解,請參閱使用 Microsoft Entra ID 進行驗證

使用來自裝置的 SAS 權杖

利用 SAS 權杖取得 IoT 中樞之 DeviceConnect 權限的方法有兩種:使用身分識別登錄的對稱裝置金鑰,或使用共用存取金鑰

所有可從裝置存取的功能,在設計上會以前置詞/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 欄位設為原則的名稱。 此原則必須授與 DeviceConnect 權限。

使用共用存取原則來存取裝置功能的兩個主要案例包括︰

因為共用存取原則可能可以授與以任何裝置身分連線的存取權限,所以在建立 SAS 權杖時,請務必使用正確的資源 URI。 此設定對權杖服務來說特別重要,因為它們必須使用資源 URI 來設定權杖的範圍,以便納入特定裝置。 這點與通訊協定閘道的關聯性比較薄弱,因為它們已經在為所有裝置調節流量。

舉例來說,權杖服務如果使用名為 device 的預先建立共用存取原則,將會使用下列參數來建立權杖:

  • 資源 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 功能。

權杖服務是自訂雲端服務。 這會使用具有 DeviceConnect 權限的 IoT 中樞「共用存取原則」,來建立「裝置範圍」或「模組範圍」權杖。 這些權杖可讓裝置或模組連線到 IoT 中樞。

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

以下是權杖服務模式的主要步驟:

  1. 為您的 IoT 中樞建立具有 DeviceConnect 權限的 IoT 中樞共用存取原則。 您可以在 Azure 入口網站中或以程式設計方式建立此原則。 權杖服務會使用此原則簽署它所建立的權杖。

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

  3. 權杖服務會傳回權杖。 權杖藉由使用 /devices/{deviceId}/devices/{deviceId}/modules/{moduleId} 作為 resourceURI 來建立,以 deviceId 作為要進行驗證的裝置,以及以 moduleId 作為要進行驗證的模組。 權杖服務會使用共用存取原則來建構權杖。

  4. 裝置/模組直接透過 IoT 中樞使用權杖。

注意

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

權杖服務可以視需要設定權杖到期日。 權杖到期時,IoT 中樞會切斷裝置/模組連線。 然後,裝置/模組必須向權杖服務要求新權杖。 使用過短的到期時間會增加裝置/模組與權杖服務上的負載。

為了讓裝置/模組連線至中樞,即使其使用權杖而不是金鑰來連線,您仍必須將它新增至 Azure IoT 中樞身分識別登錄。 因此,您可以藉由在身分識別登錄中啟用或停用裝置/模組身分識別,繼續使用每個裝置/每個模組的存取控制。 此方法可減輕使用較長到期時間權杖的風險。

和自訂閘道器的比較

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

產生 SAS 權杖

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

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

  • 權杖服務模式的實作,如建立權杖服務章節中所述。

使用共用存取金鑰簽署的權杖授與對與共用存取原則權限相關聯的所有功能之存取。 以裝置身分識別對稱金鑰簽署的權杖只會授與相關裝置身分識別的 DeviceConnect 權限。

本節提供以不同程式碼語言產生 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 封包會有作為 ClientId 的 deviceId、Username 欄位中會有 {iothubhostname}/{deviceId},而 Password 欄位中則會有 SAS 權杖。 {iothubhostname} 應該是 IoT 中樞的完整 CName (例如 myhub.azure-devices.net)。

使用 AMQP \(英文\) 時,IoT 中樞支援 SASL PLAIN \(英文\) 和 AMQP 宣告式安全性 \(英文\)。

如果使用以 AMQP 宣告為基礎的安全性,標準會指定如何傳輸這些權杖。

在 SASL PLAIN 中, username 可以是:

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

在這兩種案例,密碼欄位包含權杖,如 SAS 權杖結構中所述。

HTTPS 實作驗證的方式是在 Authorization 要求標頭中包含有效的權杖。

例如,使用者名稱 (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 中樞的用戶端可為每個 TCP 連線使用單一權杖。 當權杖過期時,TCP 連線會中斷服務連線,並觸發重新連線。 此行為雖不會對後端應用程式造成問題,但是對裝置應用程式不利,原因如下︰

  • 閘道器通常會代表許多裝置連線。 使用 SASL PLAIN 時,它們必須針對連接至 IoT 中樞的每個裝置不同的建立 TCP 連線。 這個案例會大幅提高電力與網路資源的耗用量,並增加每個裝置連線的延遲。

  • 在每個權杖到期後,增加使用要重新連接的資源通常會對資源受限的裝置有不良影響。

下一步

現在您已了解如何控制存取 IoT 中樞,接下來您可能對下列 IoT 中樞開發人員指南主題感興趣︰