具有托管标识的 Azure 托管应用程序

注意

Azure 托管应用程序的托管标识支持目前为预览版。 请使用 2018-09-01-preview API 版本来利用托管标识。

了解如何将托管应用程序配置为包含托管标识。 托管标识可用于允许客户向托管应用程序授予对现有资源的访问权限。 标识由 Azure 平台托管,且无需预配或轮换任何机密。 有关 Microsoft Entra ID 中的托管标识的详细信息,请参阅 Azure 资源的托管标识

你的应用程序可以被授予两种类型的标识:

  • 系统分配的托管标识与你的应用程序相绑定,如果删除应用,标识也会被删除。 一个应用只能具有一个系统分配的托管标识。
  • 用户分配的托管标识是可以分配给应用的独立 Azure 资源。 一个应用可以有多个用户分配的托管标识。

如何使用托管标识

托管标识可以实现托管应用程序的多种方案。 可解决的常见方案包括:

  • 部署链接到现有 Azure 资源的托管应用程序。 例如,在托管应用程序中部署已附加到现有网络接口的 Azure 虚拟机 (VM)。
  • 向托管应用程序和发布者授予对受管理资源组外部的 Azure 资源的访问权限。
  • 为活动日志以及 Azure 中的其他服务提供托管应用程序的操作标识。

添加托管标识

要创建具有托管标识的托管应用程序,需要在 Azure 资源上设置另一个属性。 下面演示了一个示例标识属性:

{
  "identity": {
    "type": "SystemAssigned, UserAssigned",
    "userAssignedIdentities": {
      "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testRG/providers/Microsoft.ManagedIdentity/userassignedidentites/myuserassignedidentity": {}
    }
  }
}

有两种常用方法来创建具有identity的托管应用程序:createUiDefinition.jsonAzure 资源管理器模板。 对于简单的单一创建方案,应使用 createUiDefinition 来启用托管标识,因为它提供了更丰富的体验。 但是,在处理需要自动化部署或多个托管应用程序部署的高级系统或复杂系统时,可以使用模板。

使用 createUiDefinition

可以通过 CreateUIDefinition.json 为托管应用程序配置托管标识。 在输出部分中,键 managedIdentity 可用于替代托管应用程序模板的标识属性。 以下示例在托管应用程序上启用系统分配的托管标识。 可以通过使用 createUiDefinition 元素要求使用者提供输入,来构建更复杂的标识对象。 这些输入可用于构造具有用户分配的托管标识的托管应用程序。

"outputs": {
  "managedIdentity": { "Type": "SystemAssigned" }
}

何时使用 createUiDefinition 来启用托管标识

下面是有关何时使用 createUiDefinition 以在托管应用程序中启用托管标识的一些建议。

  • 托管应用程序的创建通过 Azure 门户或 Azure 市场来完成。
  • 托管标识需要复杂的使用者输入。
  • 创建托管应用程序时需要托管标识。

托管标识 createUiDefinition 控件

createUiDefinition 支持内置的托管标识控件

{
  "$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#",
  "handler": "Microsoft.Azure.CreateUIDef",
  "version": "0.1.2-preview",
  "parameters": {
    "basics": [],
    "steps": [
      {
        "name": "applicationSettings",
        "label": "Application Settings",
        "subLabel": {
          "preValidation": "Configure your application settings",
          "postValidation": "Done"
        },
        "bladeTitle": "Application Settings",
        "elements": [
          {
            "name": "appName",
            "type": "Microsoft.Common.TextBox",
            "label": "Managed application Name",
            "toolTip": "Managed application instance name",
            "visible": true
          },
          {
            "name": "appIdentity",
            "type": "Microsoft.ManagedIdentity.IdentitySelector",
            "label": "Managed Identity Configuration",
            "toolTip": {
              "systemAssignedIdentity": "Enable system assigned identity to grant the managed application access to additional existing resources.",
              "userAssignedIdentity": "Add user assigned identities to grant the managed application access to additional existing resources."
            },
            "defaultValue": {
              "systemAssignedIdentity": "Off"
            },
            "options": {
              "hideSystemAssignedIdentity": false,
              "hideUserAssignedIdentity": false,
              "readOnlySystemAssignedIdentity": false
            },
            "visible": true
          }
        ]
      }
    ],
    "outputs": {
      "applicationResourceName": "[steps('applicationSettings').appName]",
      "location": "[location()]",
      "managedIdentity": "[steps('applicationSettings').appIdentity]"
    }
  }
}

