Search code examples
oauth-2.0dynamics-crmpostmandynamics-crm-onlinedata-export

How do I authenticate against the Dynamics 365 Data Export Service API?


I've set up something called the Data Export Service for Dynamics 365 so that it replicates into an Azure SQL database. This is working as expected.

I'm trying to find a way to be proactively notified if this service encounters any errors. There does not appear to be a native way to do this through the setup in CRM itself, but they do provide an API. The Swagger page outlining all methods can be found here.

I'm trying to call the GetProfilesByOrganizationId method using Postman:

https://discovery.crmreplication.azure.net/crm/exporter/profiles?organizationId=4ef7XXXX-XXXX-XXXX-XXXX-XXXXXX8a98f&status=true

I'm having issues with authentication and always receive the following error:

"Message": "Received unauthenticated requestRequest Url https://discovery.crmreplication.azure.net/crm/exporter/profiles?organizationId=4ef7XXXX-XXXX-XXXX-XXXX-XXXXXX8a98f&status=true"

I have registered an application in Azure that has permission to access Dynamics 365 on behalf of the authenticated user which in this case is me, the administrator.

I have set the Type to OAuth 2.0 on the Authorization tab of Postman. I have requested an Access Token using the Grant Type of Authorization Code against the above application successfully. This has added a header to the request:

Key: Authorization
Value: Bearer BIGLONGACCESSTOKEN

Despite this header being present I still get the error mentioned above.

The API documentation implies the authentication is OAuth2 Implicit Grant Flow (click on any red exclamation mark in the documentation) but I can't get this to work in Postman. When I try to request a token with this method I get the error:

unsupported_response_type

... in the Postman console.

Any ideas how to authenticate (with Implicit Grant?) against this API in Postman?

(I'd accept C# examples if they're more appropriate, but I'd be surprised if Postman can't show me what I need)


Solution

  • It looks like the code sample shown by Microsoft can work if updated with newer methods and with some extra configuration in Azure that's not documented.

    Azure configuration

    By installing the Data Export service (and assuming it's all working) you'll have a new Enterprise Application listed in Azure AD as Crm Exporter.

    To take advantage of this application and authenticate with the Data Export API you must configure an app of your own.

    Go to the App registrations tab in Azure AD and add a new application registration.
    Give it a name and set the Application type to Native. The redirect URI doesn't typically matter as long as it's valid.

    Click the Manifest button to edit the manifest, change the property oauth2AllowImplicitFlow to true and save the changes.

    The only other important configuration is Required permissions which should be set as below:

    • Windows Azure Active Directory
      • Delegated permissions
        • Sign in and read user profile
    • Data Export Service for Microsoft Dynamics 365 (Crm Exporter)
      • Delegated permissions
        • Have access to Data Export Service for Microsoft Dynamics 365 API

    You will then need to click Grant Permissions.

    C# changes

    The updated method looks like this:

    using Microsoft.IdentityModel.Clients.ActiveDirectory;
    
    string clientId = "11cfXXXX-XXXX-XXXX-XXXX-XXXXXXXXd020";
    string user = "[email protected]";
    string password = "PASSWORD";
    
    var authParam= await AuthenticationParameters.CreateFromResourceUrlAsync(
        new Uri("https://discovery.crmreplication.azure.net/crm/exporter/aad/challenge")
    );
    
    var context = new AuthenticationContext(authParam.Authority, false);
    
    var credentials = new UserPasswordCredential(user, password);
    
    var token = await context.AcquireTokenAsync(authParam.Resource, clientId, credentials).AccessToken;
    

    You can now query the Data Export API by providing the token as a header:

    Authorization : Bearer eJ0y........Hgzk

    curl -X GET --header 'Accept: application/json' 'https://discovery.crmreplication.azure.net/crm/exporter/profiles?organizationId=MyOrgId&status=true'