Azure Functions with Dataverse provide a potent combination in terms of extending business logic and functionality. As a result, it has become the go-to solution for many scenarios.
While it can be straightforward to write or develop a new Azure Function, and subsequently deploy your function quickly and easily using the many streamlined tools that Microsoft provides, security can often get overlooked or is only considered as an afterthought.
In this article, we will discuss an HTTP-triggered Azure Function and how to make an authenticated call from Dataverse. However, first let’s review what we get out of the box with Dataverse.
When we create a new HTTP-triggered Azure Function, it provides us Function level code as an authentication key. Dataverse supports extending by configuring a webhook that uses the authentication code to call it. For reference (Write an Azure Function that processes Dataverse events – Learn | Microsoft Docs)
Since this is configured server-side, it may be okay in some scenarios, but what if we want to call this from the client– side? For example, we could add a button or onLoad call to trigger or invoke logic via the Azure Function that would trigger directly from a client side application such as a model-driven app in dataverse or a customer web application. We wouldn’t want to expose the code or function key on the client-side and be accessible or visible in the debugger tools.
Enter MSAL.js
The Microsoft Authentication Library for JavaScript (MSAL.js), allows us to implement implicit flow or authorization code flow to authenticate the calling user and make a secure call to the Azure Function.
For this example, we will use authorization code flow.
Azure Function Setup:
First, let us get our HTTP-triggered Azure Function ready.
I will publish this to Azure from Visual Studio, accepting the defaults.
After publishing, I have added Dataverse URL to the CORS exception for my Azure Function.
Authentication:
After publishing it to Azure, I will enable authentication on it. I have used express setup and accepted the defaults. As part of the app registration, it automatically exposes the API via a scope (user_impersonation). The scope will be used when creating the App Registration to represent a SPA (read Dataverse).
App Registration for Dataverse:
We will create an App Registration that will have permissions to call this Azure Function.
API Permissions:
Here we will add the dataversefuncapi user_impersonation scope under the API permissions.
MSAL.js Configuration:
We will use MSAL.js 2.0 (microsoft-authentication-library-for-js/lib/msal-browser at dev · AzureAD/microsoft-authentication-library-for-js (github.com)). I have downloaded the msal-browser.min.js file from the CDN and uploaded it as a WebResource in Dataverse. As of July 2021, the latest version available is 2.15.0.
Here is the MSAL.js configuration.
All the information shown above is extracted from the dataversefunc-client app registration.
To configure this in Dataverse, I have added the function onLoad of the Account form:
Now, if I go to my account form, it will automatically authenticate the logged-in user. In this case, it is my user, and it will get the token and call the Azure Function securely.
Conclusion:
With a few clicks and configuration, we just saw how easy it is to secure an HTTP-triggered Azure Function and consume it securely from Dataverse. If you have any questions, queries, or insights, please reach out to us! We will be happy to help!