Azure APIM:如何使用用户分配的托管身份从密钥保管库获取SSL证书



当我尝试使用用户分配的托管身份从Azure密钥保管库为我的API管理实例获取自定义TLS/SSL证书时遇到问题,如下所述:从Azure密钥存储库为API管理实例获取定制TLS/SSL认证。与文档的不同之处在于,我的密钥保管库启用了网络访问规则。具体来说,用户指定的托管身份和密钥库的防火墙的组合很麻烦。

步骤:

  1. 为APIM创建vnet+子网
  2. 创建用户分配的托管标识
  3. 创建密钥保管库。允许从APIM的子网进行网络访问,并为用户分配的托管标识创建有关机密的GET/LIST访问策略
  4. 生成自签名证书并将其导入密钥保管库
  5. 部署APIM(开发人员SKU,内部vnet模式,具有用户分配的托管身份,使用密钥库中的ssl证书进行自定义主机名配置(

错误

这将导致以下错误消息。该消息具有误导性,因为给定的标识确实具有GET权限。

Failed to access KeyVault Secret https://kv-xxx.vault.azure.net/secrets/gateway-certificate/58542d0de4094c60856f97482a9b2e69 using Managed Service Identity (http://aka.ms/apimmsi) of Api Management service. Check if Managed Identity of Type: UserAssigned, ClientId: 2fa6db22-xxxx-xxxx-xxxx-xxxxxxxxxxxx and ObjectId: 91f8fa07-xxxx-xxxx-xxxx-xxxxxxxxxxxx has GET permissions on secrets in the KeyVault Access Policies.

成功场景

如前所述,似乎特别是用户指定的托管身份和具有网络访问规则的密钥库的这种组合很麻烦。以下内容确实有效:

  • 系统分配托管身份+密钥库上的防火墙
  • 用户分配的托管身份+密钥保管库上没有防火墙

部署

我用Bicep部署了我的资源,但我通过门户网站也遇到了同样的问题。

APIM:的二头肌模块

@description('Name of APIM service')
param apimName string
@description('Location')
param location string = resourceGroup().location
@allowed([
'Basic'
'Consumption'
'Developer'
'Isolated'
'Premium'
'Standard'
])
@description('SKU name of APIM')
param skuName string
@description('Capacity of the SKU (number of deployed units of the SKU)')
param skuCapacity int
@description('Id of the subnet')
param subnetId string
@description('Publisher email')
param publisherEmail string
@description('Publisher name')
param publisherName string
@description('Id of the managed identity')
param managedIdentityId string
@description('Client id of the managed identity')
param managedIdentityClientId string
@description('Reference to the Key Vault certificate')
param certificateKeyVaultId string
@description('Reference to the Key Vault certificate')
@secure()
param certificateKeyVaultPassword string
@description('Hostname of the gateway')
param gatewayHostname string
resource apim 'Microsoft.ApiManagement/service@2021-08-01' = {
name: apimName
location: location
sku: {
capacity: skuCapacity
name: skuName
}
identity: {
type: 'UserAssigned'
userAssignedIdentities: {
'${managedIdentityId}': {}
}
}
properties: {
hostnameConfigurations: [
{
type: 'Proxy'
hostName: gatewayHostname
defaultSslBinding: true
certificateSource: 'KeyVault'
identityClientId: managedIdentityClientId
keyVaultId: certificateKeyVaultId
certificatePassword: certificateKeyVaultPassword
}
]
publisherEmail: publisherEmail
publisherName: publisherName
virtualNetworkConfiguration: {
subnetResourceId: subnetId
}
virtualNetworkType: 'Internal'
}
}

链接:

  • https://github.com/MicrosoftDocs/azure-docs/issues/86983
  • https://learn.microsoft.com/en-us/azure/api-management/api-management-howto-integrate-internal-vnet-appgateway#set-api管理中的up自定义域名
  • https://learn.microsoft.com/en-us/azure/api-management/api-management-howto-use-managed-service-identity#use-azure密钥库ua的ssl tls证书

正如这里提到的。如果在密钥保管库上启用了密钥保管库防火墙,则必须使用API管理实例的系统签名托管标识来访问密钥保管库。

要绕过这一点,你可以试试这个(如果你不想明确列出APIM控制平面IP的白名单(:

  1. 在不使用自定义域的情况下部署APIM
  2. 将APIM系统分配的标识添加到ssl证书密钥库
  3. 使用自定义域重新部署APIM

最新更新