IoT 中心对托管标识的支持

托管标识以安全的方式在 Microsoft Entra ID 中为 Azure 服务提供了一个自动托管标识。 这样,开发人员在管理凭据时便无需提供标识。 有两种类型的托管标识:系统分配和用户分配的托管标识。 IoT 中心支持这两者。

在 IoT 中心,托管标识可用于从 IoT 中心到其他 Azure 服务的出口连接,以实现消息路由文件上传批量设备导入/导出等功能。 在本文中,你将了解如何在 IoT 中心使用系统分配的和用户分配的托管标识来实现不同的功能。

先决条件

系统分配的托管标识

在 Azure 门户中启用或禁用系统分配的托管标识

  1. 登录 Azure 门户,导航到 IoT 中心。

  2. 在导航菜单的“安全设置”部分中选择“标识”。

  3. 选择“系统分配”选项卡。

  4. 将系统分配的托管标识“状态”设为“”或“”,然后选择“保存”。

    注意

    在使用系统分配的托管标识时,无法将其关闭。 在禁用该功能之前,请确保没有自定义终结点在使用系统分配的托管标识身份验证。

    Screenshot showing where to turn on system-assigned managed identity for an IoT hub.

在创建中心时使用 ARM 模板启用系统分配的托管标识

若要在预配资源时在 IoT 中心启用系统分配的托管标识,请使用下面的 Azure 资源管理器 (ARM) 模板。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": 
    {
      "iotHubName": {
        "type": "string",
        "metadata": {
          "description": "Name of iothub resource"
        }
      },
      "skuName": {
        "type": "string",
        "defaultValue": "S1",
        "metadata": {
          "description": "SKU name of iothub resource, by default is Standard S1"
        }
      },
      "skuTier": {
        "type": "string",
        "defaultValue": "Standard",
        "metadata": {
          "description": "SKU tier of iothub resource, by default is Standard"
        }
      },
      "location": {
        "type": "string",
        "defaultValue": "[resourceGroup().location]",
        "metadata": {
          "description": "Location of iothub resource. Please provide any of supported-regions of iothub"
        }
      }
    },
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2020-10-01",
      "name": "createIotHub",
      "properties": {
        "mode": "Incremental",
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "resources": [
            {
              "type": "Microsoft.Devices/IotHubs",
              "apiVersion": "2021-03-31",
              "name": "[parameters('iotHubName')]",
              "location": "[parameters('location')]",
              "identity": {
                "type": "SystemAssigned"
              },
              "sku": {
              "name": "[parameters('skuName')]",
              "tier": "[parameters('skuTier')]",
              "capacity": 1
              }
            }
          ] 
        }
      }
    }
  ]
}

替换资源 namelocationSKU.nameSKU.tier 的值后,可以在 Azure CLI 中使用以下命令在现有资源组中部署资源:

az deployment group create --name <deployment-name> --resource-group <resource-group-name> --template-file <template-file.json> --parameters iotHubName=<valid-iothub-name> skuName=<sku-name> skuTier=<sku-tier> location=<any-of-supported-regions>

创建资源后,可使用 Azure CLI 检索分配给中心的系统分配的托管标识:

az resource show --resource-type Microsoft.Devices/IotHubs --name <iot-hub-resource-name> --resource-group <resource-group-name>

用户分配的托管标识

在本部分中,你将了解如何使用 Azure 门户从 IoT 中心添加和删除用户分配的托管标识。

  1. 首先,需要创建一个用户分配的托管标识作为独立资源。 为此,可按照创建用户分配的托管标识中的说明操作。

  2. 转到 IoT 中心,导航到 IoT 中心门户中的“标识”。

  3. 在“用户分配”选项卡下,单击“关联用户分配的托管标识” 。 选择要添加到中心的用户分配的托管标识,然后单击“选择”。

  4. 可从 IoT 中心删除用户分配的标识。 选择要删除的用户分配的标识,然后单击“删除”按钮。 请注意,仅可从 IoT 中心删除用户分配的标识,并且此删除操作不会将用户分配的标识作为资源删除。 要将用户分配的标识作为资源删除,请按照删除用户分配的托管标识中的说明操作。

    Screenshot showing how to add user-assigned managed identity for an I O T hub.

在创建中心时使用 ARM 模板启用用户分配的托管标识

