Today we are going to be talking about securing your function app API using Azure active directory(AAD).
Recently as part of a business request, we were required to host an API on Azure. We decided to host the API using Azure functions. As you may already know, we can secure the function API using API keys(by setting the authorization to “function” level) but today we will cover how to secure your function API using oAuth (via AAD). This means, to call our API, we will first need to call a token endpoint to retrieve a token. Then using the token we can call our function API. We will simulate this using postman. We will not cover too much details about the function itself but focus on the authentication portion instead. A simplistic diagram is shown below.
As a first step, lets create our basic function app. We will use the http triggered template.
Go to the Azure Home page and click on “Create Resource”.
Enter “function” in the search box and click on “Function app” in the drop down list.
Click on Create.
Select your resource group. Enter a function name (I’ve selected anufunchttp).
Set the runtime stack to .NET. Select your region (I’ve selected South India).
Set the other options as shown below.
Click on “Review + Create”. Once validation is complete, click “Create” and wait for the deployment to be completed.
*The function app will automatically be created on consumption plan which is the cheapest plan available.
Now go to your function app and click on “Functions” on the left side pane. Click on “+Add”. As a template click on “HTTP trigger” and set the Authorization level to “Anonymous”. Click Add.
Once your function is created, click on “Get Function Url”.
This will give you the url of your function. It will be something like https://anufunchttp.azurewebsites.net/api/HttpTrigger1?. Copy this and store it in your note pad. We will now attempt to call this function first from our browser and then from postman.
First go to your browser and in the search box type in your url followed by “name=XYZ”. In my case it was https://anufunchttp.azurewebsites.net/api/HttpTrigger1?name=XYZ.You should immediately get a result pop up in the screen as shown below.
Basically in the background our function with default code was called with a name parameter and it returns back some text as a response.
Let’s try and call this same API from Postman.
Here also we get the same result.
Our API is currently open to everyone on the internet. Sure you can set the Authorization level to “Function” to authenticate using an API key but there is a more secure way to do the authentication and that is what we will now setup.
As a first step, go to your function app and click to Authentication/Authorization under settings in the left. Set the App Service Authentication to ON. Set the Action to take to Login with AAD and then click on Azure Active Directory.
*Authentication can only be switched on for non Linux consumption plan. Since python uses Linux, you cannot switch AAD on for a python app using consumption plan. You will either need to use .NET or Java with consumption plan or switch to an app service or premium plan.
Set the Management mode to Express as shown below and Click Ok. What this means is that behind the scenes, Azure will create an App registration for you in Azure Active Directory and assign it to your function app.
Don’t forget to click SAVE in the next screen.
The settings will take a few minutes to propagate.
After waiting for about 5 minutes, let’s try calling the same function API from Postman. We should get the below result.
What just happened?
How come we are not authorized to call our API anymore? This is because the API is now secured by AAD. We need request AAD for a token to get temporary access to the API. We will now attempt to configure this.
We first need to register a new app(will call this mynewapp) on AAD which will call your function API.
Go to the home page and type Azure Active in the search box and click on Azure Active Directory from the drop down list.
Go to App registrations. You can see your function app entry as a new APP(because of the earlier step). Make note of the function app client id. It will be required later. Click on New registration to register a new app.
Enter a name for your new app, set the supported account types to Multi Tenant and click on Register
Once your app is created, make note of the Application (client) id and the Directory(tenant) id. If you click on Endpoints, a new pane will pop up. Copy the OAuth2.0 token endpoint v1.
Next click on the Certificates and Secrets on the left pane.
Click on New client secret and give your secret a name. Click on Add.
A secret will be generated for your new app. Copy this secret immediately and store it for later use. This is what you will share with applications who need to call your function API. For security reasons, you should create register different apps for each of your calling applications and create individual secrets for each of them.
*Once you close this window, the secret will no longer be visible.
Now we need to give this new app access to our function app. Click on API permissions to add the permission to your function app. Then click on “Add a permission” and select the App which was automatically created for your function app.
Make sure the Permissions box is checked and Click “Add Permissions”.
There is one final step required. Go to your Azure active directory and click on App registrations. Click on the app that was created for your function app.
Click on Authentication on the left pane. Make sure the “Access tokens” box is checked as shown below. Then click Save.
That’s it. We are done. Now let’s try and call our function API once more using oAuth flow.
You should have the following details handy.
· The function app client id. Let’s call this clientid1
· The calling app client id. Let’s call this clientid2
· The secret for the calling app. Let’s call this secret
· The tenant id. Let’s call this tenantid.
· The oAuth endpoint. https://login.microsoftonline.com/organizations/oauth2/token (replace organizations with your tenantid).
The first step of OAuth flow is to retrieve the bearer token.
We need a POST call with the body being set to x-www-form-urlencoded. Add the following key values in the body.
client_id — Set this to clientid2
client_secret — Set this to secret
grant_type — client_credentials
resource — Set this to clientid1
If everything is in order, the response should be a 200 message with a bearer token. This token is valid for 3599 second or roughly 1 hour.
So now, let’s try calling our original function API from postman using this bearer token.
In your original call, click the authorization tab and set this to Bearer token. Add the bearer token that you received from your earlier token call. This is called implicit grant oAuth 2.
You will notice an Authorization key value automatically added as part of the header. When you submit this request, you will get a 200 response this time with the original response message.
Don’t be surprised if this call stops working after 1 hour. That just means your token has expired, so you need to call the token end point for a new token. When calling the APIs from an application, It is recommended to cache the bearer token and only call the token endpoint when the existing token has expired.
Hopefully with demo, you would understand how to secure your function API using AAD (aka oAuth authentication). If you are still confused, just redo this demo a couple of time to get a hang of the steps.
Drop me a message or comment if you have any questions.