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

About migrating MSAL 2.x to MSAL 3.x #6498

Closed
aNyMoRe0505 opened this issue Sep 20, 2023 · 9 comments
Closed

About migrating MSAL 2.x to MSAL 3.x #6498

aNyMoRe0505 opened this issue Sep 20, 2023 · 9 comments
Assignees
Labels
msal-browser Related to msal-browser package msal-react Related to @azure/msal-react public-client Issues regarding PublicClientApplications question Customer is asking for a clarification, use case or information.

Comments

@aNyMoRe0505
Copy link

Core Library

MSAL.js (@azure/msal-browser)

Core Library Version

3.1.0

Wrapper Library

MSAL React (@azure/msal-react)

Wrapper Library Version

2.0.3

Public or Confidential Client?

Public

Description

Hello, according to the v-2 migration guideline, one of the breaking changes is that we must initialize the application object. We need to wait for the initialization to resolve before invoking other MSAL APIs. I find this a bit awkward. It means we have to manage a state ourselves to know if the initialization is complete, like this:

const [initialized, setInitialized] = useState(false);
useEffect(() => {
    const initializeMsal = async () => {
      await msalInstance.initialize();
      setInitialized(true);
    };
    initializeMsal();
}, []);

In all places where we use MSAL API, we have to use this flag to determine if we can invoke the MSAL API, such as acquireTokenSilent and loginRedirect. I could manage this flag using context or Redux, but would it be better if MSAL provided a variable, like:

const { instance, isInitialized } = useMsal();

Also, I'd like to ask if my approach is correct. Do I still need to use this flag to determine whether to render the login button? I have a feeling this isn't the best approach

MSAL Configuration

No response

Relevant Code Snippets

No response

Identity Provider

None

Source

Internal (Microsoft)

@aNyMoRe0505 aNyMoRe0505 added the question Customer is asking for a clarification, use case or information. label Sep 20, 2023
@github-actions github-actions bot added msal-browser Related to msal-browser package msal-react Related to @azure/msal-react public-client Issues regarding PublicClientApplications labels Sep 20, 2023
@microsoft-github-policy-service microsoft-github-policy-service bot added the Needs: Attention 👋 Awaiting response from the MSAL.js team label Sep 20, 2023
@tnorling
Copy link
Collaborator

You do not need to initialize yourself if you are using msal-react. It is handled under the hood by the msal-react library, starting in msal-react v1.4.0. Continue to use the inProgress state variable to determine whether it's safe to invoke login/acquireToken.

@microsoft-github-policy-service microsoft-github-policy-service bot added Needs: Author Feedback Awaiting response from issue author and removed Needs: Attention 👋 Awaiting response from the MSAL.js team labels Sep 20, 2023
@aNyMoRe0505
Copy link
Author

aNyMoRe0505 commented Sep 21, 2023

Hi, @tnorling
thank you for your quick response. I got a bit confused after reviewing this document (initialization part).
Which status can determine if we can call the acquireToken API, is it none?
Is there any documentation mentioning that we must first check inProgress status before calling the MSAL API?
In this example, there is also no judgment of the inProgress state.


Is it possible to simply have a flag indicating that the MSAL initialization is complete, since the inProgress state will keep changing? We just want to know if the initialization is complete. Using inProgress would cause the useEffect to execute multiple times. For example, we only want to call an API when the account exists.

useEffect(() => {
    if (inProgress === 'none' && account) {
      // do something, acquireToken
    }
  }, [account, inProgress]);

if inProgress change to acquireToken and eventually to none. This will trigger the effect again.

I also want to ask when inProgress appears as startup, acquireToken, ssoSilent, or handleRedirect. Because when I call acquireTokenSilent, it doesn't actually change to acquireToken. I think I should clarify these.

@microsoft-github-policy-service microsoft-github-policy-service bot added Needs: Attention 👋 Awaiting response from the MSAL.js team and removed Needs: Author Feedback Awaiting response from issue author labels Sep 21, 2023
@aNyMoRe0505
Copy link
Author

