skip to Main Content

Edit:
The problem was a simple typo in the Header. You’re probably wasting your time here


In essence, I have the same problem as described here. It’s a somewhat different usecase and I’ll try to provide as much context as I can in the hopes that someone will be able to solve the problem.

So, this has to do with Azure, which seems to be an Alias for "Crazy problem generator". My apologies.

I’m trying to write a Service in NodeJS which has the purpose of synchronizing another app’s database with data from Azure.

For that reason, I’m using msal-node‘s Client Credential Flow as described here.

I find their comment // replace with your resource quite ridiculous, as I have not found a single full example online that specifies the format that should be used.

Intuitively, I would use something like

['GroupMember.Read.All']
//or
['https://graph.microsoft.com/GroupMember.Read.All']

Unfortunately, this does not work. Luckily, I get an error that describes the problem (even if only when this is the only scope I use, othewise the error is garbage):

{
  // ...
  errorMessage: '1002012 - [2022-05-23 11:39:00Z]: AADSTS1002012: The provided value for scope https://graph.microsoft.com/bla openid profile offline_access is not valid. Client credential flows must have a scope value with /.default suffixed to the resource identifier (application ID URI).rn'
}

Okay, let’s do that:

['https://graph.microsoft.com/GroupMember.Read.All/.default']

Now, the app actually performs a request, but unfortunately, I get

{
  // ...
  errorCode: 'invalid_resource',
  errorMessage: '500011 - [2022-05-23 11:42:31Z]: AADSTS500011: The resource principal named https://graph.microsoft.com/GroupMember.Read.All was not found in the tenant named <My company name, not an ID as shown in some places>. This can happen if the application has not
 been installed by the administrator of the tenant or consented to by any user in the tenant. You might have sent your authentication request to the wrong tenant.rn' +
    'Trace ID: <some id>rn' +
    'Correlation ID: <some id>rn' +
    'Timestamp: 2022-05-23 11:42:31Z - Correlation ID: <some id> - Trace ID: <some id>',
}

And yet it is there
aad admin center screenshot

And I am able to get a token for the .default scope. That’s just not good for anything.

The important parts of the actual code:

import fetch from 'isomorphic-fetch';
import * as msal from '@azure/msal-node';
// got env variables using dotenv package
// this is Typescript

const msalConfig = {
    auth: {
        clientId: process.env.OAUTH_APP_ID!,
        authority: process.env.OAUTH_AUTHORITY!,
        clientSecret: process.env.OAUTH_APP_SECRET!
    },
    system: {
        loggerOptions: {
            loggerCallback(loglevel: any, message: any, containsPii: any) {
                console.log(message);
            },
            piiLoggingEnabled: false,
            logLevel: msal.LogLevel.Verbose,
        }
    }
};

const msalClient = new msal.ConfidentialClientApplication(msalConfig);

const allCompanyMembersGroupId = '<some id>';

const tokenRequest = {
    scopes: ['https://graph.microsoft.com/GroupMember.Read.All/.default']
};

msalClient.acquireTokenByClientCredential(tokenRequest).then(response => {
    console.log('Got token:', response);
    fetch(`https://graph.microsoft.com/v1.0/groups/${allCompanyMembersGroupId}/members`, {
        method: 'GET',
        headers: {
            Authority: `Bearer ${response!.accessToken}`
        }
    }).then((res: any) => {
        console.log('Got response:', res);
    })
});

As mentioned, the request isn’t performed with my GroupMember.Read.All scope. With the default scope, I get a 401 unauthorized error.

So, these are my questions:

  1. How to fix this?
  2. Okay, if it you don’t know how to fix it, what is the exact format required for the scope? Is the prefix https://graph.microsoft.com correct, even for my specific app?
  3. Is this the correct library to use, or is this just broken code or not intended for such use? The other question I linked to above mentions that requests were successful using Postman, just not this lib…

Thanks heaps for any advice!

2

Answers


  1. Chosen as BEST ANSWER

    It's a problem with the headers. It should be Authorization instead of Authority.


  2. The error is in the following variable:

    const tokenRequest = {
        scopes: ['https://graph.microsoft.com/GroupMember.Read.All/.default']
    };
    

    the correct one would be:

    const tokenRequest = {
        scopes: ['https://graph.microsoft.com/.default']
    };
    

    Note: When using Client Credentials flow, it is a must to specify the scope string tailing with "/.default".

    For eg:

    • If you are trying to get an access-token using client credentials
      flow for MS Graph API, the scope should be
      "https://graph.microsoft.com/.default&quot;.
    • If you are trying to get an
      access-token using client credentials flow for a custom API which is
      registered in AAD, the scope should be either
      "api://{API-Domain-Name}/.default" or
      "api://{API-Client-Id}/.default".
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search