你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

在 Azure API 管理中使用托管标识

适用于:所有 API 管理层级

本文介绍如何为 Azure API 管理实例创建托管标识,以及如何使用它访问其他资源。 Microsoft Entra ID 生成的托管标识使 API 管理能够轻松安全地访问受 Microsoft Entra 保护的其他资源,例如 Azure Key Vault。 Azure 管理这些标识,因此无需预配或轮换任何机密。 有关托管标识的详细信息,请参阅什么是 Azure 资源托管标识?

可以向 API 管理实例授予两种类型的标识:

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

注意

托管标识特定于托管 Azure 订阅的 Microsoft Entra 租户。 如果将订阅移动到其他目录,则托管标识不会更新。 如果移动了订阅,则需要重新创建并重新配置标识。

注意

目前无法在工作区中使用此功能。

创建系统分配的托管标识

Azure 门户

若要在 Azure 门户中设置托管标识,请创建 API 管理实例,然后启用该功能。

  1. 按常规在门户中创建 API 管理实例。 在门户网站中转到它。

  2. 在左侧菜单中,在“安全性”下,选择“托管标识”。

  3. “系统分配 ”选项卡上,将 “状态 ”更改为 “打开”。 选择“保存” 。

    显示如何启用系统分配的托管标识的屏幕截图。

Azure PowerShell

注意

建议使用 Azure Az PowerShell 模块与 Azure 交互。 若要开始,请参阅安装 Azure PowerShell。 若要了解如何迁移到 Az PowerShell 模块,请参阅 将 Azure PowerShell 从 AzureRM 迁移到 Az

以下步骤将引导你创建 API 管理实例并使用 Azure PowerShell 为其分配标识。

  1. 如果需要,请按照 Azure PowerShell 指南中的说明安装 Azure PowerShell。 然后运行 Connect-AzAccount 以创建与 Azure 的连接。

  2. 使用以下代码创建具有系统分配的托管标识的实例。 有关如何将 Azure PowerShell 与 API 管理配合使用的更多示例,请参阅 API 管理 PowerShell 示例

    # Create a resource group.
    New-AzResourceGroup -Name $resourceGroupName -Location $___location
    
    # Create an API Management Consumption SKU service.
    New-AzApiManagement -ResourceGroupName $resourceGroupName -Name consumptionskuservice -Location $___location -Sku Consumption -Organization contoso -AdminEmail contoso@contoso.com -SystemAssignedIdentity
    

你还可以更新现有实例以创建标识:

# Get an API Management instance
$apimService = Get-AzApiManagement -ResourceGroupName $resourceGroupName -Name $apiManagementName

# Update an API Management instance
Set-AzApiManagement -InputObject $apimService -SystemAssignedIdentity

Azure 资源管理器 (ARM) 模板

可以使用系统分配的标识创建 API 管理实例,方法是在 ARM 模板资源定义中包含以下属性:

"identity" : {
    "type" : "SystemAssigned"
}

此属性指示 Azure 为 API 管理实例创建和管理标识。

例如,完整的 ARM 模板可能如下所示:

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "0.9.0.0",
    "resources": [{
        "apiVersion": "2021-08-01",
        "name": "contoso",
        "type": "Microsoft.ApiManagement/service",
        "___location": "[resourceGroup().___location]",
        "tags": {},
        "sku": {
            "name": "Developer",
            "capacity": "1"
        },
        "properties": {
            "publisherEmail": "admin@contoso.com",
            "publisherName": "Contoso"
        },
        "identity": {
            "type": "systemAssigned"
        }
    }]
}

创建实例后,它具有以下附加属性:

"identity": {
    "type": "SystemAssigned",
    "tenantId": "<TENANTID>",
    "principalId": "<PRINCIPALID>"
}

tenantId 属性标识该标识所属的 Microsoft Entra 租户。 principalId 属性是实例的新标识的唯一标识符。 在 Microsoft Entra ID 中,服务主体的名称与你为 API 管理实例提供的名称相同。

注意

