Integrating Dynamics 365 with Azure Function using Managed Identity

March 20, 2019

I love Azure Functions. These days, I have to restrain the tendency to solve every problem with this Swiss army knife. 

When designing Azure Function integration with Dynamics 365, one of the immediate questions raised is where to store connection strings, credentials and other sensitive details. 
The immediate answer is ‘Not in your code’. So where?

One option is to store sensitive details in the Application Settings store which is ‘encrypted at rest and transmitted over an encrypted channel.’
While this option is  quite easy to use, it isn’t considered most secured.

One option is to store sensitive details in the Application Settings store

Another option is using Managed Identity with Azure Key Vault service.
With this option, Azure Function App is assigned an AAD identity, which is then authorized to access specific Key Vault secrets.
This option is considered more secured as the Function App is specifically granted access to  specific sensitive data, while Application Settings stored data is generally exposed.

In this post, I’ll walkthrough the process of setting and using Managed Identity to Integrate Azure Function with Dynamics 365. In this case, Dynamics 365 access details will be stored in Azure Key Vault.

For the walkthrough, I’ll use the Lead Landing Page scenario, replacing Flow component with Azure Function. Although a bit verbose, the process is quite simple.

Implementation Notes

  • Like most Azure services, Azure Key Vault usage costs money. With Azure Key Vault, any retrieval of secret is paid for. In order to reduce costs, some caching mechanism (which will not be discussed in this post) is in order.

Prerequisites

  1. Have accessible Microsoft Dynamics 365 instance
  2. Have access to Azure environment with sufficient privileges to create Azure Function and Key Vault store.

Walkthrough

  1. Register App with AAD

    Register a new Web App/API in Azure AD with a Client Secret and copy Application Id key and secret to Notepad.

  2. Add an App User to Dynamics 365

    Follow this article: Add a new Application User in Dynamics 365

  3. Create a Function App

    Create a Function App

    Set Function App details and click ‘Create’

    Set Function App details and click ‘Create’

    Add a new Function

    Add a new Function

    Select the HTTP trigger option

    Select the HTTP trigger option

    Click ‘Create’ to complete Function creation

    Click ‘Create’ to complete Function creation

    Leave the function code as is for now, we will alter it later on.

    Leave the function code as is for now, we will alter it later on.

  4. Assign Function App with a Managed Identity

    Go to the Function App Platform Features tab and click ‘Identity’

    Go to the Function App Platform Features tab and click ‘Identity’

    Click the ‘On’ button to assign a System identity and click ‘Save’

    Click the ‘On’ button to assign a System identity and click ‘Save’

    Click ‘Yes’ to enable system assigned managed indentity

    Click ‘Yes’ to enable system assigned managed indentity

    You can see the newly assigned identity object ID

    You can see the newly assigned identity object ID

  5. Setup Azure Key Vault store

    Create a new Azure Key Vault store

    Create a new Azure Key Vault store

    Click ‘Create’ at the bottom of the screen

    Click ‘Create’ at the bottom of the screen

    Click ‘Add new’ under the Access policies blade.
    In the Add access policy, check Get and List in the Key Management Operations group.
    Under the Principal blade, find and select your Function App. Click ‘Select’.
    This will grant our Function identity access to the Key Vault secrets.

    Click ‘Add new’ under the Access policies blade. In the Add access policy, check Get and List in the Key Management Operations group.

    Next, select a Resource Group for the Key Vault store. Click ‘Create’ to complete Azure Key Vault store creation

    Next, select a Resource Group for the Key Vault store

  6. Store secrets in Azure Key Vault

    Find the newly created Azure Key Vault store or access it from the dashboard if possible.

    Find the newly created Azure Key Vault store or access it from the dashboard if possible.

    Access the Secrets area

    Access the Secrets area

    Click Secrets and ‘Generate/import’ to generate a new secret

    Click ‘Generate/import’ to generate a new secret

    Set secret Name (select a self explanatory name, since once created, you won’t be able to see the actual secret value in the area).
    Set the secret string in the Value field. Click ‘Create’.
    In this case, the secret I defined is Dynamics Web API URL, similar to <a href="https://.api.crm.dynamics.com/api/data/v9.1/”>https://.api.crm.dynamics.com/api/data/v9.1/

    Set secret Name (select a meaningful name, as this will be used in our code). Set the secret string in the Value field

    In the same manner, add additional secrets to hold the applicationId and secret keys you copied after registering an app in AAD (step 1 in this walkthrough).

    In the same manner, add additional secrets to hold the applicationId and secret keys you copied after registering an app in AAD

    Click each of the newly created secrets and copy the Secret Identifier, which will be used in the code to access the secret value

    Click each of the newly created secrets and copy the Secret Identifier, which will be used in the code to access the secret value

  7. Update Azure Function Code

    Go back to the Function created on step 3 above.
    Click View Files, add a new project.json file and paste in the following definition. Click ‘Save’.

    {
        “frameworks”: {
            “net46”: {
                “dependencies”: {
                    “Microsoft.Azure.KeyVault”: “2.4.0-preview”,
                    “Microsoft.Azure.Services.AppAuthentication”: “1.1.0-preview”                
                }
            }
        }
    }

    image

    Go back to the function code and replace the existing code with the code found here (placed in Github for convenience).

    This code, triggered by an HTTP request from the Lead landing page, performs the following tasks:
    – Receives and parse Lead data
    – Extract Dynamics access details from Azure Key Vault
    – Use access details to generate an access token
    – Create a new Dynamics Lead record using Web API
    – Returns operation result to the caller

    In the GetDyn365AccessDetails method, replace the URLs for the three keys

    dyn365WebAPIURL, dyn365AppIdKVURL, dyn365secretKVURL with the URLs copied on step 6.
    Click ‘Save’.

    Click ‘Get Function URL’ and paste somewhere, as it will be used next

    Click ‘Get Function URL’ and paste somewhere, as it will be used next

  8. Hookup Lead Landing Page to Azure Function

    Last, create a new HTML page, and copy the HTML found here (placed in Github for convenience).
    Find the AzureFunctionRequestURL variable and replace its value with the Azure Function URL copied in the previous step. Save.

    Find the AzureFunctionRequestURL variable and replace its value with the Azure Function URL copied in the previous step

  9. Test

    To test the solution, run the Lead Landing HTML page. Submitting Lead data should results with a new Lead record in Dynamics 365.

    To test the whole flow, run the Lead Landing HTML page

    Submitting Lead data should results with a new Lead record in Dynamics 365.

    If the flow fails, add the address from which the HTML page is executed to the Azure Function CORS collection to authorize it.

    If the flow fails, add the address from which the HTML page is executed to the Azure Function CORS collection to authorize it.

    If the flow fails, add the address from which the HTML page is executed to the Azure Function CORS collection to authorize it.

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*