In Part 1 of this series we created two Azure Functions protected by function keys and published those to Azure. In this part we're going to use Azure API Management to wrap those functions and provide access via API Keys.
Head back into Azure create a new resource choosing API Management
Provide an appropriate resource name for your instance and then choose the Developer (no SLA) pricing tier. As mentioned in part 1, there are some restrictions placed on the consumption tier so for a real world application you would probably want to use one of the other tiers, and for this example we need access to the management API that you don't get with the consumption tier.
All other settings can be left at their default values for this example. The creation process may take a little bit of time.
Once your API Management resource has created open it in Azure and choose APIs from the left menu and then Function App
In the import wizard that opens you should be able to browse to your Function and Select the calls you want to import.
Your import for the System function should look similar to this.
In my example I've used the 'Full' option and adjusted the 'API URL suffix' and included a 'Version identifier' to make the URL for this function a bit cleaner.
Do the same for the User function.
If we open the v1 User API and click on the Test tab you should be able to see the complete Request URL.
Lets head back to Postman and try calling this API, but this time don't add the x-functions-key header value.
Notice that we received a slightly different error message this time. If we head back to the Function and look at the App keys you'll see that API Management has automatically created it's own Host key, apim-DevToAPIMan, and automatically uses this to call the function.
The API Management URI is now protected by a subscription key that can be generated in the API Management interface and we're going to use this alongside Products to provide us with a lot of control when it comes to providing access to our APIs.
Add two new products via the left hand menu option in API Management, one for the system function and one for the user function. Give them appropriate names and then also choose the APIs you want this product to give access to, ticking the 'Published' checkbox along the way.
Being able to specify which APIs are included in a product allows us to create separate products for different user types, with access to only the APIs those types require if we want.
Once we've created the products head over to the Subscriptions left hand menu entry and add a new subscription.
You'll notice in the create subscription screen we can set the scope Product and then select the product that this subscription has access to.
When the subscription is created two keys are generated for us, a primary and a secondary. This could allow us to, for example, use the primary key internally in our application to call services as a user, but then make the secondary key visible to the user so that they can call the APIs themselves, this way we can differentiate between an internal application call and an external user call at runtime, and also revoke and regenerate one or both of the keys as required.
Before we go ahead and use these keys, head back to our APIs and in the settings change the header and query parameter names to something easier, in this example 'devto-key'.
With 'Subscription required' ticked if we now provide one of the primary or secondary keys via a header or query parameter called 'devto-key' we should gain access to our API call.
Let's give it a test.
We've now got Azure Functions which we've published that can be called directly if we include a host key, but we won't use that method for access, instead we've created an instance of Azure API Management, imported our functions and then used products and subscriptions to control access to the APIs.
In the final step we're going to bring this all together by making changes to our System Azure Function so that it can programmatically create new user subscriptions in our API Management instance.
Head on over to Part 3 to continue this.