There are two main ways to main ways to perform Server-to-Server (S2S) authentication: with a client id/client secret or with certificates. People most commonly use the client secret option as it is much easier to implement -- you create a new secret on the App Registration and you can use it. However, certificate-based authentication is generally considered to be more secure than using a client secret (which is effectively just a password). It seems that most people shy away from using certificates for authentication because of the perceived complexity in using them.
In this blog, I'll show that it is actually very easy to maintain self-signed certificates in an Azure Key Vault and use them to connect to Dynamics 365 through an Azure Function -- all with minimal configuration and code.
Configuration
In order to wire this up, we need to configure a few resources in Azure and Dynamics 365.
Azure Key Vault
This is where we will create and store the self-signed certificate. Alternatively, you could import a certificate you previously generated.
- Create a new Key Vault resource in Azure.
- Go to Certificates > Generate/Import
- Set the Certificate Name
- Set the Subject (can be anything)
- Click
Create
- After the certificate has generated, export it
- Download in CER format
- Copy the
Secret Identifierfrom the bottom of the page.
- Download in CER format
Azure Active Directory
We need to register a new application in Azure AD and configure the certificate on it. This is the application that our Azure Function will use to get a valid OAuth access token which is authorized to access Dynamics 365.
- Go to Azure Active Directory > App Registrations
- Click
New Registration- Give it a Name, you can leave the Redirect URI blank
- Copy the Application (client) ID value
- Click on
Certificates & secrets- Upload the .cer file you downloaded above
- Upload the .cer file you downloaded above
Dynamics 365
Next, we need to configure an Application User in Dynamics 365. This user is mapped to the Azure AD App Registration, and it is granted a security role which controls what the user can access. For more details on this, check out this link.
- Go to Settings > Security > Users
- Switch the view to
Application Users - Create a new User
- Switch to the
Application Userform - Populate the
Application IDwith theApplication IDfrom the App Registration
- Switch to the
- Assign a security role to the user
Azure Function
Finally, we deploy the Azure Function which will use the certificate from the Key Vault to connect to our Dynamics 365 environment. The Azure Function uses a system
- Deploy the Azure Function
- See the next section for the code
- Go to Platform Features > Identity
- Turn the System Assigned identity to
On
- Turn the System Assigned identity to
- Go back to the Azure Key Vault.
- Click on Access Policies > Add New
- Select the principal that matches the managed identity of the Azure Function (should have the same name)
- Grant it "Get" access for "Secret permissions"
- Click OK
- Go back to the Azure Function
- Open the Configuration/Application Settings
- Set the "Certificate" application setting, replacing URI with the Secret Identifier you copied above.
@Microsoft.KeyVault(SecretUri=https://bguidinger.vault.azure.net/secrets/CertificateName/VersionNumber)
Development
The code for the Azure Function can be found here.
As you can see, the Function code is very simple -- we don't need to wire up any code to pull the certificate from the Azure Key Vault. Instead, we we just pull the configuration values from the App Settings...which includes the Certificate setting value (which is the Base64 encoded certificate with the public and private key).
var certificateString = ConfigurationManager.AppSettings["Certificate"];var certificateBytes = Convert.FromBase64String(certificateString);var certificate = new X509Certificate2(certificateBytes, string.Empty, X509KeyStorageFlags.MachineKeySet);
Once we have the X509Certificate2 object, we can use it with the CrmServiceClient. Note that the second and third parameters (certificate store/thumbprint) are not required since we are directly passing the certificate in.
var client = new CrmServiceClient(certificate, StoreName.My, null, instanceUri, true, null, clientId, null, null);
Once we have the CrmServiceClient, we can check the IsReady parameter to make sure we connected successfully. If it's true then we're connected to CRM!
Testing
All that's left to do now is test the Function! To do this, we can open up Postman and execute an HTTP GET request to the Function URL (since it's an HTTP Triggered function).
So there you have it. An Azure Function that connects to Dynamics 365 using certificate-based authentication with minimal configuration and code! In the next blog, I'll show how, if you're using an App Service, you can use an Azure Managed Identity (both system-assigned and user-assigned) to make connecting to Dynamics 365 even easier.

Like
Report
*This post is locked for comments