In this article I want to revisit securing an Azure Function so that it cannot be called directly, but can be called by Azure API Management.
To do this, I am going to leverage Managed Identities and make use of this in my API Management policy.
I know I could do this with IP white listing, but the fact that I am going to create my API Management instance at the Consumption tier is going to limit this, as no IP Addresses, at least that I could see, are provided to white list.
The Function App was created with the following settings:
- Runtime Stack: .NET Core
- Plan: Consumption
The API Management was created with the following settings:
- Pricing Tier: Consumption
I created an HttpTrigger Function in the Function App.
I set the Function access to
Just to note, according to the documentation, it is NOT recommended to secure Function Apps in production with Api Keys, which is why I am securing with Azure Active Directory.
I copy my Function Url, will need that in a later step.
In API Management I created a Blank Api, I gave it the same name as my Function App.
I created an operation and gave it the same name as my function, in this case,
I opened up the policy editor for the
I set my policy to the following:
<policies> <inbound> <base /> <set-backend-service base-url="FUNCTION_URL" /> <rewrite-uri template="/" /> </inbound> <backend> <base /> </backend> <outbound> <base /> </outbound> <on-error> <base /> </on-error> </policies>
FUNCTION_URL with the Function Url I copied in a previous step.
Using Postman, I called both the Function App directly and from API Management.
Both calls were successful.
Secure the Function App.
To do this, I just followed the steps in my previous article http://www.mattruma.com/secure-an-azure-function-app-with-azure-active-directory/.
When I try to call my Function App directly in Postman I receive a
401 - Unauthorized error, exactly what I was expecting.
Same thing happens when I try that operation in API Management.
Give API Management access to call the Function App.
From the API Management blade, I selected Managed Identities.
Set Status to On.
Once the Managed Identity is created, I navigated to the HttpTrigger1 operation in API Management.
I opened up the policy and added a
I set the
resource attribute to the URL of my Function App, it also works with the Function App’s Object Id.
I clicked Save.
I ran my test again from API Management.
It worked successfully!
This works for other services within Azure, e.g. Logic Apps, App Services, etc.
As long as Managed Identity is enabled on the calling resource and a token is provided, the calls to the Function App will be successful.
This will also work for any Subscription within the same Tenant as they all share the same Azure Active Directory.
Next step is trying to determine if I can limit it to just a single Subscription and/or API Management calling the Function App, but for now this works.