Authentication using the OAuth 2.0 authorization code flow with the Microsoft Identity Platform (Azure AD) and @azure/msal-node in a Node.js backend

alokmahor 1 Reputation point
2023-05-22T09:03:33.5766667+00:00

I want to implement authentication using the [OAuth 2.0][1] authorization code flow with the Microsoft Identity Platform (Azure AD) and the [@azure/msal-node][2] library in a [Node.js][3] backend.

So I can call graph api on successful authentication.

I tried to adopt code from official example at https://learn.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-nodejs-webapp-msal 

Here is my code:

const express = require('express');
const { PublicClientApplication, LogLevel } = require('@azure/msal-node');

// Initialize the MSAL client with your authentication configuration
const msalConfig = {
  auth: {
    clientId: process.env.CLIENT_ID,
    clientSecret: process.env.CLIENT_SECRET,
    authority: `https://login.microsoftonline.com/${process.env.TENANT_ID}`,
    redirectUri: 'http://localhost:3000/redirect'
  },
  system: {
    loggerOptions: {
      loggerCallback(loglevel, message, containsPii) {
        console.log(message);
      },
      piiLoggingEnabled: false,
      logLevel: LogLevel.Info
    }
  }
};

const msalClient = new PublicClientApplication(msalConfig);

// Create an Express app
const app = express();

// Define a route for initiating the login process
app.get('/login', async (req, res) => {
  const authCodeUrlParameters = {
    scopes: ['openid', 'profile', 'offline_access', 'Calendars.Read'],
    redirectUri: 'http://localhost:3000/redirect'
  };

  // Generate the authorization URL
  const authUrl = await msalClient.getAuthCodeUrl(authCodeUrlParameters);
  console.log('alok', authUrl)

  // Redirect the user to the authorization URL
  res.redirect(authUrl);
});

// Define a route for handling the redirect callback
app.get('/redirect', async (req, res) => {
  const tokenRequest = {
    code: req.query.code,
    scopes: ['openid', 'profile', 'offline_access', 'Calendars.Read'],
    redirectUri: 'http://localhost:3000/redirect'
  };

  try {
    // Acquire an access token using the authorization code
    const response = await msalClient.acquireTokenByCode(tokenRequest);

    // use token now and save it for call graph api
    res.send('Authentication successful!');
  } catch (error) {
    // Handle the token acquisition error
    console.log(error);
    res.send('Authentication failed.');
  }
});

// Start the server
app.listen(3000, () => {
  console.log('Server started on http://localhost:3000');
});

After successful login I am getting the code via http://localhost:3000/redirect?code=something
But I am not able to get token in the line await msalClient.acquireTokenByCode(tokenRequest) I am getting error

ServerError: invalid_client: 7000218 - [2023-05-19 12:26:56Z]: AADSTS7000218: The request body must contain the following parameter: 'client_assertion' or 'client_secret'.
Trace ID: 1852de3e-3310-4503-a9c4-985e35880f00
Correlation ID: 22c042a3-0777-4151-a364-edad3312ccee
Timestamp: 2023-05-19 12:26:56Z - Correlation ID: 22c042a3-0777-4151-a364-edad3312ccee - Trace ID: 1852de3e-3310-4503-a9c4-985e35880f00
    at ServerError.AuthError [as constructor] (/home/alok/tmp/test-node/node_modules/@azure/msal-common/dist/index.cjs.js:498:24)
    at new ServerError (/home/alok/tmp/test-node/node_modules/@azure/msal-common/dist/index.cjs.js:3383:28)
    at ResponseHandler.validateTokenResponse (/home/alok/tmp/test-node/node_modules/@azure/msal-common/dist/index.cjs.js:5414:19)
    at AuthorizationCodeClient.
Microsoft Security Microsoft Entra Microsoft Entra ID
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Keith Howling 10 Reputation points Microsoft Employee
    2023-05-22T10:00:44.45+00:00

    Looks like this is a server app, so maybe use 'ConfidentialClientApplication' rarther than 'PublicClientApplication', so its able to send the client secret. For example see: https://github.com/Azure-Samples/js-e2e-web-app-server-auth/blob/396cc63dc869420aad13df52587716a2a40031d3/src/msal-express-wrapper/auth-provider.js#L63

    1 person found this answer helpful.
    0 comments No comments

  2. alokmahor 1 Reputation point
    2023-05-22T09:38:01.93+00:00

    Changing redirect URI as Web to Mobile and desktop applications platform by enabling Allow public client flows to "Yes".

    Reference: https://stackoverflow.com/a/76304639/1762051

    0 comments No comments

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.