Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

msal-node: Electron (v20) / create-react-app (5) : ClientAuthError: endpoints_resolution_error: Error: could not resolve endpoints. Please check network and try again. #5138

Closed
RadIsACoder opened this issue Aug 28, 2022 · 15 comments
Assignees
Labels
answered Question has received "first qualified response" b2c Related to Azure B2C library-specific issues msal-node Related to msal-node package Needs: Author Feedback Awaiting response from issue author no-issue-activity Issue author has not responded in 5 days public-client Issues regarding PublicClientApplications question Customer is asking for a clarification, use case or information.

Comments

@RadIsACoder
Copy link

Core Library

MSAL Node (@azure/msal-node)

Core Library Version

1.12.1

Wrapper Library

Not Applicable

Wrapper Library Version

None

Public or Confidential Client?

Public

Description

I'm getting the following error:

ClientAuthError: endpoints_resolution_error: Error: could not resolve endpoints. Please check network and try again. Detail: ClientAuthError: openid_config_error: Could not retrieve endpoints. Check your authority and verify the .well-known/openid-configuration endpoint returns the required endpoints. Attempted to retrieve endpoints from: https://sectaurapac.b2clogin.com/sectaurapac.onmicrosoft.com/b2c_1_sectaursignupsignin/v2.0/.well-known/openid-configuration

when setting up and invoking the PublicClientApplication.getAuthCodeUrl() method.

MSAL is being used to authenticate in a Desktop Electron App (with React).

The code with the same endpoints works with an older version, so ClientID and auth params are fine.

I have also "Allowed Public Client Flows" in Azure Portal.

I have also verified the end point by entering in browser which returns the relevant object:

https://{tenant_id}/{tenant_id}/b2c_1_<correct_policy>/v2.0/.well-known/openid-configuration

but I am unable to debug this any further. How can I find the specific cause for this error ?

I am presuming this is a bug as it works on older set up:

Works (taken from package.JSON):

...
"@azure/msal-node": "^1.3.1",
"react": "^16.14.0",
"react-scripts": "4.0.3"
...