API 管理实例可以同时具有系统分配的标识和用户分配的标识。 在这种情况下,该 type 属性为 SystemAssigned,UserAssigned.

使用托管标识配置密钥保管库访问权限

如果要使用 API 管理从 Azure 密钥保管库访问证书,则需要以下配置。

配置对密钥保管库的访问权限

  1. 在门户中转到密钥保管库。
  2. 在左侧菜单中,选择 “Access 配置”。 请注意配置的权限模型
  3. 根据权限模型,为 API 管理托管标识配置密钥保管库访问策略Azure RBAC 访问

若要添加密钥保管库访问策略,请执行以下操作:

  1. 在左侧菜单中,选择“访问策略”。
  2. 在“访问策略”页面上,选择“+ 创建”
  3. 在“ 权限 ”选项卡上的“ 机密权限”下,选择“ 获取列出”,然后选择“ 下一步”。
  4. 在“ 主体 ”选项卡上,选择 “主体”,搜索托管标识的资源名称,然后选择“ 下一步”。 如果你使用系统分配的标识,则主体为你的 API 管理实例的名称。
  5. 再次选择“下一步”。 在“查看 + 创建”选项卡上,选择“创建”。

配置 Azure RBAC 的访问权限:

  1. 在左侧菜单中,选择“访问控制(IAM)”。
  2. 在“访问控制(IAM)”页上,选择“添加角色分配”。
  3. 在“角色”选项卡上,选择“密钥保管库证书用户”
  4. 在“成员”选项卡上,选择“托管标识”“选择成员”。
  5. “选择托管标识 ”窗口中,选择系统分配的托管标识或与 API 管理实例关联的用户分配的托管标识,然后单击“ 选择”。
  6. 选择“查看 + 分配”。

Key Vault 防火墙要求

如果在 密钥保管库上启用了 Key Vault 防火墙 ,则必须满足以下要求:

  • 必须使用 API 管理实例的系统分配的托管标识来访问密钥保管库。

  • 在 Key Vault 防火墙中,启用“允许受信任的 Microsoft 服务绕过此防火墙”选项。

  • 在选择要添加到 Azure API 管理的证书或机密时,请确保允许本地客户端 IP 地址临时访问密钥保管库。 有关详细信息,请参阅配置 Azure Key Vault 网络设置

    完成配置后,可以在密钥保管库防火墙中阻止客户端地址。

虚拟网络要求

如果 API 管理实例部署在虚拟网络中,则还应配置下列网络设置:

  • 在 API 管理子网上启用密钥保管库的服务终结点
  • 配置一个网络安全组 (NSG) 规则,以允许指向 AzureKeyVault 和 AzureActiveDirectory 服务标记的出站流量。

有关详细信息,请参阅 在虚拟网络中设置 API 管理时的网络配置

支持使用系统分配标识的场景

下面是在 Azure API 管理中使用系统分配的托管标识的一些常见方案。

从 Key Vault 获取 API 管理实例的自定义 TLS/SSL 证书

可以使用 API 管理实例的系统分配标识来检索存储在 Key Vault 中的自定义 TLS/SSL 证书。 然后,可以将这些证书分配给 API 管理实例中的自定义域。 考虑以下注意事项:

  • 机密的内容类型必须是 application/x-pkcs12。 有关详细信息,请参阅 域证书选项
  • 必须用包含机密的密钥保管库证书机密终结点。

重要

如果未提供证书的对象版本,API 管理会在 Key Vault 中更新后四小时内自动获取证书的任何较新版本。

以下示例演示了一个 ARM 模板,该模板使用 API 管理实例的系统分配托管标识从 Key Vault 检索自定义域证书。

先决条件

  • 使用系统分配的托管标识配置的 API 管理实例。 若要创建实例,可以使用 Azure 快速入门模板
  • 同一资源组中的 Key Vault 实例。 该实例必须托管一个证书,该证书将用作 API 管理中的自定义域证书。

模板包含以下步骤。

  1. 更新 Key Vault 实例的访问策略,并允许 API 管理实例从中获取机密。
  2. 通过 Key Vault 实例中的证书设置自定义域名来更新 API 管理实例。