可使用以下示例模板,通过用户分配的托管标识来创建中心。 此模板会创建一个用户分配的标识,其名称为 [iothub-name-provided]-identity 并被分配给已创建的 IoT 中心。 可更改模板,根据需要添加多个用户分配的标识。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "iotHubName": {
      "type": "string",
      "metadata": {
        "description": "Name of iothub resource"
      }
    },
  "skuName": {
    "type": "string",
    "defaultValue": "S1",
    "metadata": {
      "description": "SKU name of iothub resource, by default is Standard S1"
    }
  },
  "skuTier": {
    "type": "string",
    "defaultValue": "Standard",
    "metadata": {
      "description": "SKU tier of iothub resource, by default is Standard"
    }
  },
  "location": {
    "type": "string",
    "defaultValue": "[resourceGroup().location]",
    "metadata": {
      "description": "Location of iothub resource. Please provide any of supported-regions of iothub"
    }
  }
},
  "variables": {
    "identityName": "[concat(parameters('iotHubName'), '-identity')]"
  },
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2020-10-01",
      "name": "createIotHub",
      "properties": {
        "mode": "Incremental",
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "resources": [
            {
              "type": "Microsoft.ManagedIdentity/userAssignedIdentities",
              "name": "[variables('identityName')]",
              "apiVersion": "2018-11-30",
              "location": "[resourceGroup().location]"
            },
            {
              "type": "Microsoft.Devices/IotHubs",
              "apiVersion": "2021-03-31",
              "name": "[parameters('iotHubName')]",
              "location": "[parameters('location')]",
              "identity": {
                "type": "UserAssigned",
                "userAssignedIdentities": {
                  "[resourceID('Microsoft.ManagedIdentity/userAssignedIdentities/',variables('identityName'))]": {}
                }
              },
              "sku": {
                "name": "[parameters('skuName')]",
                "tier": "[parameters('skuTier')]",
                "capacity": 1
              },
              "dependsOn": [
                "[resourceID('Microsoft.ManagedIdentity/userAssignedIdentities/',variables('identityName'))]"
              ]
            }
          ]
        }
      }
    }
  ]
}
az deployment group create --name <deployment-name> --resource-group <resource-group-name> --template-file <template-file.json> --parameters iotHubName=<valid-iothub-name> skuName=<sku-name> skuTier=<sku-tier> location=<any-of-supported-regions>

创建资源后,可以使用 Azure CLI 检索分配给中心的用户分配的托管标识:

az resource show --resource-type Microsoft.Devices/IotHubs --name <iot-hub-resource-name> --resource-group <resource-group-name>

从 IoT 中心到其他 Azure 资源的出口连接

托管标识可用于从 IoT 中心到其他 Azure 服务的出口连接,以实现消息路由文件上传批量设备导入/导出。 可为每个指向客户拥有的终结点的 IoT 中心出站连接选择要使用的托管标识。

注意

只有系统分配的托管标识才允许 IoT 中心访问专用资源。 如果要使用用户分配的托管标识,需要启用这些专用资源的公共访问权限才会允许连接。

使用托管标识配置消息路由

本部分将使用指向事件中心自定义终结点的消息路由作为示例。 该示例也适用于其他路由自定义终结点。

  1. 在 Azure 门户中转到事件中心,以便向托管标识分配正确的访问权限。

  2. 选择“访问控制 (IAM)”。

  3. 选择“添加”>“添加角色分配”。

    Screenshot showing Access control (IAM) page with Add role assignment menu open.

  4. 在“角色”选项卡上,选择“Azure 事件中心数据发送方”。

    注意

    对于“存储帐户”,请选择“存储 Blob 数据参与者”(非参与者或存储帐户参与者)作为角色。 对于服务总线,选择“Azure 服务总线数据发送者”。

    Screenshot showing Add role assignment page with Role tab selected.

  5. 在“成员”选项卡上,选择“托管标识”,然后选择“选择成员”。

  6. 对于用户分配的托管标识,请选择你的订阅,选择“用户分配的托管标识”,然后选择你的用户分配的托管标识。

  7. 对于系统分配的托管标识,请选择你的订阅,选择“所有系统分配的托管标识”,然后选择你的 IoT 中心的资源名称。

  8. 在“查看 + 分配”选项卡上,选择“查看 + 分配”,以分配角色 。

    若要详细了解角色分配,请参阅使用 Azure 门户分配 Azure 角色

  9. 如果需要通过 VNet 限制与自定义终结点的连接,则需要启用 Microsoft 受信任的第一方例外,使 IoT 中心能够访问特定终结点。 例如,如果要添加事件中心自定义终结点,请导航到事件中心的“防火墙和虚拟网络”选项卡,并启用“允许从所选网络访问”选项 。 在“异常”列表中,勾选“允许受信任的 Microsoft 服务访问事件中心”复选框 。 单击“保存”按钮 。 这也适用于存储帐户和服务总线。 详细了解 IoT 中心的虚拟网络支持

    注意

    在 IoT 中心内将事件中心添加为自定义终结点之前,需要完成上述步骤以为托管标识分配正确的访问权限。 请等待角色分配传播完成。

  10. 接下来,请前往 IoT 中心。 在中心导航到“消息路由”,然后选择“添加”。

  11. 在“终结点”选项卡上,通过提供以下信息为事件中心创建终结点:

    参数
    终结点类型 选择“事件中心”。
    端点名称 为新终结点提供独一无二的名称,或选择“选择现有”以选择现有的事件中心终结点。
    事件中心命名空间 使用下拉菜单选择订阅中的现有事件中心命名空间。
    事件中心实例 使用下拉菜单选择命名空间中的现有事件中心。
    身份验证类型 选择“用户分配”,然后使用下拉菜单选择在事件中心创建的“用户分配标识”。

    Screenshot that shows event hub endpoint with user assigned authentication.

  12. 选择“创建 + 下一步”。 可以通过向导继续创建指向此终结点的路由,也可以关闭向导。

