Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

msal.js 2.0 tokenResponse null after loginRedirect

I am developing an Angular 10 app that utilizes Azure B2C for policy and user management. I set up my app registration in Azure Active Directory as a singlepage app without the implicit option checked. I am using msal.js 2.0 @azure/msal-browser to log into B2C and retrieve id and access tokens using code flow. I set up my configuration, created the msal object, defined the redirect promise, then later call loginRedirect with the appropriate user scopes. The page redirects properly.

However, after I sign in the tokenResponse comes back as null. I have tried altering the authority and scopes, but it always comes back as null. How do I get the handleRedirectPromise to return a valid token response?

Here's my code:

    private msalConfig: Msal.Configuration = {
        auth: {
            clientId: xxxx-xx-xx-xx-xxxxx,
            authority: 'https://login.microsoftonline.com/common', 
            redirectUri: 'https://localhost:4200'
        },
        cache: {
            cacheLocation: 'sessionStorage',
            storeAuthStateInCookie: false
        },
    };

    private loginRequest: Msal.RedirectRequest = {
        scopes: ['user.read'],
    };

    const msalInstance = new Msal.PublicClientApplication(this.msalConfig);
    msalInstance
            .handleRedirectPromise()
            .then((tokenResponse: Msal.AuthenticationResult) => {
                let accountObj = null;
                if (tokenResponse !== null) {
                    accountObj = tokenResponse.account;
                    const id_token = tokenResponse.idToken;
                    const access_token = tokenResponse.accessToken;
                    console.log('id_token', id_token);
                    console.log('access_token', access_token);
                }
            })
            .catch(error => {
                authStore.loginError$.next(true);
                console.error(error);
            });

    msalInstance.loginRedirect(this.loginRequest);

Edit:

I have also tried authority: `https://<tenant-name>.b2clogin.com/<tenant-name>.onmicrosoft.com/<policy-name> and https://login.microsoftonline.com/tfp/{tenant}.onmicrosoft.com/B2C_1_SiupIn for the authority in the msalConfig object as well as scopes: ['openid'] in the loginRequest. When I use this I get the following error in the browser when I try to log in:

zone-evergreen.js:1068 GET https://login.microsoftonline.com/common/discovery/instance?api-version=1.1&authorization_endpoint=https://<tenant>.b2clogin.com/<tenant>.onmicrosoft.com/b2c_1_defaultsigninsignup/oauth2/v2.0/authorize 400 (Bad Request)

core.js:4197 ERROR Error: Uncaught (in promise): ClientAuthError: endpoints_resolution_error: Error: could not resolve endpoints. Please check network and try again. Detail: ClientConfigurationError: untrusted_authority: The provided authority is not a trusted authority. Please include this authority in the knownAuthorities config parameter.
ClientAuthError: endpoints_resolution_error: Error: could not resolve endpoints. Please check network and try again. Detail: ClientConfigurationError: untrusted_authority: The provided authority is not a trusted authority. Please include this authority in the knownAuthorities config parameter.
like image 964
afriedman111 Avatar asked Sep 27 '20 01:09

afriedman111


People also ask

What is redirect URI in Msal?

When a user authenticates, Azure Active Directory (Azure AD) sends the token to the app by using the redirect URI registered with the Azure AD application. The Microsoft Authentication library (MSAL) requires that the redirect URI be registered with the Azure AD app in a specific format.

Which ID is required for Msal configuration?

Initialize MSAL. The minimum required configuration property is the clientID of your application, shown as the Application (client) ID on the Overview page of the app registration in the Azure portal.

What is the latest version of Msal JS?

MSAL. js 2.0 is now generally available with support for authorization code flow - Microsoft 365 Developer Blog.

How do you use acquireTokenSilent?

acquireTokenSilent(accessTokenRequest) . then(function (accessTokenResponse) { // Acquire token silent success // Call API with token let accessToken = accessTokenResponse. accessToken; }) . catch(function (error) { //Acquire token silent failure, and send an interactive request if (error.


2 Answers

The way you set up the redirect flow seems correct. You first have to call the handleRedirectPromise() (which registers it), and then call the loginRedirect(). At page load handleRedirectPromise() will return null, and after sign-in it should return the token.

There are issues with your configuration, however.

  1. You need to designate your domain as a knownAuthority, like:
        auth: {
            clientId: 'xxxx-xx-xx-xx-xxxxx',
            authority: 'https://<tenant-name>.b2clogin.com/<tenant-name>.onmicrosoft.com/<policy-name>', 
            knownAuthorities: ['<your-tenant-name>.b2clogin.com']
            redirectUri: 'https://localhost:4200'
        },
  1. User.Read is a MS Graph API scope. You cannot use it with B2C. Only the OIDC scopes are allowed i.e. use openid instead.

See this for more.

like image 88
derisen Avatar answered Nov 21 '22 14:11

derisen


The problem was with my angular app. I had my app redirecting the base url to my /home route. So whenever you open the base route the app is redirected. From this route, the request is made. I added the redirect uri for the /home route to my AAD app registration, commented out the redirectUri in my b2c configuration and set navigateToLoginRequestUrl to true.

like image 31
afriedman111 Avatar answered Nov 21 '22 15:11

afriedman111