运行模板时,请提供适合你的环境的参数值。

{
	"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
	"contentVersion": "1.0.0.0",
	"parameters": {
        "apiManagementServiceName": {
            "type": "string",
            "minLength": 8,
            "metadata":{
                "description": "The name of the API Management instance"
            }
        },
		"publisherEmail": {
			"type": "string",
			"minLength": 1,
			"metadata": {
				"description": "The email address of the owner of the instance"
			}
		},
		"publisherName": {
			"type": "string",
			"minLength": 1,
			"metadata": {
				"description": "The name of the owner of the instance"
			}
		},
		"sku": {
			"type": "string",
			"allowedValues": ["Developer",
			"Standard",
			"Premium"],
			"defaultValue": "Developer",
			"metadata": {
				"description": "The pricing tier of the API Management instance"
			}
		},
		"skuCount": {
			"type": "int",
			"defaultValue": 1,
			"metadata": {
				"description": "The instance size of the API Management instance"
			}
		},
        "keyVaultName": {
            "type": "string",
            "metadata": {
                "description": "The name of the key vault"
            }
        },
		"proxyCustomHostname1": {
			"type": "string",
			"metadata": {
				"description": "Gateway custom hostname 1. Example: api.contoso.com"
			}
		},
		"keyVaultIdToCertificate": {
			"type": "string",
			"metadata": {
				"description": "Reference to the key vault certificate. Example: https://contoso.vault.azure.net/secrets/contosogatewaycertificate"
			}
		}
	},
	 "variables": {
        "apimServiceIdentityResourceId": "[concat(resourceId('Microsoft.ApiManagement/service', parameters('apiManagementServiceName')),'/providers/Microsoft.ManagedIdentity/Identities/default')]"
		    },
	"resources": [ 
   {
        "apiVersion": "2021-08-01",
        "name": "[parameters('apiManagementServiceName')]",
        "type": "Microsoft.ApiManagement/service",
        "___location": "[resourceGroup().___location]",
        "tags": {
        },
        "sku": {
            "name": "[parameters('sku')]",
            "capacity": "[parameters('skuCount')]"
        },
        "properties": {
            "publisherEmail": "[parameters('publisherEmail')]",
            "publisherName": "[parameters('publisherName')]"
        },
        "identity": {
            "type": "systemAssigned"
        }
    },
    {
        "type": "Microsoft.KeyVault/vaults/accessPolicies",
        "name": "[concat(parameters('keyVaultName'), '/add')]",
        "apiVersion": "2018-02-14",
        "properties": {
            "accessPolicies": [{
                "tenantId": "[reference(variables('apimServiceIdentityResourceId'), '2018-11-30').tenantId]",
                "objectId": "[reference(variables('apimServiceIdentityResourceId'), '2018-11-30').principalId]",
                "permissions": {
                     "secrets": ["get", "list"]
                }
            }]
        }
    },
	{
        "apiVersion": "2021-04-01",
		"type": "Microsoft.Resources/deployments",
        "name": "apimWithKeyVault",
		 "dependsOn": [
        "[resourceId('Microsoft.ApiManagement/service', parameters('apiManagementServiceName'))]"
        ],
        "properties": {
            "mode": "incremental",
            "template": {
                "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
				"contentVersion": "1.0.0.0",
				"parameters": {},			
				"resources": [{
					"apiVersion": "2021-08-01",
					"name": "[parameters('apiManagementServiceName')]",
					"type": "Microsoft.ApiManagement/service",
					"___location": "[resourceGroup().___location]",
					"tags": {
					},
					"sku": {
						"name": "[parameters('sku')]",
						"capacity": "[parameters('skuCount')]"
					},
					"properties": {
						"publisherEmail": "[parameters('publisherEmail')]",
						"publisherName": "[parameters('publisherName')]",
						"hostnameConfigurations": [{
							"type": "Proxy",
							"hostName": "[parameters('proxyCustomHostname1')]",
							"keyVaultId": "[parameters('keyVaultIdToCertificate')]"
						}]
					},
					"identity": {
						"type": "systemAssigned"
					}
				}]
		}
		}
	}
]
}