可以更改现有自定义终结点的身份验证类型。 使用以下步骤修改终结点:

  1. 在 IoT 中心的左导航窗格中选择“消息路由”,然后选择“自定义终结点”。

  2. 选中要修改的自定义终结点的复选框,然后选择“更改身份验证类型”。

  3. 选择此终结点的新身份验证类型,然后选择“保存”。

使用托管标识配置文件上传

IoT 中心的文件上传功能允许设备将文件上传到客户拥有的存储帐户。 若要正常上传文件,IoT 中心需要连接到存储帐户。 类似于消息路由,你可以为指向 Azure 存储帐户的 IoT 中心出站连接选择首选身份验证类型和托管标识。

  1. 在 Azure 门户中导航到存储帐户。

  2. 选择“访问控制 (IAM)”。

  3. 选择“添加”>“添加角色分配”。

    Screenshot showing Access control (IAM) page with Add role assignment menu open.

  4. 在“角色”选项卡上,选择“存储 Blob 数据参与者”。 (请勿选择“参与者”或“存储帐户参与者”。)

  5. 在“成员”选项卡上,选择“托管标识”,然后选择“选择成员”。

  6. 对于用户分配的托管标识,请选择你的订阅,选择“用户分配的托管标识”,然后选择你的用户分配的托管标识。

  7. 对于系统分配的托管标识,请选择你的订阅,选择“所有系统分配的托管标识”,然后选择你的 IoT 中心的资源名称。

  8. 在“查看 + 分配”选项卡上,选择“查看 + 分配”,以分配角色 。

    若要详细了解角色分配,请参阅使用 Azure 门户分配 Azure 角色

    如果需要通过 VNet 限制与存储帐户的连接,则需要启用 Azure 受信任的第一方例外,使 IoT 中心能够访问存储帐户。 在存储帐户资源页上,导航到存储帐户中的“防火墙和虚拟网络”选项卡,并启用“允许从所选网络进行访问”选项 。 在“例外”列表中,选中“允许受信任的 Azure 服务访问此存储帐户”复选框 。 单击“保存”按钮 。 详细了解 IoT 中心的虚拟网络支持

    注意

    在使用托管标识在 IoT 中心保存存储帐户以供文件上传之前,需要完成上述步骤来为托管标识分配正确的访问权限。 请等待角色分配传播完成。

  9. 在 IoT 中心的“资源”页上,导航到“文件上传”选项卡。

  10. 在显示的页面上,选择要在 blob 存储中使用的容器,根据需要配置“文件通知设置、SAS TTL、默认 TT 和最大传送计数”。 选择首选的身份验证类型,然后单击“保存”。 如果在此步骤中遇到错误,请暂时将存储帐户设置为允许从所有网络访问,然后重试。 文件上传配置完成后,可以在存储帐户上配置防火墙。

    Screen shot that shows file upload with msi.

    注意

    在文件上传方案中,中心和设备都需要与存储帐户连接。 上述步骤用于使用所需身份验证类型将 IoT 中心连接到存储帐户。 仍然需要使用 SAS URI 将设备连接到存储。 目前,SAS URI 是使用连接字符串生成的。 我们即将添加对使用托管标识生成 SAS URI 的支持。 请按照文件上传中的步骤操作。

