在 Azure API 管理中使用托管标识Use managed identities in Azure API Management

本文说明如何创建 API 管理服务实例的托管标识以及如何访问其他资源。This article shows you how to create a managed identity for an API Management service instance and how to access other resources. 借助 Azure Active Directory (Azure AD) 生成的托管标识,API 管理实例可以轻松、安全访问其他受 Azure AD 保护的资源(如 Azure Key Vault)。A managed identity generated by Azure Active Directory (Azure AD) allows your API Management instance to easily and securely access other Azure AD-protected resources, such as Azure Key Vault. 此标识由 Azure 托管,无需设置或转交任何机密。This identity is managed by Azure and does not require you to provision or rotate any secrets. 有关托管标识的详细信息,请参阅什么是 Azure 资源的托管标识?For more information about managed identities, see What is managed identities for Azure resources.

为 API 管理实例创建托管标识Create a managed identity for an API Management instance

使用 Azure 门户Using the Azure portal

若要在门户中设置托管标识,需先按常规创建 API 管理实例,然后启用该功能。To set up a managed identity in the portal, you will first create an API Management instance as normal and then enable the feature.

  1. 按常规在门户中创建 API 管理实例。Create an API Management instance in the portal as you normally would. 在门户中导航到该应用。Navigate to it in the portal.
  2. 选择“托管服务标识” 。Select Managed service identities.
  3. 将“使用 Azure Active Directory 注册”切换至“打开”。Switch Register with Azure Active Directory to On. 单击“保存”。Click Save.

启用 MSI

使用 Azure 资源管理器模板Using the Azure Resource Manager template

在资源定义中包括以下属性,可以创建具有标识的 API 管理实例:You can create an API Management instance with an identity by including the following property in the resource definition:

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

这将告知 Azure 为 API 管理实例创建和管理标识。This tells Azure to create and manage the identity for your API Management instance.

例如,完整的 Azure 资源管理器模板可能如下所示:For example, a complete Azure Resource Manager template might look like the following:

{
    "$schema": "https://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#",
    "contentVersion": "0.9.0.0",
    "resources": [{
        "apiVersion": "2017-03-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"
        }
    }]
}

使用托管服务标识访问其他资源Use the managed service identity to access other resources

Note

目前,托管标识可用于从 Azure Key Vault 为 API 管理自定义域名获取证书。Currently, managed identities can be used to obtain certificates from Azure Key Vault for API Management custom domain names. 不久后会支持更多方案。More scenarios will be supported soon.

从 Azure Key Vault 中获取证书Obtain a certificate from Azure Key Vault

必备条件Prerequisites

  1. 包含 pfx 证书的 Key Vault 必须与 API 管理服务在同一 Azure 订阅和同一资源组中。The Key Vault containing the pfx certificate must be in the same Azure subscription and the same Resource Group as the API Management service. 这是 Azure 资源管理器模板的要求。This is a requirement of the Azure Resource Manager template.
  2. 机密的内容类型必须是 application/x-pkcs12The Content Type of the secret must be application/x-pkcs12. 可以使用以下脚本上传证书:You can use the following script to upload the certificate:
$pfxFilePath = "PFX_CERTIFICATE_FILE_PATH" # Change this path 
$pwd = "PFX_CERTIFICATE_PASSWORD" # Change this password 
$flag = [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable 
$collection = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2Collection 
$collection.Import($pfxFilePath, $pwd, $flag) 
$pkcs12ContentType = [System.Security.Cryptography.X509Certificates.X509ContentType]::Pkcs12 
$clearBytes = $collection.Export($pkcs12ContentType) 
$fileContentEncoded = [System.Convert]::ToBase64String($clearBytes) 
$secret = ConvertTo-SecureString -String $fileContentEncoded -AsPlainText –Force 
$secretContentType = 'application/x-pkcs12' 
Set-AzureKeyVaultSecret -VaultName KEY_VAULT_NAME -Name KEY_VAULT_SECRET_NAME -SecretValue $Secret -ContentType $secretContentType

Important

如果未提供证书的对象版本,在将证书的较新版本上传到 Key Vault 后,API 管理将自动获取该版本。If the object version of the certificate is not provided, API Management will automatically obtain the newer version of the certificate after it is uploaded to Key Vault.

以下示例显示包含以下步骤的 Azure 资源管理器模板:The following example shows an Azure Resource Manager template that contains the following steps:

  1. 创建含托管标识的 API 管理实例。Create an API Management instance with a managed identity.
  2. 更新 Azure Key Vault 实例的访问策略,并允许 API 管理实例从中获取机密。Update the access policies of an Azure Key Vault instance and allow the API Management instance to obtain secrets from it.
  3. 通过 Key Vault 实例中的证书设置自定义域名来更新 API 管理实例。Update the API Management instance by setting a custom domain name through a certificate from the Key Vault instance.
{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "publisherEmail": {
            "type": "string",
            "minLength": 1,
            "metadata": {
                "description": "The email address of the owner of the service"
            }
        },
        "publisherName": {
            "type": "string",
            "defaultValue": "Contoso",
            "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 vault"
            }
        },
        "proxyCustomHostname1": {
            "type": "string",
            "metadata": {
                "description": "Proxy Custom hostname."
            }
        },
        "keyVaultIdToCertificate": {
            "type": "string",
            "metadata": {
                "description": "Reference to the KeyVault certificate. https://contoso.vault.azure.cn/secrets/contosogatewaycertificate."
            }
        }
    },
    "variables": {
        "apiManagementServiceName": "[concat('apiservice', uniqueString(resourceGroup().id))]",
        "apimServiceIdentityResourceId": "[concat(resourceId('Microsoft.ApiManagement/service', variables('apiManagementServiceName')),'/providers/Microsoft.ManagedIdentity/Identities/default')]"
    },
    "resources": [{
        "apiVersion": "2017-03-01",
        "name": "[variables('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": "2015-06-01",
        "dependsOn": [
            "[resourceId('Microsoft.ApiManagement/service', variables('apiManagementServiceName'))]"
        ],
        "properties": {
            "accessPolicies": [{
                "tenantId": "[reference(variables('apimServiceIdentityResourceId'), '2015-08-31-PREVIEW').tenantId]",
                "objectId": "[reference(variables('apimServiceIdentityResourceId'), '2015-08-31-PREVIEW').principalId]",
                "permissions": {
                    "secrets": ["get"]
                }
            }]
        }
    },
    {
        "apiVersion": "2017-05-10",
        "name": "apimWithKeyVault",
        "type": "Microsoft.Resources/deployments",
        "dependsOn": [
        "[resourceId('Microsoft.ApiManagement/service', variables('apiManagementServiceName'))]"
        ],
        "properties": {
            "mode": "incremental",
            "templateLink": {
                "uri": "https://raw.githubusercontent.com/solankisamir/arm-templates/master/basicapim.keyvault.json",
                "contentVersion": "1.0.0.0"
            },
            "parameters": {
                "publisherEmail": { "value": "[parameters('publisherEmail')]"},
                "publisherName": { "value": "[parameters('publisherName')]"},
                "sku": { "value": "[parameters('sku')]"},
                "skuCount": { "value": "[parameters('skuCount')]"},
                "proxyCustomHostname1": {"value" : "[parameters('proxyCustomHostname1')]"},
                "keyVaultIdToCertificate": {"value" : "[parameters('keyVaultIdToCertificate')]"}
            }
        }
    }]
}

后续步骤Next steps

详细了解 Azure 资源的托管标识:Learn more about managed identities for Azure resources: