Thumbnail Finding the minimal Azure Function authentication setup

Finding the minimal Azure Function authentication setup

Azure Functions can expose API endpoints (HttpTriggers). By default those Http endpoints are only protected by a function key that needs to be sent along. As this is not very secure, most companies that use Azure Functions with API endpoints want to secure them through Entra ID. This is in fact really easy and configurable without writing a single line of code. But the default setup is not entirely optimal. This blog post highlights one subject to look at to make it better.

Say we want to build an API that can be called from the SharePoint Framework (for example). An Azure Function would be a great option there, as it’s easy to build an API with it. We would need a Function with HttpTriggers and some Entra ID authentication enabled above the usual function key setup.

Configuring Entra ID authentication on an Azure Function can be done using code, for example adapting the .NET pipeline with some authentication middleware. It’s not very hard and it’s super flexible, but there’s some steps to take, tests to do and some code to review. Instead of coding, you can also simply enable the built-in authentication. It’s a feature of the App Service infrastructure, and it can be configured with either Azure Functions or App Services. It’s as easy as flipping the switch and you can even select multiple identity providers.

enable built-in authentication

When building extensions for Microsoft 365, I’m mostly just interested in the Entra ID Identity Provider. When enabling this provider it will allow you the option to select an App Registration for authenticating your Azure Function. Instead of creating my own app registration manually, I mostly select the option to let Azure provision it for me. It’s easier because it will set it up precisely as needed.

…or so I thought. So I initially overlooked the reason for Azure to want to create a Client Secret on the application:

provision app registration

The mentioned Client Secret is created on the Entra app registration and added to the Azure Function environment variables section:

client secret environment variables

But this setup is actually annoying for a couple of reasons:

  1. Administrative burden
    You’ll need to factor in that the Client Secret will eventually expire. Recreating the secret will need to be added to someones IT Admin calendar. In short: secrets add an administrative burden.

  2. Insecure practice
    Adding a secret to the environment variables like this is not exactly a safe practice, anyone with read-only access to the resource would be able to read it. To make it secure you would need to add a KeyVault to the solution, making the application architecture more complex and expensive.

Client Secrets add an administrative burden because you'll need to factor in that they'll eventually expire and will need to be replaced. They also add complexity and cost.

When looking at the provisioned application, we can see that the Client Secret is indeed configured:

app registration with secret

But there’s something else as well, in the authentication section, it appears that the Web platform has been added with a specific redirect URL and ID tokens enabled:

app registration auth blade with web platform enabled

…and therein lies the crux of the matter. That configuration would be logical for a Web Application that would challenge and redirect users to login.microsoftonline.com if they would visit the site and click a login button. The built-in authentication would use the Authorization Code flow to authenticate the user. And that’s the reason for the added client secret as well. The Azure Function will use the Client Secret in the Authorization code flow to request an access token while redeeming an authorization code.

So in a sense this provisioned app registration / authentication setup can be used for securing both a Web Application and an API!

Azure will provision an app registration that can be used for both securing a Web Application as well as an API.

You could use an Azure Function to serve HTML, so as to work (kind of) as a website. But most people (me included), will probably just use it for API-stuff (or for webjob-stuff). So my Azure Function won’t redirect users to login.microsoftonline, it won’t allow them to be redirected back to the expected redirect URL. In fact, my Azure Function will not even request an Access Token. The calling application (In this scenario that’s SharePoint Framework) will request an Access Token for this Azure Function app and will send it along to the HttpTrigger. If no access token is sent, or it is incorrect or expired, the Azure Function will simply respond with a 403 Forbidden or 401 Unauthenticated HTTP response.

So we can effectively just clean this up to a more minimal setup that works for an API and not for a Web application!

So what you can do is the following:

  1. Remove the Web platform from the Authentication section of the App Registration.
  2. Remove the Client Secret from the Certificates & Secrets section of the App Registration.
  3. On the Azure Function configuration remove the MICROSOFT_PROVIDER_AUTHENTICATION_SECRET environment variable / app setting.
  4. Make sure you’ve configured the authentication settings of the Azure Function to return a 401 response on unauthenticated requests:

    configure auth settings 401 response

If you now edit the identity provider settings, you’ll notice that the fields for the Client Secret are empty. And that’s OK!

edit identity provider settings

And you’re done! The Authentication will keep working as expected, and you’ll make your IT Admin a bit happier!

Enabling built-in authentication on an Azure Function is a very simple and powerful feature. However, by default it will provision an app registration that can be used for both Web Applications as well as API’s. Cleaning that up to a more minimal setup is wise, to lessen the administrative burden and the impact of additional resources and costs.

🚀 I hope you enjoyed this post or learned something new! Happy coding! 🚀


auth azurefunction entraid
Support me by sharing this

More

More blogs

Calling Entra ID secured Azure Functions from Power Automate
Calling Entra ID secured Azure Functions from Power Automate

Can you call an Entra ID secured Azure Function from Power Automate? Yes you can, in several ways. This blog post describes one way to do it.

Read more
Using the on-behalf-of flow in Azure PowerShell Functions
Using the on-behalf-of flow in Azure PowerShell Functions

A step by step guide on how to use the on-behalf-of flow in Azure PowerShell Functions.

Read more
Working with Microsoft Teams PowerShell in Azure Automation
Working with Microsoft Teams PowerShell in Azure Automation

How to work with Microsoft Teams PowerShell and Managed Identity in Azure Automation

Read more

Thanks

Thanks for reading

Thanks for reading my blog, I hope you got what you came for. Blogs of others have been super important during my work. This site is me returning the favor. If you read anything you do not understand because I failed to clarify it enough, please drop me a post using my socials.


Warm regards,
Martin

Microsoft MVP | Microsoft 365 Architect

Microsoft MVP horizontal