Customer Engagement & Dynamics CRM Forum

Expand all | Collapse all

Externally accessing Web API using only JavaScript

  • 1.  Externally accessing Web API using only JavaScript

    SILVER CONTRIBUTOR
    Posted Feb 07, 2019 10:58 AM
    Hello,

    I've been researching if it is possible to query the Dynamics CRM (online) from an external website using only JavaScript and a service account.  I'm aware of and successfully built the OAuth version where I'm prompted for login credentials but I would like to avoid the login prompt and pass the credentials "silently", if possible.  I have combed through all of the Microsoft documentation online and I am not interested in the C# use cases. Can this be done?

    Thank you,

    Bob




    ------------------------------
    Robert Chang
    CRM Application Developer
    Cystic Fibrosis Foundation
    Bethesda MD
    ------------------------------


  • 2.  RE: Externally accessing Web API using only JavaScript

    TOP CONTRIBUTOR
    Posted Feb 07, 2019 10:45 PM
    Robert,
        Your requirement is a bit vague. My apologies for the following rant. I hope I don't come off too strong, and my apologies if I misunderstood your request. What it sounds like is you want the ability for a web site to serve a web page to a user's browser, and that page will contain service account credentials so that their browser can make direct API calls into your CRM system?

    If (my above summary is not correct), then {stop reading && please clarify}. else...{continue reading};

    Yes it is possible and I can help you....by giving you a bunch of reasons you should not do it.

    This is extraordinarily bad idea for the following reasons:
    Given that your API URL, service account user name and password would have to be in plain text (or easily decrypted) in the end user's browser to implement the above requirement.

    1. An attacker would be able to bypass your primary line of defense - the login.
    2. The attacker will have access to ALL the possible API calls in your CRM system. They can set up automated bot networks to hammer your endpoint to find a weakness or cause a denial of service (DoS), in which case your CRM system will go down. This is a massive "attack surface" you are opening up. The best way to mitigate this problem is to set up a facade web service (such as Azure Functions or Logic App) between the browser and D365. 
    3. There is no way to monitor and respond if an attack is launched at your API. You will have no useful information about the source of the attack or whether information was leaked. Therefore you may have to notify all your members that their information may have been compromised.
    4. There are over 1000 different security settings in a single security role for an OOTB system. Do you have the ability to run exhaustive penetration testing on every possible security setting in CRM? It is highly likely that someone will change the security on your service account in the future without you knowing it, and you will be exposing unintended data. Hackers are testing your public endpoints 24x7 for possible change in configuration so they can see if they can exploit it.
    5. If…no…WHEN you have a security problem in the future (even if it is not due to this configuration) then you will be audited, and this configuration will stand out as a demonstration of poor security practices.
    6. You would be violating the MS Service Agreement section 4.a.i where it says you "cannot transfer your Microsoft account credentials to another user or entity"
    Give me a call. Lets to go lunch. I work in Bethesda. I can help you get what you need without taking unnecessary risks.

    ------------------------------
    Nelson Johnson
    Solution Architect
    BroadPoint, Inc.
    Bethesda MD
    Link with me! https://www.linkedin.com/in/nelsonjohnson/
    ------------------------------



  • 3.  RE: Externally accessing Web API using only JavaScript

    SILVER CONTRIBUTOR
    Posted Feb 08, 2019 04:31 AM
    Hi,

    I basically agree with all of the above, but trying to work the problem I have come with as follows:

    The problem you have is that as the JavaScript will be running within another application (I am assuming, and it's not running in some NodeJS app on a server somewhere) then you've got the issue that any credentials that the client uses to access Dynamics (whether directly or via proxy) are going to be available through debugging tools etc in the client. Even if they're encrypted then by design the code to decrypt them also must be on the client.

    So you need to work a way of locking it down. If the website isn't public then in theory you could restrict the IP address range of where the requests could come from. You cannot do this directly within Dynamics 365, but the easiest way is to have Azure Key Vault give you some client credentials (which isn't violation of your service agreement) and continually rotate them. You would then put restrictions on the key vault to say it could only be accessed by certain IP address ranges or virtual networks. This isn't 100% safe, as the credentials would still be made available to the client's browser, but if they were extracted they would quickly be useless, and I think the log analytics would log which credentials were handed out to which client IP. If your website is public, then obviously this doesn't work.

    But as detailed above the most secure way is to do this server side. Create a certificate, upload the public key to Azure and install that on all the servers you need to access D365 from. Then you can use any client library you like to access Dynamics and you know it's going to be OK. That way even if the certificate thumbprint is compromised (i.e. someone rogue goes into Azure and publishes it to the world) then they don't have all the information they need to authenticate, they would still need the certificate.

    So yeah, it can be done, and you can make it safer than just putting logon credentials in logon.js, but still not a particularly good idea.




    ------------------------------
    Ben Bartle
    IBM
    ------------------------------



  • 4.  RE: Externally accessing Web API using only JavaScript

    SILVER CONTRIBUTOR
    Posted Feb 08, 2019 10:02 AM
    Nelson,

    Thanks again for responding!  You've been the first to reply to my last couple posts.  No offense taken at all.  I agree, this would be career ending if I planned to implement such as solution so let me clarify.

    A vendor of ours is being ask to build a web site that we think we plan to have Dynamics CRM as the data store.  I'm well aware of Adxstudio and have a good amount of experience customizing it but it's just not a good fit for many reasons that I won't go into here.  The vendor proposed that we or "me" build a microservice layer to act as the bridge between Dynamics CRM and the web site. Contacts, Accounts, and various custom entity data would go back and forth through this microservice API for registration, profile, email subscriptions, etc.  To complicate things a little more, we have an identity portal/SSO already in place elsewhere that we would like to leverage for this project but it may be omitted in this first phase.

    Based on their proposal, I believe the vendor wants to avoid using(learning) the SDK to interface with the CRM.  While the microservice layer would be built using the SDK/Xrm Tooling, I found the article on Server-to-Server (S2S) authentication but that seemed to require C#.  I wanted to see if there was a way the website could bypass a microservice and go to Dynamics CRM directly without C#.  The OAuth samples worked well but that's not what we really need.

    Thanks again for advice!

    A call and or lunch sounds great, I'll reach out soon.

    Regards,

    Bob


    ------------------------------
    Robert Chang
    CRM Application Developer
    Cystic Fibrosis Foundation
    Bethesda MD
    ------------------------------



  • 5.  RE: Externally accessing Web API using only JavaScript

    TOP CONTRIBUTOR
    Posted Feb 08, 2019 07:12 AM
    Robert

    Yes, you can do that. I had a similar requirement where we have a secure connection and therefore "don't need" the credentials.

    I wrote a webapi using nodeJS and express that appends the necessary credentials to access crm.

    Essentially

    1. User goes to http://myNodeService/api/data/v9.0/accounts?$select=name&$top=3 HTTP/1.1 
    2. myNodeService authenticates itself
    3. myNodeService goes to Crm and pass the url parameter api/data/v9.0/accounts?$select=name&$top=3 HTTP/1.1 
    4. myNodeService returns results to user
    Cheers!

    ------------------------------
    Rex Kenley Tan, MCP
    Akron OH
    https://www.youracclaim.com/users/rex-kenley-tan

    *Always be CURRENT with JavaScript & C#, NEVER be obsolete.

    DISCLAIMER: All views expressed on this site are my own and DO NOT represent the opinions of ANY entity whatsoever with which I have been, am now, or will be affiliated.
    ------------------------------



  • 6.  RE: Externally accessing Web API using only JavaScript

    Posted Feb 08, 2019 03:08 PM
    Hi Rex,

    Can you elaborate on #2?

    Is this just to say you store the credentials on the server where your nodeJS site is running?
    Thanks


    ------------------------------
    scott farriss
    Source LLC
    temple terrace FL
    ------------------------------



  • 7.  RE: Externally accessing Web API using only JavaScript

    TOP CONTRIBUTOR
    Posted Feb 08, 2019 03:21 PM
    Scott

    That is correct.

    Dynamics 365 and Node.js integration using the Web API
    Dynamics 365 and Node.js integration using the Web API - part 2
    AleksandrRogov/DynamicsWebApi
    Dynamics 365 v.9 WebAPI - authentication examples in nodeJS

    Cheers!

    ------------------------------
    Rex Kenley Tan, MCP
    Akron OH
    https://www.youracclaim.com/users/rex-kenley-tan

    *Always be CURRENT with JavaScript & C#, NEVER be obsolete.

    DISCLAIMER: All views expressed on this site are my own and DO NOT represent the opinions of ANY entity whatsoever with which I have been, am now, or will be affiliated.
    ------------------------------



  • 8.  RE: Externally accessing Web API using only JavaScript

    Posted Feb 08, 2019 05:25 PM
    Hi,

    We use PHP web pages to connect directly to Dynamics CRM. In some cases our contacts authenticate via AD and then we use a service account to connect to CRM, in other cases the contacts don't need to authenticate, e.g., FAQ site that used the CRM KB articles. Apologies, I don't have the technical knowledge to delve any deeper, I can put you in contact with my colleague who developed it if you need some help. He did a lot of research on the API before he could get it to work the way he wanted, he is also very security conscious.

    One thing I would say is to make sure to put enough error handling in your code to capture and handle all sorts of eventualities, e.g., when the API fails to connect, or the API returns empty {} braces with no data but no error is thrown etc. I have a post on here from this week where our API went AWOL for 24 hours. As above, the API was throwing no error but returning empty {} braces. We had no errors on the client side and no errors on CRM (MS checked), we suspect that something happened further up the stack in Azure as all our instances were returning the same thing. Coupled with this, we have an adx portal that I assume uses the Web API that was hosted on Azure, that remained working. We don't have premier support with MS so we couldn't get an RCA report, instead we had to add a lot of error checking on the client side to build resilience.

    Regards,
    Kevin

    ------------------------------
    Kevin Harrington
    CRM Product Manager

    ------------------------------



  • 9.  RE: Externally accessing Web API using only JavaScript

    SILVER CONTRIBUTOR
    Posted Feb 11, 2019 11:14 AM
    Kevin,

    Thanks for responding!  I'll keep the PHP option in mind.

    Regards,

    Bob



    ------------------------------
    Robert Chang
    CRM Application Developer
    Cystic Fibrosis Foundation
    Bethesda MD
    ------------------------------



If you've found this thread useful, dive deeper into User Group community content by role