Screenshot of the application settings for system-assigned managed identity and user-assigned managed identity

使用 Azure 资源管理器模板

注意

将为经历 Azure 门户创建体验的客户自动生成市场托管应用程序模板。 对于这些方案,必须使用 createUiDefinition 中的 managedIdentity 输出键来启用标识。

也可以通过 Azure 资源管理器模板启用托管标识。 以下示例在托管应用程序上启用系统分配的托管标识。 可以通过使用 Azure 资源管理器模板参数提供输入,来构建更复杂的标识对象。 这些输入可用于构造具有用户分配的托管标识的托管应用程序。

何时使用 Azure 资源管理器模板来启用托管标识

下面是有关何时使用 Azure 资源管理器模板在托管应用程序中启用托管标识的一些建议。

  • 可以基于模板以编程方式部署托管应用程序。
  • 预配托管应用程序需要托管标识的自定义角色分配。
  • 托管应用程序不需要 Azure 门户和 Azure 市场创建流。

SystemAssigned 模板

用于部署具有系统分配的托管标识的托管应用程序的基本 Azure 资源管理器模板。

"resources": [
  {
    "type": "Microsoft.Solutions/applications",
    "name": "[parameters('applicationName')]",
    "apiVersion": "2018-09-01-preview",
    "location": "[parameters('location')]",
    "identity": {
        "type": "SystemAssigned"
    },
    "properties": {
        "ManagedResourceGroupId": "[parameters('managedByResourceGroupId')]",
        "parameters": { }
    }
  }
]

UserAssigned 模板

用于部署具有用户分配的托管标识的托管应用程序的基本 Azure 资源管理器模板。

"resources": [
  {
    "type": "Microsoft.ManagedIdentity/userAssignedIdentities",
    "name": "[parameters('managedIdentityName')]",
    "apiVersion": "2018-11-30",
    "location": "[parameters('location')]"
  },
  {
    "type": "Microsoft.Solutions/applications",
    "name": "[parameters('applicationName')]",
    "apiVersion": "2018-09-01-preview",
    "location": "[parameters('location')]",
    "identity": {
        "type": "UserAssigned",
        "userAssignedIdentities": {
            "[resourceID('Microsoft.ManagedIdentity/userAssignedIdentities/',parameters('managedIdentityName'))]": {}
        }
    },
    "properties": {
        "ManagedResourceGroupId": "[parameters('managedByResourceGroupId')]",
        "parameters": { }
    }
  }
]

授予对 Azure 资源的访问权限

为托管应用程序授予标识后,可通过创建角色分配为该应用程序授予对现有 Azure 资源的访问权限。

为此,请搜索并选择托管应用程序或用户分配的托管标识的名称,然后选择“访问控制 (IAM)”。 有关详细步骤,请参阅使用 Azure 门户分配 Azure 角色

链接现有的 Azure 资源

注意

在部署托管应用程序之前,必须配置用户分配的托管标识。 此外,托管应用程序的链接资源部署仅支持市场类型。

托管标识还可用于部署在部署期间需要访问现有资源的托管应用程序。 当客户预配了托管应用程序,可以添加用户分配的托管标识以在 mainTemplate 部署中提供更多授权。

使用链接资源创作 createUiDefinition

将托管应用程序的部署链接到现有资源时,必须提供现有的 Azure 资源,以及在该资源中具有适用角色分配的用户分配的托管标识。

需要两个输入的示例 createUiDefinition.json:网络接口资源 ID 和用户分配的托管标识资源 ID。

