2020-12-04 11:11 pm #FestiveTechCalendar
In this walk-through, you will be guided through securing your Azure Functions so that a random user can’t just execute your functions, even if they have the function key and full function URL. Therefore, by the end of this walk-through you’ll have more security available than what you would get from just using a function key alone.
The overarching goal is to create your public-facing Application Programming Interface (API) in such a way that you can leverage Azure Functions without the functions being open to the world, and then you can use Azure API Management (APIM) as a public-facing facade to let specific customers into the appropriate APIs.
With APIM, you will not only be able to expose your own APIs as needed, but you can also route users to a third-party API without them even knowing you are using the third-party API, if you need to do so. Even if the customers do know that you are using a third-party API, all they need from you is one URL to access all of the APIs you need to expose to them. This also protects the customers from having to know what your third-party API key is, since they will never need to call the third-party API directly.
APIM also has additional gains when it comes to dealing with bad players. With APIM you can easily throttle users on an API. If you use a plan other than the consumption plan, you can further throttle the API by specific IP or subscription key. This functionality won’t be covered in this walk-through, but you will be set up to use it if you want to go deeper in the future.
This walkthrough is featured in day 6 of the festive tech calendar!
Watch the video of me working through this walkthrough here: Festive Tech Calendar [day 6]: Azure Functions and APIM
More info about the Festive Tech Calendar
To get started, you will need the following:
To simulate your current functions at Azure, for use in this walk-through you’ll just use a simple function app. This function app will contain a couple of simple functions so that you can see a few of the features of APIM later in the walk-through.

SimpleFunctions
Select a folder that makes sense to you for storing the function app, then hit the Create button.
Http Trigger and use the Storage emulator and give the function an authorization level of Function.
SimpleAuthorizationFunction by right-clicking on the Function1.cs file and renaming:SimpleAuthorizationFunction
Make sure to also update the FunctionName attribute to reflect the new name.
Add -> New Azure Function.
SimpleAnonymousFunctionSimpleAnonymousFunction
For this function, choose Anonymous authorization and an Http Trigger


http://localhost:7071/api/SimpleAnonymousFunction?name=brian

Azure Cloud Shell and select Bash as the terminal. When the terminal is connected, run the following command [note: you should change the location to a region near you [az account list-locations –query “[].{Name:name}” -o table]]:rgname="azurefunctionsandapim"
echo $rgname
loc="centralus"
echo $loc
az group create --location $loc --name $rgname

storagename="afandapimstor$RANDOM"
echo $storagename
az storage account create --name $storagename --location $loc --resource-group $rgname --sku Standard_LRS
This will create your storage account for the Azure Function App.
fAppName="afandapimfa$RANDOM"
echo $fAppName
az functionapp create --name $fAppName --storage-account $storagename --consumption-plan-location $loc --resource-group $rgname --functions-version 3
NOTE: Make sure your function version matches what you created in Visual Studio (likely 3 at this point).This will create everything you need to deploy the app. Browse to the resource group to see all of the provisioned resources.

Build -> Publish
Azure and Next.
Azure Function App (Windows) and Next
Finish
Publish
Functions to see that everything deployed as expected.
SimpleAuthorizationFunction to navigate to the function in the portal. Once there, click on Get Function URL to get the URL for the public-facing function.
&name=yourname to the end to see that it is working as expected.https://afandapimfa28230.azurewebsites.net/api/SimpleAuthorizationFunction?code=RcJ1...&name=brian


The functions are publicly-exposed, so anyone with the key can execute them. In this task you will lock the functions down so that only authenticated users can execute the functions.
In the previous step, you’ve already proved that the functions are public, because they are accessible from postman. Now you need to lock them down.
Authentication / Authorization option under Settings.
App Service Authentication. Then select Azure Active Directory. This will open the Azure Active Directory Settings for the function app.
Express. Then save with the default settings by hitting OK. If you already had an AD App, you could select it here, but you likely don’t, so you need to create a new one.
OK, you’ll return to the Authentication / Authorization window. Make sure to hit Save to actually save the application settings.
Advanced instance. Navigate away from the function app by going to the home directory at azure or going to some other resource, then come back to the function app. Select the Authentication / Authorization option again, then change Active Directory to Advanced. This will show you the Client ID and secret. Make a note of the Client ID and secret for use later in this walk-through.
OK and Save again, so that your changes are applied. As a final step, make sure to select Log in with Azure Active Directory in the Action to take when request is not authenticated dropdown.
401 - Unauthorized error on execution of the function.
In this task you will create the APIM that you will use for your public-facing facade. You will then create a couple of APIs to separate functions so you can see how the different subscriptions can give access to different clients.
After creating a couple of APIs, you will create a couple of Products, each having one or more subscriptions.
Create a Resource.
API Management and select it when it pops up in the dropdown.
Create button.
mypublicapi
Enter whatever you want for the organization name, and your email for administrator email. Select the Consumption plan in the drop down (Consumption will spin up quickly, others take somewhere around 45 minutes to provision). In the end, you should have settings similar to what is shown here:
Monitoring tab, you will likely want to have Application Insights enabled in the real world. For this, you don’t need it. In my instance, I am turning it on and using the same AI instance that is being used by my function app. This is also likely not ideal as you probably don’t want to mix and match these resources into the same AI instance.IMPORTANT: In order for this APIM to communicate with the Azure Function App, you need to make sure that this APIM has a managed identity. You can enable that now during creation. In case you forget or didn’t do this, the way to do this will be covered shortly. For the demo, I’m leaving it unchecked on purpose.

