question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

HTTP status code 400 | Attempted to reach: https://login.microsoftonline.com/common/oauth2/v2.0/token

See original GitHub issue

Core Library

MSAL Node (@azure/msal-node)

Core Library Version

1.12.1

Wrapper Library

Not Applicable

Wrapper Library Version

na

Description

.acquireTokenByCode() results in an http status 400

I’m creating an OAuth flow with Vercel/Nextjs serverless functions and this error has plagued me for a week. The auth code flow works fine using .getAuthCodeUrl().

Testing a deployment build on Vercel returned the 400 error. Making a fetch request directly to the endpoint also resulted in a 400 error.

I downloaded the quickstart code from the Azure dashboard and it works perfectly fine. This tells me it’s not a problem with my machine or Azure app registration, but probably a problem in my configuration and usage of the library.

I’ve basically copied that quickstart code into serverless functions and now it doesn’t work. Please let me know how to debug this issue or if I’ve made a mistake in my code 👍

Error Message

ClientAuthError: network_error: Network request failed. Please check network trace to determine root cause. | Fetch client threw: Error: HTTP status code 400 | Attempted to reach: https://login.microsoftonline.com/common/oauth2/v2.0/token at ClientAuthError.AuthError [as constructor] (C:\Development\rememberly-ui\node_modules@azure\msal-common\dist\index.cjs.js:500:24) at new ClientAuthError (C:\Development\rememberly-ui\node_modules@azure\msal-common\dist\index.cjs.js:802:28) at Function.ClientAuthError.createNetworkError (C:\Development\rememberly-ui\node_modules@azure\msal-common\dist\index.cjs.js:845:16) at NetworkManager.<anonymous> (C:\Development\rememberly-ui\node_modules@azure\msal-common\dist\index.cjs.js:3418:51) at step (C:\Development\rememberly-ui\node_modules@azure\msal-common\dist\index.cjs.js:79:23)
at Object.throw (C:\Development\rememberly-ui\node_modules@azure\msal-common\dist\index.cjs.js:60:53) at rejected (C:\Development\rememberly-ui\node_modules@azure\msal-common\dist\index.cjs.js:51:65) at runMicrotasks (<anonymous>) at processTicksAndRejections (node:internal/process/task_queues:96:5) { errorCode: ‘network_error’, errorMessage: ‘Network request failed. Please check network trace to determine root cause. | Fetch client threw: Error: HTTP status code 400 | Attempted to reach: https://login.microsoftonline.com/common/oauth2/v2.0/token’, subError: ‘’ }

Msal Logs

[Thu, 04 Aug 2022 01:19:29 GMT] : @azure/msal-node@1.12.1 : Info - acquireTokenByCode called [Thu, 04 Aug 2022 01:19:29 GMT] : @azure/msal-node@1.12.1 : Verbose - initializeRequestScopes called[Thu, 04 Aug 2022 01:19:29 GMT] : [14fd4f2e-9a49-4738-b9ae-0a5f6f83186a] : @azure/msal-node@1.12.1 : Verbose - buildOauthClientConfiguration called [Thu, 04 Aug 2022 01:19:29 GMT] : [14fd4f2e-9a49-4738-b9ae-0a5f6f83186a] : @azure/msal-node@1.12.1 : Verbose - building oauth client configuration with the authority: https://login.microsoftonline.com/common [Thu, 04 Aug 2022 01:19:29 GMT] : [14fd4f2e-9a49-4738-b9ae-0a5f6f83186a] : @azure/msal-node@1.12.1 : Verbose - createAuthority called [Thu, 04 Aug 2022 01:19:29 GMT] : [14fd4f2e-9a49-4738-b9ae-0a5f6f83186a] : @azure/msal-node@1.12.1 : Verbose - Auth code client created [Thu, 04 Aug 2022 01:19:29 GMT] : [14fd4f2e-9a49-4738-b9ae-0a5f6f83186a] : @azure/msal-common@7.3.0 : Info - in acquireToken call

MSAL Configuration

const clientConfig = {
  auth: {
    clientId: process.env.AZURE_CLIENT_ID,
    authority: 'https://login.microsoftonline.com/common',
    clientSecret: process.env.AZURE_CLIENT_SECRET
  },
  system: {
    loggerOptions: {
      loggerCallback(loglevel, message, containsPii) {
        console.log(message);
      },
      piiLoggingEnabled: false,
      logLevel: msal.LogLevel.Verbose
    }
  }
};

Relevant Code Snippets

~~ _utils.js ~~
const msal = require('@azure/msal-node'); 

const clientConfig = {
  auth: {
    clientId: process.env.AZURE_CLIENT_ID,
    authority: 'https://login.microsoftonline.com/common',
    clientSecret: process.env.AZURE_CLIENT_SECRET
  },
  system: {
    loggerOptions: {
      loggerCallback(loglevel, message, containsPii) {
        console.log(message);
      },
      piiLoggingEnabled: false,
      logLevel: msal.LogLevel.Verbose
    }
  }
};

export const clientApplication = new msal.ConfidentialClientApplication(clientConfig)
~~~~~~

~~ exchange-auth-code.js ~~


import { getURL } from '@/utils/helpers';
import { clientApplication } from './_utils';

const exchangeOutlookAuthCode = async (req, res) => {
  const code = req.body.code; // code is passed in from POST request on the frontend
  const redirectUri = getURL() + '/api/outlook/exchange-auth-code';

  const tokenRequest = {
    code,
    redirectUri,
    scopes: ['user.read']
  };

  await clientApplication
    .acquireTokenByCode(tokenRequest)
    .then((response) => {
      console.log('response: ', response);
    })
    .catch((err) => {
      console.error(err);
    });
};

export default exchangeOutlookAuthCode;
~~~~~~

~~ quickstart code from Azure, this code works ~~

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */
const express = require("express");
const msal = require('@azure/msal-node');

const SERVER_PORT = process.env.PORT || 3000;
const REDIRECT_URI = "http://localhost:3000/redirect";

// Before running the sample, you will need to replace the values in the config, 
// including the clientSecret
const config = {
    auth: {
        clientId: "*******",
        authority: "https://login.microsoftonline.com/common",
        clientSecret: "*******"
    },
    system: {
        loggerOptions: {
            loggerCallback(loglevel, message, containsPii) {
                console.log(message);
            },
            piiLoggingEnabled: false,
            logLevel: msal.LogLevel.Verbose,
        }
    }
};

// Create msal application object
const pca = new msal.ConfidentialClientApplication(config);

// Create Express App and Routes
const app = express();

app.get('/', (req, res) => {
    const authCodeUrlParameters = {
        scopes: ["user.read"],
        redirectUri: REDIRECT_URI,
    };

    // get url to sign user in and consent to scopes needed for application
    pca.getAuthCodeUrl(authCodeUrlParameters).then((response) => {
        res.redirect(response);
    }).catch((error) => console.log(JSON.stringify(error)));
});

app.get('/redirect', (req, res) => {
    const tokenRequest = {
        code: req.query.code,
        scopes: ["user.read"],
        redirectUri: REDIRECT_URI,
    };
    console.log(pca.storage.cache)
    pca.acquireTokenByCode(tokenRequest).then((response) => {
        console.log("\nResponse: \n:", response);
        res.sendStatus(200);
    }).catch((error) => {
        console.log(error);
        res.status(500).send(error);
    });
});


app.listen(SERVER_PORT, () => console.log(`Msal Node Auth Code Sample app listening on port ${SERVER_PORT}!`))

Reproduction Steps

  1. create post request to http://localhost;3000/api/outlook/exchange-auth-code with the auth code as a value in the body : {code: auth_code}
  2. code returns the error listed above Error: HTTP status code 400

Expected Behavior

Expected to return access token and refresh token

Identity Provider

Azure AD / MSA

Browsers Affected (Select all that apply)

None (Server)

Regression

No response

Source

External (Customer)

Issue Analytics

  • State:closed
  • Created a year ago
  • Reactions:1
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
dpwatrouscommented, Aug 4, 2022

We’ve seen a very similar-looking issue, though it’s hard to say if it’s the same without more info.

In our case, it’s in an Electron app, and the error only seems to happen to a certain customer who is using ADFS. The renderer (browser) process performs interactive auth, and when the redirect URI is hit, it sends the auth code to the main (Node.js) process, which calls acquireTokenByCode(). That aquireTokenByCode() call fails with an HTTP 400 ClientAuthError.

We were able to dig into the error further and determine the actual 400 error is an “invalid_grant” error with a message of: “AADSTS50076: Due to a configuration change made by your administrator, or because you moved to a new location, you must use multi-factor authentication to access ‘<REDACTED>’”. Usually MFA is handled while obtaining the auth code, so we’re still not sure what’s going wrong here.

If you debug into the MSAL library code itself you may be able to find the real underlying HTTP 400 error which is being swallowed. (See this issue)

0reactions
jasonnuttercommented, Aug 5, 2022

@LodenH16 Interesting, glad to hear its now working.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Microsoft Access Token Request Error - 400 Bad Request
For example, when I click the login.microsoftonline.com link, the error page has them in the lower right corner: "AADSTS90056: This endpoint ...
Read more >
Getting "The remote server returned an error: (400) Bad ...
Actually I am try to get AccessToken using Using the TenantId after ... ID "https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token" by ...
Read more >
Bug report: login fails with error 400 on 5.4.0 #3431 - GitHub
Fetch client threw: Error: HTTP status code 400 | Attempted to reach: https://login.microsoftonline.com/REDACTED/oauth2/v2.0/token.
Read more >
Solved: Getting 400 error for https://login.microsoftonl...
Solved: I am making a post request to https://login.microsoftonline.com/common/oauth2/token in my react application I am getting 400 error ...
Read more >
What is HTTP error 400 and how do you fix it? - IT PRO
A 400 Bad Request error can occur when the DNS data stored locally is out of sync with a website's registered DNS information...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found