0

I am putting together an api integration with Dynamics CRM on premise (v8.1/8.2), on a IFD, using the password grant type.

I am retrieving an access token successfully, however when I then try to call endpoints (e.g /api/data/v8.2/contacts?$select=fullname,contactid ) I get 401 - access denied errors. When I log into the CRM with the user I can successfully view this data and the error occurs on all tested endpoints.

Interestingly this morning I realised the tokens retrieved cannot be base64 decoded - is that correct?

I could use some ideas on what to look at next to resolve the problem. Steps I've taken:

  • Triple checking the initial token request
  • Triple checked the Service Root URL
  • Tried on two CRM/Azure setups
  • Tried with my own (node) code and internet examples
  • A wide variety of token setups
  • Confirmed the user exists in Azure and the CRM
  • Confirmed user has sufficient permissions
  • Confirmed the application on Azure has all dynamics permissions granted
  • Confirmed I am on the same network as Azure and the CRM

It seems apparent that I have a configuration issue somewhere in Azure or the CRM. However no guide or question I can find suggests looking at problems I haven't already checked for and I could really use some input from those who have had to make adjustments in obscure settings ect.

Heres my token request:

var options = {
    method: 'POST',
    url: 'https://login.microsoftonline.com/<snip>/oauth2/token', //for 'intercity technology' (guid is unique)
    headers:
        {
            'cache-control': 'no-cache',
            'content-type': 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' },
    formData:
        {
            grant_type: 'password',
            client_id: ‘<snip>’, //aplication id
            client_secret: ‘<snip>’, //any key in the keys list
            username: ‘<snip>’,
            password: ‘<snip>’, // and their password
            resource: ‘<snip>’ //application id

        }
};


   logger.debug(util.inspect(options));

    request(options, function (error, response, body) {
...

Heres my current api request test:

 var options = {
            method: 'GET',
            url: organisation_url + '/api/data/v8.2/contacts?$select=fullname,contactid',
            headers: {
                Authorization: 'Bearer '+token,
                Accept: 'application/json',
                'OData-MaxVersion':4.0,
                'OData-Version': 4.0,
                'Content-Type': 'application/json; charset=utf-8',
                'Prefer': 'odata.maxpagesize=500',
                'Prefer': 'odata.include-annotations=OData.Community.Display.V1.FormattedValue'
            }
            };
            logger.debug(util.inspect(options));

            request(options, function (error, response, body) {
...
tracer tong
  • 535
  • 5
  • 15
  • Interestingly, I just found https://stackoverflow.com/questions/45467317/authorize-webapp-to-adfs-in-order-to-access-dynamics-crm-web-api Which is very similar to my situation. Can anyone tell me what a system user refers to in this context, (At the top of the accepted answer). – tracer tong Nov 14 '17 at 13:40

1 Answers1

1

You'll need to use a grant type of 'client_credentials' instead of 'password' as the later isn't supported. Something like:

 grant_type: 'client_credentials',
 client_id: ‘<snip>’, //aplication id
 client_secret: ‘<snip>’, //any key in the keys list
 resource: ‘<snip>’ //CRM Url

Follow the guide here and all the links to ensure the AAD application is registered correctly and the CRM application user is in place.

Jason Lattimer
  • 2,847
  • 13
  • 14
  • Thats not going to work for me, the version of dynamics I'm working with doesn't support application users (I believe they were taken out in the 2016 release) – tracer tong Nov 14 '17 at 15:50
  • Correction - this isn't going to work for me because application users only exist on the cloud version of dynamics and not on premise – tracer tong Nov 14 '17 at 16:41