Why should you read this article?
You might have encountered cases when you need to call azure services from Dynamics, in those cases the options you have are:
- Call the service (Azure API/ Azure function/ etc) through ajax wherein the keys are sent as part of the header itself, here an attacker can directly change the query parameter or post body and easy achieve a horizontal/ vertical privilege escalation.
- Call the service through plugins, but in this case as well the application loses the context of the user and the call to the Azure service is made by the application where the user identity has to be passed either in query string or in post body, but since the user identity can be easily tampered, this approach is better than the first but not quite as secure.
So this article will help you understand how you can integrate ADAL JS in Dynamics pages so that you can call Azure services without leaking the key or loosing the user context.
Steps to integrate ADAL JS with Dynamics 365?
Step 1: Navigate to Settings -> Customize the System
Step2: Select Web Resources under the component and click on “New”. Fill the required fields, select “Type” as “Webpage(HTML)”. Click on Text editor and just write “Dummy Page”.
Step 3: Select Web Resources under the component and click on “New”. Fill the required fields, select “Type” as “Script(JScript)” and in the upload file section upload the adaljs script which can be downloaded from their GitHub repo.
Step 4: In the web resources add another file by clicking on “New”. Fill the required fields, select “Type” as “Script(JScript)”. Click on the Text Editor and paste the below code after making the required changes as per your environment
"use strict";
// Function that manages authentication
function authenticate() {
//Set these variables to match your environment
var organizationURI = "https://crmXXXX.XXXX.dynamics.com"; //The URL to connect to CRM (online)
var tenant = "XXXX.onmicrosoft.com"; //The name of the Azure AD organization you use
var clientId = "XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXX"; //The ClientId you got when you registered the application
var pageUrl = "https://crmXXXX.XXXX.dynamics.com"; //The URL of this page in your development environment when debugging.
var user, authContext, message, errorMessage, loginButton, logoutButton, getAccountsButton, accountsTable, accountsTableBody;
//Configuration data for AuthenticationContext
var endpoints = {
orgUri: organizationURI
};
var config = {
tenant: tenant,
clientId: clientId,
postLogoutRedirectUri: pageUrl,
endpoints: endpoints,
popup: true,
cacheLocation: 'localStorage', // enable this for IE, as sessionStorage does not work for localhost.
};
//OAuth context
authContext = new AuthenticationContext(config);
var dummyAuthPage = '/WebResources/new_auth.html';
var getUser = function () {
return new Promise(function (resolve, reject) {
// If the user is cached, resolve the promise immediately.
var user = authContext.getCachedUser();
if (user) {
resolve(user);
return;
}
// The user was not cached. Open a popup window which
// performs the OAuth login process, then signals
// the result.
authContext.config.displayCall = function (url) {
authContext.config.displayCall = null;
var popup = window.open(url, 'auth-popup', 'width=800,height=500');
var intervalId = window.setInterval(function () {
try {
if (popup.location.pathname.indexOf('/' + dummyAuthPage) >= 0) {
window.clearInterval(intervalId);
authContext.handleWindowCallback(popup.location.hash);
popup.close();
var user = authContext.getCachedUser();
if (user) {
resolve(user);
} else {
reject(authContext.getLoginError());
}
}
} catch (whatever) {
if (popup.closed) {
reject();
}
}
}, 100);
};
authContext.config.redirectUri = window.location.href.replace('form/ClientApiWrapper.aspx', dummyAuthPage); //This code is added to handle the ClientApiWrapper added by Dynamics so that the request is redirected to correct page
authContext.login();
});
};
getUser();
}
Final Step: Now that you have all your JS and HTML prepared all need to do is to call them on any page where you intend to call Azure Services using ADAL JS. For my case I have configured my Accounts page to load these scripts onload and get the user JWT token from Azure AD which would then be used to call Azure Functions.
1. Add the Adal JS script in Form Libraries
2. In the Event Handlers, I have configured to call new_adalAuth to be called on Form load
And there you go, now you have fully functioning ADAL JS with Dynamics 365. Thanks to the Anders Fjeldstad’s comment here which helped me figure out this whole integration.

Like
Report
*This post is locked for comments