存储和管理 Key Vault 中的命名值

可以使用系统分配的托管标识访问 Key Vault 来存储和管理机密,以便在 API 管理策略中使用。 有关详细信息,请参阅在 Azure API 管理策略中使用命名值

使用 API 管理标识向后端进行身份验证

可以使用系统分配的标识通过 authentication-managed-identity 策略向后端服务进行身份验证。

使用系统分配的托管标识连接到 IP 防火墙后面的 Azure 资源

API 管理是针对以下资源的受信任 Microsoft 服务。 此受信任状态使服务能够连接到防火墙后面的以下资源。 显式将适当的 Azure 角色分配给一个资源实例的系统分配的托管标识后,该实例的访问范围将对应于分配给该托管标识的 Azure 角色。

将事件记录到事件中心

可以配置和使用系统分配的托管标识来访问事件中心,以记录 API 管理实例中的事件。 有关详细信息,请参阅 如何在 Azure API 管理中将事件记录到事件中心

创建用户分配的托管标识

注意

可以将 API 管理实例与多达 10 个用户分配的托管标识相关联。

Azure 门户

若要在门户中设置托管标识,必须先创建 API 管理实例并 创建用户分配的标识。 然后完成以下步骤。

  1. 转到门户中的您的 API 管理实例。

  2. 在左侧菜单中,在“安全性”下,选择“托管标识”。

  3. 在“用户分配”选项卡上,选择“添加”。

  4. 搜索之前创建的标识并选择它。 选择“添加” 。

    显示如何启用用户分配的托管标识的屏幕截图。

Azure PowerShell

注意

建议使用 Azure Az PowerShell 模块与 Azure 交互。 若要开始,请参阅安装 Azure PowerShell。 若要了解如何迁移到 Az PowerShell 模块,请参阅 将 Azure PowerShell 从 AzureRM 迁移到 Az

以下步骤将引导你创建 API 管理实例并使用 Azure PowerShell 为其分配标识。

  1. 如果需要,请按照 Azure PowerShell 指南中的说明安装 Azure PowerShell。 然后运行 Connect-AzAccount 以创建与 Azure 的连接。

  2. 使用以下代码创建实例。 有关如何将 Azure PowerShell 与 API 管理配合使用的更多示例,请参阅 API 管理 PowerShell 示例

    # Create a resource group.
    New-AzResourceGroup -Name $resourceGroupName -Location $___location
    
    # Create a user-assigned identity. This code requires installation of the Az.ManagedServiceIdentity module.
    $userAssignedIdentity = New-AzUserAssignedIdentity -Name $userAssignedIdentityName -ResourceGroupName $resourceGroupName
    
    # Create an API Management Consumption SKU service.
    $userIdentities = @($userAssignedIdentity.Id)
    
    New-AzApiManagement -ResourceGroupName $resourceGroupName -Location $___location -Name $apiManagementName -Organization contoso -AdminEmail admin@contoso.com -Sku Consumption -UserAssignedIdentity $userIdentities
    

还可以更新现有服务以向服务分配标识:

# Get an API Management instance.
$apimService = Get-AzApiManagement -ResourceGroupName $resourceGroupName -Name $apiManagementName

# Create a user-assigned identity. This code requires installation of the Az.ManagedServiceIdentity module.
$userAssignedIdentity = New-AzUserAssignedIdentity -Name $userAssignedIdentityName -ResourceGroupName $resourceGroupName

# Update the API Management instance.
$userIdentities = @($userAssignedIdentity.Id)
Set-AzApiManagement -InputObject $apimService -UserAssignedIdentity $userIdentities

ARM 模板

可以通过在资源定义中包含以下属性来创建具有标识的 API 管理实例:

"identity": {
    "type": "UserAssigned",
    "userAssignedIdentities": {
        "<RESOURCEID>": {}
    }
}

添加用户分配的类型会通知 Azure 使用为实例指定的用户分配标识。

例如,完整的 ARM 模板可能如下所示:

