2

I am trying to use PHP and CURL to connect to Microsoft Dynamics API so I can read client data from the CRM. The API guide can be found here: https://msdn.microsoft.com/en-gb/library/mt593051.aspx

I've been into the Azure portal and set up a new application, and it gives me the credentials to use (client id, secret, etc.) and the url end points. Using these credentials I am able to successfully connect to the CRM and retrieve a bearer access token, but I am unable to get any further.

When I attempt to use the token to return data I receive the below error message:

HTTP Error 401 - Unauthorized: Access is denied

My assumption would be that I must be passing the token correctly?

My code is below.

<?php
// Step 1 - Use the credentials supplied by CRM to get an access token (this bit works okay)
$credentials = array(
    'grant_type'=>'client_credentials',
    'username'=>'xxxxxxxx',
    'password'=>'xxxxxxxx',
    'client_id'=>'xxxxxxxxxxxx',
    'client_secret'=>'xxxxxxxxxx',
    );
$urlSafeCredentials = http_build_query($credentials);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,'https://login.microsoftonline.com/xxxxxxxxxxxxxx/oauth2/token');
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $urlSafeCredentials);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded')); 
$response = curl_exec($ch);
$result = json_decode($response);
curl_close($ch);


// A BEARER access token is successfully returned
$token = $result->access_token;


// Step 2 - Use the access token to request data from the CRM (this bit fails with HTTP Error 401 - Unauthorized: Access is denied)

$ch = curl_init('https://clientspecificurl.crm4.dynamics.com/api/data/v8.1/accounts');
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json', 'Content-Type: application/x-www-form-urlencoded','Authorization: Bearer '.$token)); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
curl_close($ch);
print_r($response); // 401 Unauthorized ?!
?>  

As far as I can tell there is nothing else to configure at the back end, any help would be much appreciated.

2 Answers2

0

Based on the parameters to acquire the token, you were mixing the client credentials flow and resource owner password flow and lack of resource parameter.

The client credentials flow requires parameters grant_type,client_id,client_secret,resource and the value of grant_type is client_credentials.

The resource owner password credentials flow requires grant_type,client_id,client_secret,username,password,resource and the value of grant_type is password.

If you were using the client credentials flow, you can refer this blog for acquiring the token. And if you were using the resource owner password, you can refer this thread.

Details about difference of the flows in Oauth 2 please refer RFC 6749.

Community
  • 1
  • 1
Fei Xue
  • 14,369
  • 1
  • 19
  • 27
0

I wrote a lightweight PHP class for working with Dynamics 365 online Web API. You can find it here.

BTW in your code you should try "password" inside the grant_type instead of "client_credentials"

RobbeR
  • 485
  • 6
  • 23