Search code examples
node.jsazureoauthazure-ad-msaldynamics-business-central

(msal-node) - Dynamics 365 Business Central returns 401 for any resource with received token


We are currently switching to an OAuth based authorization solution based on the @azure/msal-node package to authorize our API's with the ones provided by Dynamics 365 Business Central (19.5, Cloud). Somehow I can not get it to work. Our tenant instance just returns a 401 when requesting any resource using the retrieved token.

Really reached a dead end here, any help would be greatly appreciated.

Permissions set in Azure's "App Registrations" section

And yes, I have consented all of those Permissions on behalf of our tenant (admin consent)

  • API.ReadWrite.All
  • app_access
  • Automation.ReadWrite.All

The token even contains following scopes when decoded over at jwt.ms:

{
  "scopes": [
    "Automation.ReadWrite.All",
    "app_access",
    "API.ReadWrite.All"
  ]
}

Example of our implementation

/**
 * Uses `msal-node`  to authenticate against the microsoft servers
 * to gain access to Dynamics 365 Business Central
 */
async getClientCredentialsToken() {
   try {
      const validity = await this.validateClientCredentialsToken();
      if (validity) return;

      const authOptions = {
        clientId: process.env.AAD_CLIENT_ID,
        authority: process.env.AAD_AUTHORITY,
        clientSecret: process.env.AAD_CLIENT_SECRET,
      };

      const cacheOptions = {
        Account: {},
        IdToken: {},
        AccessToken: {},
        RefreshToken: {},
        AppMetadata: {},
      };

      const cca = new msal.ConfidentialClientApplication({
        cache: cacheOptions,
        auth: authOptions,
      });

      const response = await cca.acquireTokenByClientCredential({
        azureRegion: null,
        skipCache: true,
        scopes: ["https://api.businesscentral.dynamics.com/.default"],
      });

      return response;
    } catch (err) {
      console.log(err);
    }
},

Example of a response when requesting an existing endpoint

No matter what endpoint is hit. This is the response I get for it:

{
    "error": {
        "code": "Authentication_InvalidCredentials",
        "message": "The server has rejected the client credentials.  CorrelationId:  b004d293-f576-40c9-bbc6-3fb32533a65b."
    }
}

Solution

  • Solution found inside the Docs

    So for anybody stumbling upon the same scenario I have found something that finally worked! You need to register the application inside the Dynamics 365 Business Central client as described inside the official documentation.