{
    "$schema": "https://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#",
    "contentVersion": "0.9.0.0",
    "resources": [{
        "apiVersion": "2021-08-01",
        "name": "contoso",
        "type": "Microsoft.ApiManagement/service",
        "___location": "[resourceGroup().___location]",
        "tags": {},
        "sku": {
            "name": "Developer",
            "capacity": "1"
        },
        "properties": {
            "publisherEmail": "admin@contoso.com",
            "publisherName": "Contoso"
        },
        "identity": {
            "type": "UserAssigned",
             "userAssignedIdentities": {
                "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('identityName'))]": {}
             }
        },
         "dependsOn": [
          "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('identityName'))]"
        ]
    }]
}

创建服务后,它具有以下附加属性:

"identity": {
    "type": "UserAssigned",
    "userAssignedIdentities": {
        "<RESOURCEID>": {
            "principalId": "<PRINCIPALID>",
            "clientId": "<CLIENTID>"
        }
    }
}

principalId 属性是用于 Microsoft Entra 管理的标识的唯一标识符。 clientId 属性是应用程序的新标识的唯一标识符,用于指定在运行时调用期间要使用的标识。

注意

API 管理实例可以同时具有系统分配的标识和用户分配的标识。 在这种情况下,该 type 属性将为 SystemAssigned,UserAssigned.

支持使用用户分配的托管标识的场景

下面是在 Azure API 管理中使用用户分配的托管标识的一些常见方案。

从 Key Vault 获取 API 管理实例的自定义 TLS/SSL 证书

可以使用用户分配的标识在 API 管理实例和 Key Vault 之间建立信任。 然后,可以使用此信任来检索存储在 Key Vault 中的自定义 TLS/SSL 证书。 然后,可以将这些证书分配给 API 管理实例中的自定义域。

重要

如果密钥保管库上启用了 Key Vault 防火墙,则无法使用用户分配的标识从 API 管理进行访问。 可以改用系统分配的标识。 在 Key Vault 防火墙中,必须启用 “允许受信任的Microsoft服务绕过此防火墙 选项”。

考虑以下注意事项:

  • 机密的内容类型必须是 application/x-pkcs12。
  • 必须使用 Key Vault 的证书密钥终结点,该终结点包含机密信息。

重要

如果未提供证书的对象版本,API 管理会在 Key Vault 中更新后四小时内自动获取证书的任何较新版本。

存储和管理 Key Vault 中的命名值

可以使用用户分配的托管标识访问 Key Vault 来存储和管理用于 API 管理策略的机密。 有关详细信息,请参阅在 Azure API 管理策略中使用命名值

注意

如果密钥保管库上启用了 Key Vault 防火墙,则无法使用用户分配的标识从 API 管理进行访问。 可以改用系统分配的标识。 在 Key Vault 防火墙中,必须启用 “允许受信任的Microsoft服务绕过此防火墙 选项”。

使用用户分配的标识向后端进行身份验证

可以使用用户分配的标识通过 authentication-managed-identity 策略向后端服务进行身份验证。

将事件记录到事件中心

可以配置和使用用户分配的托管标识来访问事件中心,以记录 API 管理实例中的事件。 如需了解更多信息,请参阅如何在 Azure API 管理中将事件记录到 Azure 事件中心

删除标识

可以通过门户或 ARM 模板禁用功能,以与创建功能相同的方式移除系统分配的标识。 可以单独删除用户分配的标识。 若要删除所有标识,请将标识类型设置为 "None"

以这种方式删除系统分配的身份标识也会将其从 Microsoft Entra ID 中删除。 删除 API 管理实例时,也将自动从 Microsoft Entra ID 中删除系统分配的标识。

若要使用 ARM 模板删除所有标识,请更新本部分:

"identity": {
    "type": "None"
}

重要

如果 API 管理实例配置了 Key Vault 中的自定义 SSL 证书,并且你尝试禁用托管标识,则请求将失败。

可以通过从 Key Vault 证书切换到内联编码的证书,然后禁用托管标识来解决此问题。 有关详细信息,请参阅配置自定义域名