off for this demo - even though this may not be totally feasible in the real world, it should be the safest. Review and Create the APIM instance. This is another opportunity to get a coffee. If you selected a version other than the Consumption plan, you should probably go to lunch. The APIM should be up in about 3-5 minutes. When the deployment completes, you can go to the resource group and drill into the APIM, or you can search for it by searching for API Management Services in the top search bar. Either way, find the APIM you created and navigate to it.
APIs, Subscriptions, and the Gateway URL which is named after the name you put in for the APIM instance. Additionally, another important menu is Managed Identities which is not shown, but is in the left menu under Security.
APIs option in the left menu.
Function App option to select the function app for use in the API.


Authorization function. Then hit Select.
AllPublicData
Also change the API URL suffix toPublic
Then hit the Create button.

GET method, and then hit the Test button at the top.
Send button to send a request.
AllCustomerData
Use the URL SuffixCustomer
Use the same function app and include bot of your available functions. As before, none of the functions will be authorized, but the API is in place.
Public data, exposing the SimpleAnonymousFunction from the AllPublicData API. The second product will expose the Customer data, with access to both of the methods from the AllCustomerData API. You could create an additional product to span both APIs, if you needed to do so. Create a new product by hitting the Products option in the left menu. Then hit the + Add button at the top.
Unrestricted
Give it a description likeThis is the Public Data Product
Set it to Published and leave the check boxes for Requires subscription checked and Requires approval unchecked. Then hit the Select API button For this one, only select the AllPublicData Then hit Create
Customer API. Call this new APIClient
Additionally, make sure that this product also requires a subscription to be able to be used.


+ Add subscription and create a new subscription with the namePremiumClient
And the display name Premium.

Subscriptions. Note that your product subscription is also shown here.
PublicBasic
with DisplayName Basic, and make sure to drill into the subscription and make a note of the subscription key.Unrestricted

Ocp-Apim-Subscription-Key. This will be critical for your call. In Postman, create a new request. Use the GET URL and save the request asAllPublicData Get SimpleAuth
Which points to the URLhttps://mypublicapi.azure-api.net/Public/SimpleAnonymousFunction
Note: Your API will vary, of course.And hit the send button. You should a message similar to the following:

Ocp-Apim-Subscription-Key
Set the value to one of the keys from your Basic subscription. Then resend the request. The message should change back to a 401 - You do not have permission.

The main trick to getting this to work is to let your APIM instance work as if it is an authenticated user, so that the APIM can leverage your Azure Functions.
Managed Identities which is under the Security. Set the status to On for System Assigned (If you already set this, you will already have a system assigned id).
Save, then Yes to create the id.
App Registrations now.

All APIs then click on the Policies to open the All APIs -> Policies window:
<inbound /> policies:<authentication-managed-identity resource="your-function-app-client-id-goes-here" />



Name to get the expected result.



In this walk-through, you have seen how you can easily create a function app, deploy it to azure, lock down the function app to require authentication, and then use a public-facing facade created by the Azure APIM to allow users to get into the correct functions via subscription keys.
At the end of this walk-through, you have made it so the only gateway into your azure functions (APIs) is via the APIM or an authenticated user. When this is set, direct calls to your functions are blocked unless the user is authenticated. Additionally, you prevented direct calls to your APIM methods by requiring a subscription on each of the APIs. You saw how to easily add products and subscriptions to group your clients, and noted that you can easily rotate these subscription tokens if things go off track.
If you enjoyed this walk through, you should go deeper. At Opsgility, we have a training where you can explore these concepts and more in our Azure App Security challenge, and you can also earn a badge by completing this training. Check out our schedule here, or contact us to find out more about how you can take the Azure App Security challenge or other trainings through Skill Me UP Academy.
Additional concepts you will want to learn to enhance your knowledge include using the APIM to throttle bad players, version your APIs, connect to Azure Key Vault and get secrets, and do other things like make sure that users can’t see what your APIs are doing via the functions.
Categories: : C#, Azure, Azure Functions, APIM, Managed Identity, Azure AD