使用托管标识配置批量设备导入/导出

IoT 中心支持从/向客户提供的存储 blob 批量导入/导出设备的信息。 若要使用此功,需要从 IoT 中心连接到存储帐户。

  1. 在 Azure 门户中导航到存储帐户。

  2. 选择“访问控制 (IAM)”。

  3. 选择“添加”>“添加角色分配”。

    Screenshot showing Access control (IAM) page with Add role assignment menu open.

  4. 在“角色”选项卡上,选择“存储 Blob 数据参与者”。 (请勿选择“参与者”或“存储帐户参与者”。)

  5. 在“成员”选项卡上,选择“托管标识”,然后选择“选择成员”。

  6. 对于用户分配的托管标识,请选择你的订阅,选择“用户分配的托管标识”,然后选择你的用户分配的托管标识。

  7. 对于系统分配的托管标识,请选择你的订阅,选择“所有系统分配的托管标识”,然后选择你的 IoT 中心的资源名称。

  8. 在“查看 + 分配”选项卡上,选择“查看 + 分配”,以分配角色 。

    若要详细了解角色分配,请参阅使用 Azure 门户分配 Azure 角色

将 REST API 或 SDK 用于导入和导出作业

现在可以将 Azure IoT REST API 或 SDK 用于创建导入和导出作业。 需要在请求正文中提供以下属性:

  • storageAuthenticationType: 将值设置为 identityBased。
  • inputBlobContainerUri: 仅在导入作业中设置此属性。
  • inputBlobContainerUri: 在导入和导出作业中设置此属性。
  • identity: 将值设置为要使用的托管标识。

Azure IoT 中心 SDK 也支持在服务客户端的注册表管理器中使用此功能。 以下代码段演示如何在使用 C# SDK 时启动导入或导出作业。

C# 代码片段

    // Create an export job
 
    using RegistryManager srcRegistryManager = RegistryManager.CreateFromConnectionString(hubConnectionString);
 
    JobProperties jobProperties = JobProperties.CreateForExportJob(
        outputBlobContainerUri: blobContainerUri,
        excludeKeysInExport: false,
        storageAuthenticationType: StorageAuthenticationType.IdentityBased,
        identity: new ManagedIdentity
        {
            userAssignedIdentity = userDefinedManagedIdentityResourceId
        });
    // Create an import job
    
    using RegistryManager destRegistryManager = RegistryManager.CreateFromConnectionString(hubConnectionString);
 
    JobProperties jobProperties = JobProperties.CreateForImportJob(
        inputBlobContainerUri: blobContainerUri,
        outputBlobContainerUri: blobContainerUri,
        storageAuthenticationType: StorageAuthenticationType.IdentityBased,
        identity: new ManagedIdentity
        {
            userAssignedIdentity = userDefinedManagedIdentityResourceId
        });

Python 代码片段

# see note below
iothub_job_manager = IoTHubJobManager("<IoT Hub connection string>")

# Create an import job
result = iothub_job_manager.create_import_export_job(JobProperties(
    type="import",
    input_blob_container_uri="<input container URI>",
    output_blob_container_uri="<output container URI>",
    storage_authentication_type="identityBased",
    identity=ManagedIdentity(
        user_assigned_identity="<resource ID of user assigned managed identity>"
    )
))

# Create an export job
result = iothub_job_manager.create_import_export_job(JobProperties(
    type="export",
    output_blob_container_uri="<output container URI>",
    storage_authentication_type="identityBased",
    exclude_keys_in_export=True,
    identity=ManagedIdentity(
        user_assigned_identity="<resource ID of user assigned managed identity>"
    ) 
))

注意

  • 如果将 storageAuthenticationType 设置为 identityBased,并且 userAssignedIdentity 属性不为 null,则作业将使用指定的用户分配的托管标识 。
  • 如果未使用 userAssignedIdentity 中指定的用户分配的托管标识配置 IoT 中心,则作业将失败。
  • 如果将 storageAuthenticationType 设置为 identityBased,并且 userAssignedIdentity 属性为 null,则作业将使用系统分配的托管标识 。
  • 如果未使用用户分配的托管标识配置 IoT 中心,则作业将失败。
  • 如果将 storageAuthenticationType 设置为 identityBased,并且中心上未配置用户分配的托管标识和系统分配的托管标识,则作业将失败 。

SDK 示例

后续步骤

使用以下链接详细了解 IoT 中心功能: