12

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.
afriedman111
  • 1,925
  • 4
  • 25
  • 42
  • Check the browser session storage in the browser console to see if MSAL is holding an error. – Jas Suri - MSFT Sep 27 '20 at 08:20
  • That authority is definitely incorrect. Should be in format “ https://.b2clogin.com/.onmicrosoft.com/”. See the sample https://github.com/Azure-Samples/active-directory-b2c-javascript-msal-singlepageapp – Jas Suri - MSFT Sep 27 '20 at 09:51
  • And there is no such scope “user.read” for AAD B2C. See this https://learn.microsoft.com/en-us/azure/active-directory-b2c/tutorial-single-page-app-webapi?tabs=app-reg-ga – Jas Suri - MSFT Sep 27 '20 at 09:52
  • What you’ve configured is a pure AAD flow, not AAD B2C. – Jas Suri - MSFT Sep 27 '20 at 09:53
  • So @Jas Suri, I did try that as an authority, and I got an error in the browser (I updated my post with the full error). I also checked sessionStorage and it had 'errors: ["endpoints_resolution_error", "endpoints_resolution_error"]'. I also had tried openid, , and an empty array [], as scopes. I have looked for b2c examples with msal 2.0 and found little. I followed this guide: https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/v1-migration.md?spm=a2c6h.14275010.0.0.146871f8rE1slq&file=v1-migration.md – afriedman111 Sep 27 '20 at 13:28
  • The guide is for AAD not AAD B2C, see the sample I linked. – Jas Suri - MSFT Sep 27 '20 at 19:14

2 Answers2

6

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.

derisen
  • 630
  • 3
  • 13
  • Thank you! I made some progress. I added the knownAuthorities entry into my msalConfig. When I try to log in, I don't get errors anymore. I now get msal entries in my sessionStorage for different values: params, origin, authority and nonce.id_token. However, the full redirection doesn't occur. It looks like it tries to redirect, but redirects back. Also the tokenResponse is still null. – afriedman111 Sep 27 '20 at 20:03
  • you're welcome : ) just to confirm, did you also remove the 'user.read' scope and replaced with 'openid'? – derisen Sep 27 '20 at 20:07
  • Yes, I used { scopes: ['openid'] }. I wonder if it has to do with my app registration? – afriedman111 Sep 27 '20 at 20:09
  • 1
    I followed the Msal 2.0 registration in here https://learn.microsoft.com/en-us/azure/active-directory/develop/scenario-spa-app-registration#redirect-uri-msaljs-20-with-auth-code-flow – afriedman111 Sep 27 '20 at 20:17
  • 1
    Strange.. Might be browser related. Do you have a public repository that I can take a look at? Alternatively, you can send a network trace to me over email (I recommend using Fiddler). Also, there's an Angular 10 sample for AAD that you might check https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/samples/msal-angular-v2-samples/angular10-browser-sample – derisen Sep 27 '20 at 20:22
  • Intresting, the redirection is working in Edge, though it doesn't work in Chrome. However, in Edge the tokenResponse is still null after login. Also while some values are being cached in sessionStorage, none of them are the id_token or access_token. – afriedman111 Sep 27 '20 at 20:34
  • So I changed the authority to `https://{tenant}.b2clogin.com/tfp/{tenant}.onmicrosoft.com/B2C_1_DefaultSignInSignUp` with the 'tfp' and Chrome is now redirecting to the signin policy fine. The tokenResponse is still returning null though. – afriedman111 Sep 28 '20 at 00:56
  • Hi @derisen, I just read through your entier message. My application is in a private repo, but sending a network trace over email would definitely work. If you are still willing, I would be very greatful. How do I go about sending it to you? – afriedman111 Oct 14 '20 at 17:36
  • @afriedman111 sounds good. you can get my email on my github profile https://github.com/derisen – derisen Oct 14 '20 at 22:51
4

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.

afriedman111
  • 1,925
  • 4
  • 25
  • 42