I wrote previously about calling Azure Logic apps with Managed Identity from API Management – I decided to test the same pattern with Azure functions as API imported to APIM, and write a short post as documentation about it.
Disclaimer: This guide assumes previous knowledge about importing functions to API management; In case the subject is not familiar, I’d recommend reading the following docs article ’Import an Azure Function App as an API in Azure API Management’
✅ Enable Azure AD Easy Auth for the function, take note of the clientid (Appid) from Azure AD Portal (Express setup is enough for validating this test)
- Note: Easy auth by default does not restrict the Function for any user or SPN inside the tenant; it just verifies that the token was issued inside the same tenant, and has audience value that was registered for the function
- There are multiple ways to restrict which JWT’s the function accepts, but in our example, function is limited besides the JWT, to the Function authorization key, which is included in the import phase of function to APIM
- For our use case we remove redirect-uri from the application and the user sign-in using IDtokens issued by removing implicit grant; This makes the API only callable by the SPN’s that bear the JWT token and the Function Authorization Key
- In this simple configuration valid JWT token can be generated by any app registration in the tenant that can generate access tokens for App. In advanced use you can build further limitations on function to authorize based on scopes and claims.
Setup Azure API management
- Prerequisites (Have function ready in APIM)
✅ Enable Managed Identity for Azure API management
✅ Enable Authentication policy in single operation, or in the base policy for all functions in the API
- For me enabling it in the base policy makes most sense, as all operations do require JWT token to be validated in the function itself.
- Add following items in the base policy, replace with applicable values as per your own configuration.
<policies> <inbound> <authentication-managed-identity resource="a1cc707b-a118-4fde-8043-88f33bb939ca" output-token-variable-name="msi-access-token" ignore-error="false" /> <set-header name="Authorization" exists-action="override"> <value>@("Bearer " + (string)context.Variables["msi-access-token"])</value> </set-header> <set-backend-service id="apim-generated-policy" backend-id="groupfunc2" /> <base /> </inbound> <backend> <base /> </backend> <outbound> <base /> </outbound> <on-error> <base /> </on-error> </policies>
✅ Confirm that function authorizes APIM with the Bearer Token
- VScode debug feature is great use case here
- If you have enabled logs for Managed Identity, you can see the event from Log Analytics for the Authorization
At the moment of writing I have not tested this with the developer portal, but the way the policy is setup, it actually creates the JWT Token in base policy for the function. There are some pass-through scenarios which might need further work (which token to include in authorization header)