Microsoft Dynamics 365

Learn how to integrate your Microsoft Dynamics instance with Strivacity, allowing Strivacity to add, update and maintain customer information and use it as a source of entitlement.

Integrating Strivacity with Microsoft Dynamics provides the following benefits:

  • Use Microsoft Dynamics customer information as a source of entitlement during customer registration, login, or any step within the customer account lifecycle
  • Create new customer records, and synchronize/update those customer records with the latest customer account information (from Strivacity)
  • If required, migrate customer information from Microsoft Dynamics to Strivacity upon account registration

They're two steps to setting up Strivacity with Microsoft Dynamics 365:

1) Setup Microsoft Power Platform to register Strivacity as an Application and define API permissions for the application, and enable public client access

2) Setup a pre-registration hook within Strivacity

1) Setup Microsoft Power Platform to register Strivacity as an Application

1) From within the Azure Active Directory Dashboard, click on App registrations, and click + New registration

2) Define a name for your new application

3) Choose Accounts in any organizational directory (Any Azure AD directory - Multitenant)

4) Click the Register button. Your newly created application should be registered as shown in the screenshot below.


Make a record of the ClientID so that you can use it at a later stage of the integration.

5) Next, click on Certificates and Secrets

6) Click on New client secret and copy it to a safe location for use later in this integration. Note you will not be able to copy the secret again later

7) Next, click on API permissions, and then Add a permission

8) Select Dynamics CRM as shown below:

9) Next, search for “user_impersonation”, and then click add permissions as shown below:

10) Now click on Manifest, and set allowPublicClient to true, as shown highlighted below:

This completes the initial configuration within Microsoft Dynamics 365 for use with Strivacity.

2) Setup a pre-registration hook within Strivacity

1) Log into the Strivacity Admin Console using an Admin role, or a role that has delegated access to create a Lifecycle Event Hook.

Using the pre-registration hook code below, do the following:


This will search Microsoft Dynamics 365 for a contact matching the primary email address

Now add any additional logic as you see fit!

var dynamics = require('dynamics-web-api');
var AuthenticationContext = require('adal-node').AuthenticationContext;

// dynamics config

// get an adal context for use in auth
var adalContext = new AuthenticationContext(DYNAMICS_AUTHORITY_URL);

/** This function will be called from the Pre registration hook in a blocking manner.
 * @param {Object}   args                                         Input arguments
 * @param {Object}   args.application                             Application related information
 * @param {string}                        Name
 * @param {string}   args.application.client_id                   OAuth client ID
 * @param {Object}   args.oidc_context                            Information about the originating OpenID Connect request
 * @param {string[]} args.oidc_context.acr_values                 ACR values
 * @param {string[]} args.oidc_context.ui_locales                 UI locales
 * @param {Object}   args.customer                                Customer related information
 * @param {string}   args.customer.ip_address                     HTTP client IP coming from the X-Forwarded-For header
 * @param {string}                          Userstore
 * @param {Object}   args.customer.attributes                     User attributes provided during the registration
 * @param {Object}   args.customer.identifiers                    User identifiers provided during the registration
 * @param {Object[]} args.customer.consents                       User consents accepted during the registration
 * @param {string}                  City of the customer
 * @param {string}   args.customer.location.state                 State of the customer
 * @param {string}               Country of the customer
 * @param {string}   args.customer.location.country_code          Country code of the customer
 * @param {string}   args.customer.location.coordinates.latitude  Latitude coordinate of the customer
 * @param {string}   args.customer.location.coordinates.longitude Longitude coordinate of the customer
 * @param {Object}   args.session                                 Session store
 * @param {Object}   args.continue_context                        Continue context
 * @param {Object}   args.continue_request_parameters               Continue request parameters
 * @param {string}   args.continue_request_parameters.callback_url  Callback url to use after a continue call
 * @param {string}   args.continue_request_parameters.state         State parameter to use after a continue call
 * @param {preRegistrationCallback} callback
 * @param {denyRequestCallback} error
module.exports = async function ({ application, oidc_context, customer, session, continue_context, continue_request_parameters }, callback, error) {
    var client = new dynamics({
        webApiUrl: DYNAMICS_RESOURCE + 'api/data/v9.1/',
        onTokenRefresh: acquireToken

    var records = await client.retrieveMultiple("contacts", ["fullname"], `emailaddress1 eq '${customer.attributes.emails.primaryEmail}'`)

    // the following function call does not modify the registering user
    callback(new RegistrationData(customer.attributes, [], session));

 * Callback for acquiring a token via ADAL
function acquireToken(callback) {
    function adalcb(error, token) {
        if (!error) {
        } else {
            throw new Error(error)

    // get the token
    adalContext.acquireTokenWithClientCredentials(DYNAMICS_RESOURCE, DYNAMICS_CLIENT_ID, DYNAMICS_CLIENT_SECRET, adalcb);

/** Allow registration
 * @callback preRegistrationCallback
 * @param {RegistrationData|RedirectRequest|ShowErrorMessage} token

/** Deny registration
 * @callback denyRequestCallback
 * @param {ErrorDenyRequest} error

/** RegistrationData */
class RegistrationData {
    attributes = {}
    additionalAuthenticators = []
    session = {}

     * @constructor
     * @param {Object} attributes
     * @param {AdditionalAuthenticator[]} additionalAuthenticators
     * @param {Object} session
    constructor(attributes, additionalAuthenticators, session) {
        this.attributes = attributes;
        this.additionalAuthenticators = additionalAuthenticators;
        this.session = session;

/** AdditionalAuthenticator */
class AdditionalAuthenticator {
    type = null;
    target = null;

     * @constructor
     * @param {"email"|"phone"} type
     * @param {string} target
    constructor(type, target) {
        this.type = type; = target;

/** RedirectRequest is a global object
 * @constructor
 * @param {string} redirect_url
 * @param {Object} session

/** ShowErrorMessage is a global object
 * @constructor
 * @param {string} error_message
 * @param {Object} session

/** ErrorDenyRequest is a global object
 * @constructor
 * @param {string} description
 * @param {string} hint