PowerObjects Blog 

for Microsoft Business Applications


Authentication to Dynamics 365 using Azure Function v3 (.NET core)

Post Author: Robert Thompson |

There are not many examples of trying to use Azure Function v3 (.NET core) to access Dynamics 365. If you find yourself trying to convert the Azure Function v1 (.NET Framework) to v3 (.NET core), you will be better off creating a new Azure Function.

And if you’re trying to access Dataverse using the same libraries to access Dataverse in v3 (.NET core) that you were using in v1 (.NET Framework), this could be your chance. The goal of this blogpost is to help with resolving a few issues that are not clearly explained.

This article assumes that you have created Azure Functions or are familiar with an Azure Function in Visual Studio 2019, using WebHook and Azure Key Default. If not, here are a few links to review.

This is a great resource from Microsoft: Create a function in Azure using Visual Studio 2019.

This is a helpful blog on WebHook.

Another great resource from Microsoft: Key Default.

The following information will be covered.

  1. Creating an Azure Function v3 (.NET core) in Visual Studio 2019
  2. What NuGets are needed for the solution
  3. Adding Microsoft.Platform.Cds libraries NuGets
  4. Using Key Default config string or manually adding config string

Creating Azure Function v3 (.NET core) in Visual Studio 2019

After selecting “creating the new project” and then selecting the Azure Function template, you will be prompted with the following.

Make sure to select Azure Function v3 (.NET Core) function; then select Http Trigger.

By selecting Http Trigger, this will be fired when a create or change is made on a Dynamic 365 Dataverse record. C# code will be created based on the Azure Function being created.

If this is a new Azure Function, we may need to start adding NuGets that may not exist.

Adding NuGets

Once the solution/project has been created, we will need to add the following NuGets.

To get the following 2 NuGets and to get more information on the NuGets, go here: Microsoft.Platform.Cds.

  1. Microsoft.Powerform.Cds.Client
  2. Microsoft.Powerform.Cds.Client.Dynamics

Visual Studio 2019 > Tools > Package Manager Console

Now let’s start connecting to Dataverse environment.

Before we begin showing code on how to connect to Dataverse environment, let’s review logic that will not work using v3 (.NET Framework). This logic will not work in v3 (.NET Framework) when trying to access Dataverse environment:

using Microsoft.Xrm.Tooling.Connector;

CrmServiceClient crmConn = new CrmServiceClient(System.Environment.GetEnvironmentVariable("CRM_CONNECTION_STRING"));

Now let us connect to Dataverse environment. We’ll show 2 different ways to target the connection string that will be used to access the Dataverse environment.

As you may already now, we will need to create an App Registration. Once that been created, we will need to get the following information in order to create a connection string. (Please note there are other ways to get the connection string.)

  1. Build the manual connection string.

We will need to get the client and tenant ID and create a secret key.

  1. Using Key Vaults to get the connection string (Azure.Security.KeyVault.Sercets client library)

We can store the manual connection string within the secret value.

This is how to build the manual connection string. This is a good way for testing the connection string.

  var clientId = FROM APP REGISTRATIONS (CLIENT ID)

            var clientSecret = FROM APP REGISTRATIONS CERTIFCATES & SECRETS

            var organizationUrl = "https://organizationURL.crm.dynamics.com/";

            var tenantId = FROM APP REGISTRATIONS (TENANT ID)

            string conString = "Url=" + organizationUrl + "; " +

                   "AuthType=ClientSecret; " +

                   "ClientId= " + clientId + "; " +

                   "ClientSecret=" + clientSecret + "; " +

                   "RequireNewInstance=false; " +

                   "SkipDiscovery=true";

Using the Key Vault is good for the production environment for securing the connect string. We will be using a client library called Azure.Security.KeyVault.Sercets. This library with help with getting the connection string from secret value in the key Vault.

using Azure.Security.KeyValut.Secrets

            const string secretName = "CONNECT-CRM"; 
            var kvUri = "https://KEY-VAULT-NAME.vault.azure.net/";
            var client = new SecretClient(new Uri(kvUri), new DefaultAzureCredential());
            var secret = await client.GetSecretAsync(secretName);
            string connectionString = secret.Value.Value;

Now let us put everything together. Once all the NuGets have been installed we can now connect to Dataverse using the following code.

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Microsoft.Extensions.Configuration;
using System.Net.Http;
using Microsoft.PowerPlatform.Cds.Client;
using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk;
using Azure.Security.KeyVault.Secrets;
using Azure.Identity;

namespace AuzreFunctionPlugin
{
    public static class AuzreFunctionPlugin
    {
        [FunctionName("AuzreFunctionPlugin")]

        public static async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log)
        {   
            log.LogInformation("C# HTTP trigger function processed a request.");

            //Build the connection string
            var clientId = FROM APP REGISTRATIONS
            var clientSecret = FROM APP REGISTRATIONS CERTIFCATES & SECRETS
            var organizationUrl = "https://organizationURL.crm.dynamics.com/";
            var tenantId = FROM APP REGISTRATIONS
            string connectionString = "Url=" + organizationUrl + "; " +
                   "AuthType=ClientSecret; " +
                   "ClientId= " + clientId + "; " +
                   "ClientSecret=" + clientSecret + "; " +
                   "RequireNewInstance=false; " +
                   "SkipDiscovery=true";

            // Use Key Vault
            const string secretName = "CONNECT-CRM"; 
            var kvUri = "https://KEY-VAULT-NAME.vault.azure.net/";
            var client = new SecretClient(new Uri(kvUri), new DefaultAzureCredential());

            var secret = await client.GetSecretAsync(secretName);
            //string connectionString = secret.Value.Value;

            CdsServiceClient dataVerseConnection = new CdsServiceClient(connectionString);

            if (!dataVerseConnection.IsReady)
           {
                throw new Exception("Authentication Failed!");
           }
            
            ColumnSet attributes = new ColumnSet(new string[] { "name", "address1_line1”, “address1_line2” });
            Entity accountEntity = dataVerseConnection.Retrieve("account", new Guid(GUID_ACCOUNT), attributes);

Just something to note: you may need to use an older version on the NuGet Microsoft.IdentityModel.Clients.ActiveDirectory. There are issue with using the 5.2.8 version.

If you have a good understanding on how Azure Functions work and trying to connect to Dataverse, this will help you get there.

Thanks for taking the time to read this article.

Joe CRM
By Joe D365
Joe D365 is a Microsoft Dynamics 365 superhero who runs on pure Dynamics adrenaline. As the face of PowerObjects, Joe D365’s mission is to reveal innovative ways to use Dynamics 365 and bring the application to more businesses and organizations around the world.

Leave a Reply

Your email address will not be published. Required fields are marked *

PowerObjects Recommends