My issue is similar to this one (#6500).
After upgrading to v3 using the original setup approach, I encountered this error (BrowserAuthError: uninitialized_public_client_application). It made me realize that we need to initialize the application object as well, and the initialize function is asynchronous. This could potentially lead to calling the MSAL API before the initialization is complete, which is why I raised this issue.

@stephannielsen
Copy link

stephannielsen commented Sep 22, 2023

@tnorling

You do not need to initialize yourself if you are using msal-react.

Where does it say that in the docs - from my understanding, the docs tell me the opposite. The docs refer to the initialization of msal-browser (https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/lib/msal-react#msal-basics) and in the examples initialize is also called manually: https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/samples/msal-react-samples/typescript-sample/src/index.tsx

The samples helped us now, as we couldn't simply apply the msal-browser docs for initialization due to top-level-await, which is in conflict with our current browser target. The approach in the samples don't use top-level-await so can be applied easily. The docs/release notes could have been clearer on this change.

@aNyMoRe0505
Copy link
Author

@tnorling @jo-arroyo
sorry to bother, any update on this 🥺

@kestevez-rv
Copy link

kestevez-rv commented Sep 30, 2023

@tnorling @jo-arroyo sorry to bother, any update on this?

I've just upgrated msal-browser to v3.1.0 and I'm getting the following error:

TypeError: window.crypto.randomUUID is not a function
    at CryptoOps.createNewGuid (/Users/kenystev/projects/real-vision/rv2-ui/node_modules/@azure/msal-browser/lib/msal-browser.cjs:11021:30)
    at EventHandler.addEventCallback (/Users/kenystev/projects/real-vision/rv2-ui/node_modules/@azure/msal-browser/lib/msal-browser.cjs:12800:51)
    at StandardController.addEventCallback (/Users/kenystev/projects/real-vision/rv2-ui/node_modules/@azure/msal-browser/lib/msal-browser.cjs:16910:34)
    at PublicClientApplication.addEventCallback (/Users/kenystev/projects/real-vision/rv2-ui/node_modules/@azure/msal-browser/lib/msal-browser.cjs:17349:32)
    at /Users/kenystev/projects/real-vision/rv2-ui/src/services/msal.ts:47:18
    at processTicksAndRejections (node:internal/process/task_queues:95:5)

and I got my msal.ts file to instance it like this:
to manually call the initialize() function

export const msalInstance = new PublicClientApplication(msalConfig)

export const setToken = (token: string) => {
  // ....call API
}
msalInstance.initialize().then(() => {
  // Account selection logic is app dependent. Adjust as needed for different use cases.
  const accounts = msalInstance.getAllAccounts()
  if (accounts.length > 0) {
    msalInstance.setActiveAccount(accounts[0])
  }

  msalInstance.addEventCallback((event) => {
    if (event?.eventType === EventType.LOGIN_SUCCESS && event?.payload) {
      if ('account' in event.payload) {
        const account = event?.payload?.account
        if (account) {
          msalInstance.setActiveAccount(account)
        }
      }
      if ('accessToken' in event.payload) {
        try {
          if (!event?.payload?.accessToken) {
            throw new Error('accessToken is undefined')
          }
          setToken(event?.payload?.accessToken)
        } catch (error: any) {
          logger.error(error)
        }
      }
    }
    if (event?.eventType === EventType.LOGOUT_SUCCESS) {
      try {
          // ....call API
      } catch (error: any) {
        logger.error(error)
      }
    }
  })
})

I'm using msal-react@1.5.3 though I've tried also updating to msal-react@2.0.3 and still not working

@tnorling
Copy link
Collaborator

tnorling commented Oct 3, 2023

It made me realize that we need to initialize the application object as well, and the initialize function is asynchronous. This could potentially lead to calling the MSAL API before the initialization is complete, which is why I raised this issue.

As long as you are checking the inProgress state before invoking other asynchronous APIs you cannot get into this error state. You also should not be invoking token acquisition APIs outside the context of the MsalProvider so the inProgress state variable should be available everywhere you need it.

Which status can determine if we can call the acquireToken API, is it none?

Yes

I also want to ask when inProgress appears as startup, acquireToken, ssoSilent, or handleRedirect. Because when I call acquireTokenSilent, it doesn't actually change to acquireToken.

inProgress tracks operations that can't run in parallel with other operations and helps you ensure that those things are executed in serial (initialization, interaction). acquireTokenSilent does not block other APIs from executing and can be executed in parallel so does not get reflected in inProgress.

When the MsalProvider component is rendered inProgress is set to "Startup", PCA.initialize will be called, then PCA.handleRedirectPromise will be called and inProgress set to "handleRedirect". When handleRedirectPromise finishes inProgress will be set to "none".

From then on, you're on your own. Each time you invoke ssoSilent inProgress will be set to "ssoSilent" and when that completes, back to "None". Additionally, anytime you invoke loginRedirect/loginPopup/acquireTokenRedirect/acquireTokenPopup inProgress will be set to "acquireToken" and, when the operation completes, back to "None"

@microsoft-github-policy-service microsoft-github-policy-service bot added Needs: Author Feedback Awaiting response from issue author and removed Needs: Attention 👋 Awaiting response from the MSAL.js team labels Oct 3, 2023
@aNyMoRe0505
Copy link
Author

@tnorling
I think I don't have any further questions, so I'm closing this issue.
Additionally, I think the documentation could be clearer in this section.
Thank you for your assistance

@microsoft-github-policy-service microsoft-github-policy-service bot added Needs: Attention 👋 Awaiting response from the MSAL.js team and removed Needs: Attention 👋 Awaiting response from the MSAL.js team labels Oct 4, 2023
@microsoft-github-policy-service microsoft-github-policy-service bot removed the Needs: Author Feedback Awaiting response from issue author label Oct 4, 2023
@tnorling tnorling closed this as completed Oct 4, 2023
@zhosafwan
Copy link

TypeError: window.crypto.randomUUID is not a function
at CryptoOps.createNewGuid (/Users/kenystev/projects/real-vision/rv2-ui/node_modules/@azure/msal-browser/lib/msal-browser.cjs:11021:30)
at EventHandler.addEventCallback (/Users/kenystev/projects/real-vision/rv2-ui/node_modules/@azure/msal-browser/lib/msal-browser.cjs:12800:51)
at StandardController.addEventCallback (/Users/kenystev/projects/real-vision/rv2-ui/node_modules/@azure/msal-browser/lib/msal-browser.cjs:16910:34)
at PublicClientApplication.addEventCallback (/Users/kenystev/projects/real-vision/rv2-ui/node_modules/@azure/msal-browser/lib/msal-browser.cjs:17349:32)
at /Users/kenystev/projects/real-vision/rv2-ui/src/services/msal.ts:47:18
at processTicksAndRejections (node:internal/process/task_queues:95:5)

#6498 (comment)
Same problem

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
msal-browser Related to msal-browser package msal-react Related to @azure/msal-react 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

6 participants