I want to implement authentication using the OAuth 2.0 authorization code flow with the Microsoft Identity Platform (Azure AD) and the @azure/msal-node library in a Node.js 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.<anonymous> (/home/alok/tmp/test-node/node_modules/@azure/msal-common/dist/index.cjs.js:5722:41)
at step (/home/alok/tmp/test-node/node_modules/@azure/msal-common/dist/index.cjs.js:79:23)
at Object.next (/home/alok/tmp/test-node/node_modules/@azure/msal-common/dist/index.cjs.js:60:53)
at fulfilled (/home/alok/tmp/test-node/node_modules/@azure/msal-common/dist/index.cjs.js:50:58)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
errorCode: 'invalid_client',
errorMessage: "7000218 - [2023-05-19 12:26:56Z]: AADSTS7000218: The request body must contain the following parameter: 'client_assertion' or 'client_secret'.\r\n" +
'Trace ID: 1852de3e-3310-4503-a9c4-985e35880f00\r\n' +
'Correlation ID: 22c042a3-0777-4151-a364-edad3312ccee\r\n' +
'Timestamp: 2023-05-19 12:26:56Z - Correlation ID: 22c042a3-0777-4151-a364-edad3312ccee - Trace ID: 1852de3e-3310-4503-a9c4-985e35880f00',
subError: ''
}
I tried to get help from
Out of these none are helpful for me.
What I am missing exactly so I am getting this error?
Note that, you need to enable
Allow public client flows
to "Yes" and add redirect URI by selecting platform as Mobile and desktop applications while using PublicClientApplication.
I cloned this Github sample and registered one Azure AD application by adding redirect URI in Web
platform as below:
When I ran the sample and authenticated successfully, it asked for consent like below:
After accepting the above consent, I got code
value in address bar and same error as you like this:
When I checked the code terminal, I got similar logs as you like below:
To resolve the error, I removed redirect URI from Web
platform and added it in Mobile and desktop applications
platform by enabling Allow public client flows to "Yes" like below:
Redirect URI:
Enable public client flow:
Note that, there is no need to pass client secret in code if you make above changes while using PublicClientApplication.
When I ran the sample again after making above changes, I got below response like this:
In Browser:
In your case, check if you added redirect URI as Web
and change it to Mobile and desktop applications
platform by enabling Allow public client flows to "Yes".