在 Azure API 管理中使用托管标识
适用于:所有 API 管理层级
本文说明如何创建 Azure API 管理实例的托管标识以及如何使用它来访问其他资源。 借助 Microsoft Entra ID 生成的托管标识,API Management 实例可以轻松、安全地访问其他受 Microsoft Entra 保护的资源,例如 Azure Key Vault。 Azure 管理此标识,因此无需预配或轮换任何机密。 有关托管标识的详细信息,请参阅什么是 Azure 资源托管标识?。
可以向 API 管理实例授予两种类型的标识:
- 系统分配的标识与你的服务绑定,如果删除服务,标识也会被删除。 服务只能有一个系统分配的标识。
- 用户分配的标识是可以分配给服务的独立 Azure 资源。 服务可以有多个用户分配的标识。
注意
托管标识特定于托管 Azure 订阅的 Microsoft Entra 租户。 如果将订阅移动到其他目录,则托管标识不会更新。 如果订阅移动,则需要重新创建和配置标识。
创建系统分配的托管标识
Azure 门户
若要在 Azure 门户中设置托管标识,需先创建 API 管理实例,然后启用该功能。
按常规在门户中创建 API 管理实例。 在门户中浏览到它。
在左侧菜单中,在“安全性”下,选择“托管标识”。
在“系统分配”选项卡中,将“状态”切换为“启用” 。 选择“保存” 。
Azure PowerShell
注意
建议使用 Azure Az PowerShell 模块与 Azure 交互。 请参阅安装 Azure PowerShell 以开始使用。 若要了解如何迁移到 Az PowerShell 模块,请参阅 将 Azure PowerShell 从 AzureRM 迁移到 Az。
以下步骤将指导你完成使用 Azure PowerShell 创建 API 管理实例并为其分配标识的操作。
如果需要,请按照 Azure PowerShell 指南中的说明安装 Azure PowerShell。 然后运行
Connect-AzAccount
以创建与 Azure 的连接。使用以下代码创建具有系统分配的托管标识的实例。 有关如何将 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 资源管理器模板
在资源定义中包括以下属性,可以创建具有系统分配的标识的 API 管理实例:
"identity" : {
"type" : "SystemAssigned"
}
此属性将告知 Azure 为 API 管理实例创建和管理标识。
例如,完整的 Azure 资源管理器模板可能如下所示:
{
"$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
。
使用托管标识配置 Key Vault 访问
API 管理需要以下配置才能从 Azure 密钥保管库访问机密和证书。
配置对密钥保管库的访问权限
在门户中导航到你的密钥保管库。
在左侧菜单中,选择“访问配置”,并记下配置的权限模型。
根据权限模型,为 API 管理托管标识配置密钥保管库访问策略或 Azure RBAC 访问。
添加密钥保管库访问策略:
- 在左侧菜单中,选择“访问策略”。
- 在“访问策略”页上,选择“+ 创建”。
- 在“权限”选项卡上的“机密权限”下,选中“获取”和“列出”,然后选择“下一步”。
- 在“主体”选项卡上的“选择主体”中,搜索托管标识的资源名称,然后选择“下一步”。 如果你使用系统分配的标识,则主体为你的 API 管理实例的名称。
- 再次选择“下一步”。 在“查看 + 创建”选项卡上,选择“创建”。
配置 Azure RBAC 访问:
- 在左侧菜单中,选择“访问控制(IAM)”。
- 在“访问控制(IAM)”页上,选择“添加角色分配”。
- 在“角色”选项卡上,选择“密钥保管库机密用户”。
- 在“成员”选项卡上,选择“托管标识”>“+ 选择成员”。
- 在“选择托管标识”页上,选择系统分配的托管标识或与 API 管理实例关联的用户分配的托管标识,然后选择“选择”。
- 选择“查看 + 分配”。
Key Vault 防火墙要求
如果在密钥保管库上启用了 Key Vault 防火墙,则具有以下附加要求:
必须使用 API 管理实例的“系统分配的”托管标识来访问密钥保管库。
在 Key Vault 防火墙中,启用“允许受信任的 Microsoft 服务绕过此防火墙”选项。
在选择要添加到 Azure API 管理的证书或机密时,请确保允许本地客户端 IP 地址临时访问密钥保管库。 有关详细信息,请参阅配置 Azure Key Vault 网络设置。
完成配置后,可以在密钥保管库防火墙中阻止客户端地址。
虚拟网络要求
如果 API 管理实例部署在虚拟网络中,则还应配置下列网络设置:
- 在 API 管理子网上,启用 Azure Key Vault 的服务终结点。
- 配置一个网络安全组 (NSG) 规则,以允许指向 AzureKeyVault 和 AzureActiveDirectory 服务标记的出站流量。
有关详细信息,请参阅在 VNET 中设置 Azure API 管理时使用的网络配置。
使用系统分配标识的受支持方案
从 Azure 密钥保管库获取 API 管理实例的自定义 TLS/SSL 证书
可以使用 API 管理实例的系统分配标识来检索存储在 Azure 密钥保管库中的自定义 TLS/SSL 证书。 然后,可以将这些证书分配给 API 管理实例中的自定义域。 请记住以下注意事项:
- 机密的内容类型必须是 application/x-pkcs12。 详细了解自定义域证书要求。
- 使用包含机密的密钥保管库证书机密终结点。
重要
如果未提供证书的对象版本,在将证书的较新版本上传到密钥保管库后的四小时内,API 管理将自动获取该版本。
以下示例演示了一个 Azure 资源管理器模板,该模板使用 API 管理服务实例的系统分配托管标识从 Key Vault 检索自定义域证书。
先决条件
- 使用系统分配的托管标识配置的 API 管理服务实例。 若要创建实例,可以使用 Azure 快速入门模板。
- 同一资源组中的 Azure Key Vault 实例,托管将用作 API 管理中的自定义域证书的证书。
以下模板包含以下步骤。
- 更新 Azure Key Vault 实例的访问策略,并允许 API 管理实例从中获取机密。
- 通过 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 service"
}
},
"publisherEmail": {
"type": "string",
"minLength": 1,
"metadata": {
"description": "The email address of the owner of the service"
}
},
"publisherName": {
"type": "string",
"minLength": 1,
"metadata": {
"description": "The name of the owner of the service"
}
},
"sku": {
"type": "string",
"allowedValues": ["Developer",
"Standard",
"Premium"],
"defaultValue": "Developer",
"metadata": {
"description": "The pricing tier of this API Management service"
}
},
"skuCount": {
"type": "int",
"defaultValue": 1,
"metadata": {
"description": "The instance size of this API Management service."
}
},
"keyVaultName": {
"type": "string",
"metadata": {
"description": "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.cn/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"
}
}]
}
}
}
]
}
存储和管理 Azure Key Vault 中的命名值
可以使用系统分配的托管标识访问 Azure Key Vault 来存储和管理用于 API 管理策略的机密。 有关详细信息,请参阅在 Azure API 管理策略中使用命名值。
使用 API 管理标识向后端进行身份验证
可以使用系统分配的标识通过 authentication-managed-identity 策略向后端服务进行身份验证。
使用系统分配的托管标识连接到 IP 防火墙后面的 Azure 资源
API 管理是针对以下资源的受信任 Microsoft 服务。 这允许服务连接到防火墙后面的以下资源。 在为该资源实例的系统分配的托管标识显式分配适当的 Azure 角色之后,该实例的访问范围将与分配给托管标识的 Azure 角色相对应。
Azure 服务 | 链接 |
---|---|
Azure Key Vault | Trusted-access-to-azure-key-vault |
Azure 存储 | Trusted-access-to-azure-storage |
Azure 服务总线 | Trusted-access-to-azure-service-bus |
Azure 事件中心 | Trusted-access-to-azure-event-hub |
将事件记录到事件中心
可以配置和使用系统分配的托管标识来访问事件中心,以便从API 管理实例记录事件。 如需了解更多信息,请参阅如何在 Azure API 管理中将事件记录到 Azure 事件中心。
创建用户分配的托管标识
注意
可以将一个 API 管理实例与最多 10 个用户分配的托管标识相关联。
Azure 门户
若要在门户中设置托管标识,需先创建 API 管理实例,然后创建用户分配的标识。 然后启用此功能。
按常规在门户中创建 API 管理实例。 在门户中浏览到它。
在左侧菜单中,在“安全性”下,选择“托管标识”。
在“用户分配”选项卡上,选择“添加”。
搜索之前创建的标识并选择它。 选择“添加” 。
Azure PowerShell
注意
建议使用 Azure Az PowerShell 模块与 Azure 交互。 请参阅安装 Azure PowerShell 以开始使用。 若要了解如何迁移到 Az PowerShell 模块,请参阅 将 Azure PowerShell 从 AzureRM 迁移到 Az。
以下步骤将指导你完成使用 Azure PowerShell 创建 API 管理实例并为其分配标识的操作。
如果需要,请按照 Azure PowerShell 指南中的说明安装 Azure PowerShell。 然后运行
Connect-AzAccount
以创建与 Azure 的连接。使用以下代码创建实例。 有关如何将 Azure PowerShell 与 API 管理实例配合使用的更多示例,请参阅 API 管理 PowerShell 示例。
# Create a resource group. New-AzResourceGroup -Name $resourceGroupName -Location $location # Create a user-assigned identity. This 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 requires installation of the "Az.ManagedServiceIdentity" module.
$userAssignedIdentity = New-AzUserAssignedIdentity -Name $userAssignedIdentityName -ResourceGroupName $resourceGroupName
# Update an API Management instance
$userIdentities = @($userAssignedIdentity.Id)
Set-AzApiManagement -InputObject $apimService -UserAssignedIdentity $userIdentities
Azure Resource Manager 模板
在资源定义中包括以下属性,可以创建具有标识的 API 管理实例:
"identity": {
"type": "UserAssigned",
"userAssignedIdentities": {
"<RESOURCEID>": {}
}
}
添加用户分配的类型即告知 Azure 使用为实例指定的用户分配标识。
例如,完整的 Azure 资源管理器模板可能如下所示:
{
"$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 管理实例的自定义 TLS/SSL 证书
你可以使用用户分配的标识在 API 管理实例和 Azure Key Vault 之间建立信任。 然后,可以借助这种信任关系检索存储在 Azure Key Vault 中的自定义 TLS/SSL 证书。 然后,可以将这些证书分配给 API 管理实例中的自定义域。
重要
如果密钥保管库上启用了 Key Vault 防火墙,则无法使用用户分配的标识从 API 管理进行访问。 可以改用系统分配的标识。 在 Key Vault 防火墙中,还必须启用“允许受信任的 Microsoft 服务绕过此防火墙”选项。
请记住以下注意事项:
- 机密的内容类型必须是 application/x-pkcs12。
- 使用包含机密的密钥保管库证书机密终结点。
重要
如果未提供证书的对象版本,在将证书的较新版本上传到密钥保管库后的四小时内,API 管理将自动获取该版本。
存储和管理 Azure Key Vault 中的命名值
可以使用用户分配的托管标识访问 Azure Key Vault 来存储和管理用于 API 管理策略的机密。 有关详细信息,请参阅在 Azure API 管理策略中使用命名值。
注意
如果密钥保管库上启用了 Key Vault 防火墙,则无法使用用户分配的标识从 API 管理进行访问。 可以改用系统分配的标识。 在 Key Vault 防火墙中,还必须启用“允许受信任的 Microsoft 服务绕过此防火墙”选项。
使用用户分配的标识向后端进行身份验证
可以使用用户分配的标识通过 authentication-managed-identity 策略向后端服务进行身份验证。
将事件记录到事件中心
可以配置和使用用户分配的托管标识来访问事件中心,以便从API 管理实例记录事件。 如需了解更多信息,请参阅如何在 Azure API 管理中将事件记录到 Azure 事件中心。
删除标识
可以通过在门户中禁用功能或通过 Azure 资源管理器模板(和创建标识的方法相同)来删除系统分配的标识。 可以单独删除用户分配的标识。 若要删除所有标识,请将标识类型设置为 "None"
。
以这种方式删除系统分配的标识也会将它从 Microsoft Entra ID 中删除。 删除 API 管理实例时,也将自动从 Microsoft Entra ID 中删除系统分配的标识。
若要使用 Azure 资源管理器模板删除所有标识,请更新此部分:
"identity": {
"type": "None"
}
重要
如果使用密钥保管库中的自定义 SSL 证书配置了 API 管理实例,并尝试禁用托管标识,则请求将失败。
可以通过从 Azure 密钥保管库证书切换到内联编码证书,然后禁用托管标识来取消阻止自己。 有关详细信息,请参阅配置自定义域名。
后续步骤
详细了解 Azure 资源的托管标识: