Azure API Management is a hybrid, multi-cloud management platform for APIs across all environments. It acts as a gateway for exposing API access to the cloud-native application.
This article describes how to setup authentication in Azure API Management for requests forwarded to Azure Functions.
It is assumed that Azure API Management and Azure Functions App has been created already and has enabled Identity.
Authentication setup for Azure Function Apps and API Management
Azure Functions apps has two keys by default, host
key and a default funcktionKey
. Those will are used to authenticate HTTP triggers for the app. For API Management authentication, a new function key apim-auth-key
for the app will be added. This will be the shared secret between API Management and Function App. When a request is forwarded from API Management to the Function App, apim-auth-key
will be added in the header so that the function execution can verify the request is legitimate. Otherwise the request will be rejected with invalid authentication error.
Adding Function Key
The following Azure CLI command will create a new function key-
# Value of the key will be generated
# Predefined value can be set with the option --key-value
az functionapp keys set --resource-group rg-demo --name azure-func-demo --key-name apim-auth-key --key-type functionKeys
If the command is successful, it will print the function key value-
{
"id": "/subscriptions/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg-demo/providers/Microsoft.Web/sites/azure-func-demo/host/default/functionKeys/apim-auth-key",
"location": "Central India",
"name": "apim-auth-key",
"resourceGroup": "rg-demo",
"type": "Microsoft.Web/sites/host/functionKeys",
"value": "F0uyVNNt2NXNfO1jYvSuTx0cKJF6HIWGyk5EezpLjvcIAzFuhTlwEg=="
}
Setting up Named Value in API Management
Named Values are globally stored name-value pairs for each API Management instance. It can be used for managing constant string values across all API Management configurations and policies. Named values can also store secret values. That’s why the function key will be stored in the named values, which will be used in backed forwarding configuration.
The following Bicep script will create a named value for API Management:
var apimResourceName = 'apim-test'
var functionKey = 'F0uyVNNt2NXNfO1jYvSuTx0cKJF6HIWGyk5EezpLjvcIAzFuhTlwEg=='
// Reference to existing API Management resource
resource resourceApiManagement 'Microsoft.ApiManagement/service@2021-12-01-preview' existing = {
name: apimResourceName
}
// Create property
resource resourcePropertiesFuncKey 'Microsoft.ApiManagement/service/properties@2019-01-01' = {
parent: resourceApiManagement
name: 'func-auth-key'
properties: {
displayName: 'func-auth-key'
value: functionKey
tags: [
'key'
'function'
]
secret: true
}
}
// Create named value
resource resourceNamesValuesFuncKey 'Microsoft.ApiManagement/service/namedValues@2021-08-01' = {
parent: resourceApiManagement
name: 'func-auth-key'
properties: {
displayName: 'func-auth-key'
tags: [
'key'
'function'
]
secret: true
value: functionKey
}
dependsOn: [
resourcePropertiesFuncKey
]
}
Adding Back-ends in API Management
A backend (or API backend) in API Management is an HTTP service that implements your front-end API and its operations.
Instead of creating forwarding policy for each operation, we can create a back-end and handle authentication in there.
The following Bicep script will create a back-end for the Function App in API Management:
resource resourceBackendFunctions 'Microsoft.ApiManagement/service/backends@2021-08-01' = {
parent: resourceApiManagement
name: 'azure-func-demo'
properties: {
description: 'azure-func-demo'
url: 'https://azure-func-demo.azurewebsites.net/api'
protocol: 'http'
resourceId: 'https://management.azure.com/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Web/sites/azure-func-demo'
credentials: {
header: {
'x-functions-key': [
'{{func-auth-key}}'
]
}
}
}
dependsOn: [
resourceNamesValuesFuncKey
]
}
Adding policy for the operation
Finally, we can set policy for an operation to use the previously created back-end and forward request to the service:
<policies>
<inbound>
<base />
<set-backend-service id="backend-demo" backend-id="azure-func-demo" />
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>