web
You’re offline. This is a read only version of the page.
close
Skip to main content

Announcements

No record found.

News and Announcements icon
Community site session details

Community site session details

Session Id :
Dynamics 365 Community / Blogs / Securing Dynamics 365 / INTEGRATING ADAL JS WITH DY...

INTEGRATING ADAL JS WITH DYNAMICS 365

Vishal Saxena Profile Picture Vishal Saxena 12

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:

  1. 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.
  2. 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

1.png

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”.

2.png

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.

3.png

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

 4.png

2. In the Event Handlers, I have configured to call new_adalAuth to be called on Form load

5.png

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.

Comments

*This post is locked for comments

  • Varun Singh Profile Picture Varun Singh 943
    Posted at
    Hi Zhenyu Wang, I was facing same issue because of this line authContext.config.redirectUri = window.location.href.replace('form/ClientApiWrapper.aspx', dummyAuthPage); You need to change the redirect URI it as shown below: authContext.config.redirectUri = "https://{CRMURL}//WebResources/new_/auth.html"
  • Vishal Saxena Profile Picture Vishal Saxena 12
    Posted at

    Hi Zhenyu,

    var pageUrl = "https://crmXXXX.XXXX.dynamics.com";; is the URL of your Dynamics org.

    The error you are getting, can be resolved by specifying the return urls in your Azure Active Directory for the registered application

    Please let me know if you have any questions on this.

  • Zhenyu Wang Profile Picture Zhenyu Wang
    Posted at

    stuck on how to let user login, keeping tell me that reply url error

    anyone can help?

  • Zhenyu Wang Profile Picture Zhenyu Wang
    Posted at

    Hi Vishal,

    Could you please help explain more one this line.

    var pageUrl = "https://crmXXXX.XXXX.dynamics.com";; //The URL of this page in your development environment when debugging.

    Which url I should use here?

    Should this be something like, xxx.crm6.dynamics.com/.../daf_auth.html

    I am getting this error now

    AADSTS50011: The reply url specified in the request does not match the reply urls configured for the application:'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx'