Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Authenticating with the REST web API of MS Dynamics CRM 2016 online

I'm trying to access the new REST API for building a server-to-server interface to integrate the CRM with other applications such as the web-shop etc.

I have tried both ways of getting an access-token from Azure AD:

Client credentials

import adal

token_response = adal.acquire_token_with_client_credentials(
    'https://login.microsoftonline.com/abcdefgh-1234-5678-a1b1-morerandomstuff', 
    client_id,
    secret
)

and user/password

import adal

token_response = adal.acquire_token_with_username_password(
    'https://login.microsoftonline.com/abcdefgh-1234-5678-a1b1-morerandomstuff',
    '[email protected]_domain.com',
    'my_password'
)

In both cases, token_response gets a token-object, containing accessToken, refreshToken, expiresIn and so on. So I don't think there's an error up to this point.

Then I try to make a simple request to the web API:

headers = {'Authorization': '%s %s' % (token_response.get('tokenType'),
                                       token_response.get('accessToken'))}

r = requests.get('https://domain.api.crm4.dynamics.com/api/data/v8.0/Product',
                 headers=headers)

This always returns a HTTP 401 - Unauthorized: Access is denied.

('WWW-Authenticate', 'Bearer error=invalid_token,
error_description=Error during token validation!,
authorization_uri=https://login.windows.net/eabcdefgh-1234-5678-a1b1-morerandomstuff/oauth2/authorize,
resource_id=https://domain.api.crm4.dynamics.com/')

The user that tries to make the request has Office-365-Administrator privileges and in the CRM has all manager roles and the administrator role. Which for my taste is even a bit much, but I read somewhere, that the user has to have office-365 admin privileges. In the Azure AD there is an Application configured which has "delegated rights" to the CRM ("Access CRM Online as organization users").

What am I missing here? Or is my REST-get-request wrong? Microsoft documentation for the new API is practically nonexistent - whenever you click some link you get docs for the older APIs (organization API etc.)

like image 439
Chris Avatar asked Sep 25 '22 18:09

Chris


1 Answers

acquire_token_with_username_password has an optional parameter for specifying which resource you want access to:

resource (str, optional): The resource you are accessing. Defaults to 'https://management.core.windows.net/'.

You should thus be able to specify that you want access to CRM by adding resource as an argument to acquire_token_with_username_password:

token_response = adal.acquire_token_with_username_password(
    'https://login.microsoftonline.com/abcdefgh-1234-5678-a1b1-morerandomstuff',
    '[email protected]_domain.com',
    'my_password',
    resource='https://domain.crm4.dynamics.com'
)

This should give you a proper token for accessing CRM.

After getting the correct token, you also need to modify your Web API call slightly (from Product to products):

r = requests.get('https://domain.api.crm4.dynamics.com/api/data/v8.0/products',
                 headers=headers)
like image 106
Henrik H Avatar answered Oct 18 '22 05:10

Henrik H