How to solve 401 errors in order to access outlook calendars with @azure/identity?

Oliver Götz 0 Reputation points
2024-03-06T15:28:53.73+00:00

Hi,

I have been trying for hours now to build a next.js app that reads events from a shared outlook calendar.

For some reason I cannot explain I always receive:

GraphError

at GraphErrorHandler.eval (webpack-internal:///(action-browser)/./node_modules/@microsoft/microsoft-graph-client/lib/es/src/GraphErrorHandler.js:87:26)

at Generator.next (<anonymous>)

at eval (webpack-internal:///(action-browser)/./node_modules/tslib/tslib.es6.mjs:179:71)

at new Promise (<anonymous>)

at __awaiter (webpack-internal:///(action-browser)/./node_modules/tslib/tslib.es6.mjs:161:12)

at GraphErrorHandler.getError (webpack-internal:///(action-browser)/./node_modules/@microsoft/microsoft-graph-client/lib/es/src/GraphErrorHandler.js:80:64)

at GraphRequest.eval (webpack-internal:///(action-browser)/./node_modules/@microsoft/microsoft-graph-client/lib/es/src/GraphRequest.js:291:104)

at Generator.throw (<anonymous>)

at rejected (webpack-internal:///(action-browser)/./node_modules/tslib/tslib.es6.mjs:171:40)

at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {

statusCode: 401,

code: null,

requestId: null,

date: 2024-03-06T15:17:39.447Z,

body: ReadableStream { locked: false, state: 'readable', supportsBYOB: false }

My app registration has the correct permissions:

Calendars.Read Application Read calendars in all mailboxes
Calendars.Read Application Read calendars in all mailboxes

This is my quick a dirty backend code (I call fetchOutlookEvents() in my frontend):

// Create an instance of the TokenCredential class that is imported
const tokenCredential = new ClientSecretCredential(
  "tenantID", // just removed for security reasons
  "clientD", // just removed for security reasons
  "secret" // just removed for security reasons
);


const authProvider = new TokenCredentialAuthenticationProvider(
  tokenCredential,
  { scopes: ["https://graph.microsoft.com/.default"] }
);

const client = Client.initWithMiddleware({
  debugLogging: true,
  authProvider,
});

export const fetchOutlookEvents = async () => {
  try {
    const events = await client
      .api("/users/84c2fdbe-c42d-455a-a1ec-45115387217f/calendar")
      .get();
    console.log(events.value);
  } catch (error) {
    console.log(error);
  }
};

Microsoft Graph
Microsoft Graph
A Microsoft programmability model that exposes REST APIs and client libraries to access data on Microsoft 365 services.
12,005 questions
JavaScript API
JavaScript API
An Office service that supports add-ins to interact with objects in Office client applications.
982 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. AsithwMSFT 1,430 Reputation points Microsoft Vendor
    2024-03-09T03:29:37.1+00:00

    @Oliver Götz

    Is this the complete code? It seems like the part for requesting a token might be missing.

    async function getToken(tokenRequest) { 
    return await cca.acquireTokenByClientCredential(tokenRequest); 
    }
    
    or 
    const tokenRequest = {
        scopes: [ 'https://graph.microsoft.com/.default' ],
    };
    const tokenResponse = await cca.acquireTokenByClientCredential(tokenRequest);
    

    https://learn.microsoft.com/en-us/entra/identity-platform/tutorial-v2-nodejs-console#add-authentication-logic

    https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-console-app-nodejs-acquire-token#requesting-tokens


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.