Current set up (CRA5 required polyfill override based on this article - https://www.alchemy.com/blog/how-to-polyfill-node-core-modules-in-webpack-5)

Screen Shot 2022-08-28 at 1 29 24 PM

Package.JSON

{
  "name": "cra5polyfill",
  "version": "0.1.0",
  "private": true,
  "main": "./public/electron.js",
  "homepage": "./",
  "dependencies": {
    "@azure/msal-node": "^1.12.1",
    "@testing-library/jest-dom": "^5.14.1",
    "@testing-library/react": "^13.0.0",
    "@testing-library/user-event": "^13.2.1",
    "assert": "^2.0.0",
    "buffer": "^6.0.3",
    "crypto-browserify": "^3.12.0",
    "https-browserify": "^1.0.0",
    "os-browserify": "^0.3.0",
    "process": "^0.11.10",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-scripts": "5.0.1",
    "stream-browserify": "^3.0.0",
    "stream-http": "^3.2.0",
    "url": "^0.11.0",
    "util": "^0.12.4",
    "web-vitals": "^2.1.0"
  },
  "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test",
    "eject": "react-scripts eject",
    "electron:start": "concurrently -k \"cross-env BROWSER=none yarn start\" \"wait-on http://localhost:3000 && electron .\"",
    "build:local:mac": "yarn build && electron-builder -m -c.extraMetadata.main=build/electron.js"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "build": {
    "appId": "org.TestApplication",
    "productName": "Test",
    "publish": {
      "provider": "github",
      "token": "dffgfgfgfgdfgdfgfdgfdg"
    },
    "files": [
      "build/**/*",
      "node_modules/**/*"
    ],
    "directories": {
      "buildResources": "public"
    },
    "mac": {
      "target": "dmg",
      "hardenedRuntime": true,
      "gatekeeperAssess": false,
      "entitlements": "public/entitlements.mac.plist",
      "entitlementsInherit": "public/entitlements.mac.plist"
    },
    "afterSign": "./notarize.js",
    "dmg": {
      "sign": false
    }
  },
  "devDependencies": {
    "concurrently": "^7.3.0",
    "cross-env": "^7.0.3",
    "dotenv": "^16.0.1",
    "electron": "^20.1.0",
    "electron-builder": "^23.3.3",
    "electron-notarize": "^1.2.1",
    "react-app-rewired": "^2.2.1",
    "wait-on": "^6.0.1"
  }
}

Any help would be much appreciated.

MSAL Configuration

const authorizationOptions = {
  clientId: process.env.REACT_APP_B2C_CLIENT_ID,
  authority: process.env.REACT_APP_B2C_AUTHORITY,
  knownAuthorities: [process.env.REACT_APP_B2C_KNOWN_AUTHORITIES]
};

const authCodeUrlParameters = {
  scopes: [],
  redirectUri: process.env.REACT_APP_REDIRECT_URI,
};

(REACT_APP_REDIRECT_URI=https://{tenant_id}/oauth2/nativeclient)

const authCodeRequest = {
  redirectUri: process.env.REACT_APP_REDIRECT_URI,
  scopes: [],
};

const MSAL_CONFIG = {
  auth: authorizationOptions,
  system: {
    loggerOptions: {
      loggerCallback(level: LogLevel, message) {
        switch (level) {
          case (LogLevel.Error):
            console.log(message)
        }
      },
      
    },
  },
};

Relevant Code Snippets

const AuthProvider = () => {

  const [authClient, setAuthClient] = useState()

  const showAuthClient = () => {
    console.log(authClient)
  }

  const getTokenInteractive = async (requestParams) => {

      try {
      // Generate PKCE Challenge and Verifier
      const cryptoProvider = new CryptoProvider();
      const { challenge, verifier } = await cryptoProvider.generatePkceCodes();

       // Add PKCE params to AuthCodeUrl request (passed to getAuthCodeUrl method)
      const authCodeUrlParams = {
         ...requestParams,
         prompt: "login",
        scopes: requestParams.scopes,
        codeChallenge: challenge,
       codeChallengeMethod: "S256",
     };
  const authCodeUrl = await authClient.getAuthCodeUrl(authCodeUrlParams);
 } catch (error) {console.log(error)}
    
  }
  useEffect(() => {
    const client = new PublicClientApplication(MSAL_CONFIG);
    setAuthClient(client);
  }, []);

  return (
    <div>
      <h1 className="text-5xl text-cyan-500">Hello JS !!!</h1>
      <button onClick={showAuthClient}>AuthClient</button>
      <button className="border-3-blue" onClick={()=> {getTokenInteractive(authCodeUrlParameters)}}>getToken</button>
    </div>
  );
};

export default AuthProvider;

Identity Provider

Azure B2C Basic Policy

Source

External (Customer)

@RadIsACoder RadIsACoder added the question Customer is asking for a clarification, use case or information. label Aug 28, 2022
@ghost ghost added the Needs: Attention 👋 Awaiting response from the MSAL.js team label Aug 28, 2022
@github-actions github-actions bot added b2c Related to Azure B2C library-specific issues msal-node Related to msal-node package public-client Issues regarding PublicClientApplications labels Aug 28, 2022
@ghost ghost assigned jo-arroyo Aug 28, 2022
@tnorling
Copy link
Collaborator

@RadIsACoder What version does your package-lock say is installed when it does work? Have you looked at your network requests to see if you can determine why the call to the well-known endpoint is failing?

@ghost ghost added answered Question has received "first qualified response" Needs: Author Feedback Awaiting response from issue author and removed Needs: Attention 👋 Awaiting response from the MSAL.js team labels Aug 29, 2022
@Sectaur
Copy link

Sectaur commented Aug 30, 2022

Hi Thomas,

Nothing I'm afraid. Screenshot attached.

Screen Shot 2022-08-30 at 4 43 52 PM

Exact steps to reproduce:

Node v18.3.0

yarn create react-app msal-cra5-test

yarn start .. No problems on localhost:3000

yarn add @azure/msal (adds v."1.12.1")

create src/Auth.js 

import React, { useEffect, useState } from "react";
import {
  PublicClientApplication,
  LogLevel,
  CryptoProvider,
} from "@azure/msal-node";

const authorizationOptions = {
  clientId: process.env.REACT_APP_B2C_CLIENT_ID,
  authority: process.env.REACT_APP_B2C_AUTHORITY,
  knownAuthorities: [process.env.REACT_APP_B2C_KNOWN_AUTHORITIES],
};

const authCodeUrlParameters = {
  scopes: [],
  redirectUri: process.env.REACT_APP_REDIRECT_URI,
};

const authCodeRequest = {
  redirectUri: process.env.REACT_APP_REDIRECT_URI,
  scopes: [],
};

const MSAL_CONFIG = {
  auth: authorizationOptions,
  system: {
    loggerOptions: {
      loggerCallback(level, message) {
        switch (level) {
          case LogLevel.Error:
            console.log(message);
        }
      },
    },
  },
};

const AuthProvider = () => {
  const [authClient, setAuthClient] = useState();

  const showAuthClient = () => {
    console.log(authClient);
  };

  const getTokenInteractive = async (requestParams) => {
    try {
      // Generate PKCE Challenge and Verifier
      const cryptoProvider = new CryptoProvider();
      const { challenge, verifier } = await cryptoProvider.generatePkceCodes();

      // Add PKCE params to AuthCodeUrl request (passed to getAuthCodeUrl method)
      const authCodeUrlParams = {
        ...requestParams,
        prompt: "login",
        scopes: requestParams.scopes,
        codeChallenge: challenge,
        codeChallengeMethod: "S256",
      };

      const authCodeUrl = await authClient.getAuthCodeUrl(authCodeUrlParams);

      console.log(authCodeUrl);
    } catch (error) {
      console.log(error);
    }
  };

  useEffect(() => {
    if (!authClient) {
      const client = new PublicClientApplication(MSAL_CONFIG);

      setAuthClient(client);
    }
  }, []);

  return (
    <div>
      <h1 className="text-5xl text-cyan-500">Hello World</h1>
      <button onClick={showAuthClient}>AuthClient</button>
      <button
        className="border-3-blue"
        onClick={() => {
          getTokenInteractive(authCodeUrlParameters);
        }}
      >
        getToken
      </button>
    </div>
  );
};

export default AuthProvider;

index.js

import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import Auth from "./Auth";
import reportWebVitals from "./reportWebVitals";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    {/* <App /> */}
    <Auth />
  </React.StrictMode>
);

Results in ...

ERROR in ./node_modules/@azure/msal-node/dist/msal-node.esm.js 3:0-24
Module not found: Error: Can't resolve 'http' in '/Users/XX/Desktop/cra5msal/node_modules/@azure/msal-node/dist'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
- add a fallback 'resolve.fallback: { "http": require.resolve("stream-http") }'
- install 'stream-http'
If you don't want to include a polyfill, you can use an empty module like this:
resolve.fallback: { "http": false }....

Then follow exact process outlined here:

(https://www.alchemy.com/blog/how-to-polyfill-node-core-modules-in-webpack-5)

... No AuthCodeUrl ...

PublicClientApplication instance is created though.

Also note its working with React Scripts 4

Thanks again

@RadIsACoder
Copy link
Author

I was also hopeful when I used MSAL React, which made things much easier ( and worked) but it wouldn’t run when integrating with Electron.

This is unexpected as the components in Electron are simply being rendered using JS / JSX. The Node engine is completely isolated from the renderer and running in a different process.

@ghost ghost added Needs: Attention 👋 Awaiting response from the MSAL.js team and removed Needs: Author Feedback Awaiting response from issue author labels Aug 30, 2022
@peterzenz peterzenz assigned tnorling and unassigned jo-arroyo Aug 30, 2022
@tnorling
Copy link
Collaborator

@RadIsACoder Did you try following the instructions in the error message to provide polyfills? We recently switched to using http instead of axios to make network requests - if that is unavailable in your environment network requests will not work. You may also find our Electron/React sample interesting.

@ghost ghost added Needs: Author Feedback Awaiting response from issue author and removed Needs: Attention 👋 Awaiting response from the MSAL.js team labels Aug 30, 2022
@RadIsACoder
Copy link
Author

I followed the tutorial (above) to add polyfills.
Have you tried to install using the above steps ? If so, did you get the same error?

Webpack in CRA5 but is hidden so have to add fallbacks as per above to override the config settings.

Thanks for the sample. Will check it out.

@ghost ghost added Needs: Attention 👋 Awaiting response from the MSAL.js team and removed Needs: Author Feedback Awaiting response from issue author labels Aug 30, 2022
@tnorling
Copy link
Collaborator

@RadIsACoder To clarify, adding the polyfills did or did not solve the problem?

@ghost ghost added Needs: Author Feedback Awaiting response from issue author and removed Needs: Attention 👋 Awaiting response from the MSAL.js team labels Aug 31, 2022
@Sectaur
Copy link

Sectaur commented Aug 31, 2022

Not yet but I'm going through the ElectronReactTestApp. Jut to clarify, whats the exact defintiion of "authority" in theMSAL config.

The example gives

https://login.windows-ppe.net/common/

but another example on MSAL website gives:

authority: `${AAD_ENDPOINT_HOST}/cbe899ec-5f5c-4efe-b7a0-599505d3d54f`,

(authority: `${AAD_ENDPOINT_HOST}/${Tenant_ID}`,

Pretty confusing. Which one is it ?

@Sectaur
Copy link

Sectaur commented Aug 31, 2022

or is it this one ?

auth: {
    clientId: "<your-clientID>",
    authority: "https://<your-tenant>.b2clogin.com/<your-tenant>.onmicrosoft.com/<your-policyID>",
    knownAuthorities: ["<your-tenant>.b2clogin.com"] // array of URIs that are known to be valid
  }

@Sectaur
Copy link

Sectaur commented Aug 31, 2022

I am using B2C for my Electron React App but the test Electron React example is for AAD

@tnorling
Copy link
Collaborator

@Sectaur Authority is the url of the identity provider you are trying to acquire tokens from. All are valid, which you use depends on where your app registration and users reside. Since you're using B2C you should use the last example and fill in the placeholders with your specific tenant and policies

@Sectaur
Copy link

Sectaur commented Aug 31, 2022

Ok thanks. Will try it out.

Re: Redirect URI - The previous app used "https://${TENANT_NAME}.b2clogin.com/oauth2/nativeclient" and "Allow Public ClientFlows" to "yes".

To access the B2C user Flow, should I use this or "msal4b0db8c2-9f26-4417-8bde-3f0e3656f8e0://auth" ?

I'm not sure why the "https:// " Redirect URI worked in production mode when the Electron-React App was deployed.

Are there any examples of a Electron-React App accessing tokens with B2C / UserFlows ?

Thanks for your patience.

@tnorling
Copy link
Collaborator

The redirectUri is the location where your app will listen for the response. It can be anything you like as long as it's something your app owns and understands how to read responses from. The sample I linked before sets up a custom protocol listener here with the following hostname which it then uses as the redircectUri.

@Sectaur
Copy link

Sectaur commented Sep 1, 2022

It doesn't work with the current set up. The PublicClientApplication instantiates normally but the code fails at client.getAuthCodeUrl().

The ElectronReactTest App also failed until we added this arcane "checks" Key which we found after lots of searching.

"clientId": "123455-03aa-4f80-5rde-782b17c11859",
"authority": "https://Tenant_Name.b2clogin.com/Tenant_Name.onmicrosoft.com/Ploicy",
"knownAuthorities": ["Tenant_ID"],
"checks": ["pkce"],
"client": {
"token_endpoint_auth_method": "none"
}

The steps to reproduce are provided above.

Here's a copy of the current package.JSON.

{
  "name": "cra5polyfill",
  "version": "0.1.0",
  "private": true,
  "main": "./public/electron.js",
  "homepage": "./",
  "dependencies": {
    "@azure/msal-node": "^1.12.1",
    "@testing-library/jest-dom": "^5.14.1",
    "@testing-library/react": "^13.0.0",
    "@testing-library/user-event": "^13.2.1",
    "assert": "^2.0.0",
    "buffer": "^6.0.3",
    "crypto-browserify": "^3.12.0",
    "https-browserify": "^1.0.0",
    "os-browserify": "^0.3.0",
    "process": "^0.11.10",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.3.0",
    "react-scripts": "5.0.1",
    "stream-browserify": "^3.0.0",
    "stream-http": "^3.2.0",
    "url": "^0.11.0",
    "util": "^0.12.4",
    "web-vitals": "^2.1.0"
  },
  "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test",
    "eject": "react-scripts eject",
    "dev": "concurrently -k \"cross-env BROWSER=none yarn start\" \"wait-on http://localhost:3000 && electron .\"",
    "build:local:mac": "yarn build && electron-builder -m -c.extraMetadata.main=build/electron.js"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "concurrently": "^7.3.0",
    "cross-env": "^7.0.3",
    "dotenv": "^16.0.1",
    "electron": "^20.1.0",
    "electron-builder": "^23.3.3",
    "electron-notarize": "^1.2.1",
    "react-app-rewired": "^2.2.1",
    "wait-on": "^6.0.1"
  }
}

Thanks for your help, hopefully we can find the source of the error.

@tnorling
Copy link
Collaborator

tnorling commented Sep 1, 2022

@Sectaur

The PublicClientApplication instantiates normally but the code fails at client.getAuthCodeUrl().

Fails how?

The ElectronReactTest App also failed until we added this arcane "checks" Key which we found after lots of searching.

What is this? This isn't a config option that MSAL.js recognizes.

@ghost
Copy link

ghost commented Sep 7, 2022

@RadIsACoder This issue has been automatically marked as stale because it is marked as requiring author feedback but has not had any activity for 5 days. If your issue has been resolved please let us know by closing the issue. If your issue has not been resolved please leave a comment to keep this open. It will be closed automatically in 7 days if it remains stale.

@ghost ghost added the no-issue-activity Issue author has not responded in 5 days label Sep 7, 2022
@ghost ghost closed this as completed Sep 14, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
answered Question has received "first qualified response" b2c Related to Azure B2C library-specific issues msal-node Related to msal-node package Needs: Author Feedback Awaiting response from issue author no-issue-activity Issue author has not responded in 5 days public-client Issues regarding PublicClientApplications question Customer is asking for a clarification, use case or information.
Projects
None yet
Development

No branches or pull requests

4 participants