{
  "$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#",
  "handler": "Microsoft.Azure.CreateUIDef",
  "version": "0.1.2-preview",
  "parameters": {
    "basics": [
      {}
    ],
    "steps": [
      {
        "name": "managedApplicationSetting",
        "label": "Managed Application Settings",
        "subLabel": {
          "preValidation": "Managed Application Settings",
          "postValidation": "Done"
        },
        "bladeTitle": "Managed Application Settings",
        "elements": [
          {
            "name": "networkInterfaceId",
            "type": "Microsoft.Common.TextBox",
            "label": "Network interface resource ID",
            "defaultValue": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testRG/providers/Microsoft.Network/networkInterfaces/existingnetworkinterface",
            "toolTip": "Must represent the identity as an Azure Resource Manager resource identifer format ex. /subscriptions/sub1/resourcegroups/myGroup/providers/Microsoft.Network/networkInterfaces/networkinterface1",
            "visible": true
          },
          {
            "name": "userAssignedId",
            "type": "Microsoft.Common.TextBox",
            "label": "User-assigned managed identity resource ID",
            "defaultValue": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/testRG/providers/Microsoft.ManagedIdentity/userassignedidentites/myuserassignedidentity",
            "toolTip": "Must represent the identity as an Azure Resource Manager resource identifer format ex. /subscriptions/sub1/resourcegroups/myGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/identity1",
            "visible": true
          }
        ]
      }
    ],
    "outputs": {
      "existingNetworkInterfaceId": "[steps('managedApplicationSetting').networkInterfaceId]",
      "managedIdentity": "[parse(concat('{\"Type\":\"UserAssigned\",\"UserAssignedIdentities\":{',string(steps('managedApplicationSetting').userAssignedId),':{}}}'))]"
    }
  }
}

createUiDefinition.json 生成包含两个字段的“创建用户”体验。 第一个字段可让用户输入要链接到托管应用程序部署的资源的 Azure 资源 ID。 第二个字段可让使用者输入有权访问所链接 Azure 资源的用户分配的托管标识 Azure 资源 ID。 生成的体验如下所示:

Screenshot of a sample createUiDefinition.json with two inputs: a network interface resource ID and a user-assigned managed identity resource ID.

使用链接资源创作 mainTemplate

除了更新 createUiDefinition 以外,还需要更新主模板才能接受传入的链接资源 ID。 可以通过添加新的参数来更新主要模板,以接受新的输出。 由于 managedIdentity 输出将替代生成的托管应用程序模板中的值,因此不会将其传递到主模板,并且不应将其包含在参数部分中。

一个示例主模板,用于在 createUiDefinition.json 提供的现有网络接口中设置网络配置文件。

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "existingNetworkInterfaceId": { "type": "string" }
  },
  "variables": {
  },
  "resources": [
    {
      "apiVersion": "2016-04-30-preview",
      "type": "Microsoft.Compute/virtualMachines",
      "name": "myLinkedResourceVM",
      "location": "[resourceGroup().location]",
      "properties": {
        …,
        "networkProfile": {
          "networkInterfaces": [
            {
              "id": "[parameters('existingNetworkInterfaceId')]"
            }
          ]
        }
      }
    }
  ]
}

使用包含链接资源的托管应用程序

创建托管应用程序包后,可通过 Azure 门户使用该托管应用程序。 需要完成几个前提步骤才能使用该应用程序。

访问托管标识令牌

现在,可以在发布者租户中通过 listTokens API 访问托管应用程序的令牌。 示例请求可能如下所示:

POST https://management.chinacloudapi.cn/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/Microsoft.Solutions/applications/{applicationName}/listTokens?api-version=2018-09-01-preview HTTP/1.1

{
  "authorizationAudience": "https://management.chinacloudapi.cn/",
  "userAssignedIdentities": [
      "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{userAssignedIdentityName}"
  ]
}

请求正文参数:

参数 必需 说明
authorizationAudience 目标资源的应用 ID URI。 它也是颁发的令牌的 aud(受众)声明。 默认值为 https://management.chinacloudapi.cn/";
userAssignedIdentities 要检索其令牌的用户分配托管标识的列表。 如果未指定,listTokens 会返回系统分配的托管标识的令牌。

示例响应可能如下所示:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "value": [
    {
      "access_token": "eyJ0eXAi…",
      "expires_in": "2…",
      "expires_on": "1557…",
      "not_before": "1557…",
      "authorizationAudience": "https://management.chinacloudapi.cn/",
      "resourceId": "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/Microsoft.Solutions/applications/{applicationName}",
      "token_type": "Bearer"
    }
  ]
}

响应在 value 属性下包含令牌数组:

参数 说明
access_token 请求的访问令牌。
expires_in 访问令牌的秒数有效。
expires_on 访问令牌过期的时间范围。 此值表示自纪元以来的秒数。
not_before 访问令牌生效的时间范围。 此值表示自纪元以来的秒数。
authorizationAudience 请求其访问令牌的 aud(受众)。 此值与 listTokens 请求中提供的值相同。
resourceId 颁发的令牌的 Azure 资源 ID。 此值为托管应用程序 ID 或用户分配的托管标识 ID。
token_type 令牌的类型。