0
votes

@azure/msal-browser 2.14.1 @azure/msal-react 1.0.0-beta.2

We are using custom b2c policies

When I call acquireTokenSilent using an instance of PublicClientApplication it isn't getting the access token from the cache but i can see that an access token is stored in sessionStorage looking something like {homeAccountId}-{tenantSubdomain}.b2clogin.com-AccessToken-{aud}-{tid}. Along with refreshToken, clientInfo and idToken with similar format. It does successfully return tokens from the endpoint as expected.

In B2C redirect uri's are set to SPA and implicit flow is disabled

Config:

const config = {

auth: {
    clientId: applicationID,
    authority: signInAuthority,
    knownAuthorities: [
      `${tenantSubdomain}.b2clogin.com`,
    ],
    redirectUri: reactRedirectUri,
    validateAuthority: false,
    navigateToLoginRequestUrl: false,
    postLogoutRedirectUri: reactRedirectUri,
  },
  system: {
    loggerOptions: {
      loggerCallback: (level, message, containsPii) => {
        if (containsPii) {
          return;
        }
        switch (level) {
          case LogLevel.Error:
            console.error(message);
            return;
          case LogLevel.Info:
            console.info(message);
            return;
          case LogLevel.Verbose:
            console.debug(message);
            return;
          case LogLevel.Warning:
            console.warn(message);
            return;
        }
      },
      piiLoggingEnabled: false,
    },
    windowHashTimeout: 60000,
    iframeHashTimeout: 6000,
    loadFrameTimeout: 0,
    tokenRenewalOffsetSeconds: 1,
    // allowRedirectInIframe: true,
  },
  cache: {
    cacheLocation: "sessionStorage",
    storeAuthStateInCookie: true,
  },
};

requests:

const signInRequest = {
  scopes: [
    msalInstance.config.auth.clientId,
  ],
};

const silentRefreshRequest = {
  scopes: [
    msalInstance.config.auth.clientId,
  ],
};

offline_access, openid and profile get added automatically to the requests and I've tried many different variations on these scopes.

acquireTokenSilent:

const res = await msalInstance.acquireTokenSilent({
            ...silentRefreshRequest,
            account: msalInstance.getActiveAccount(),
          });

again I've tried a few different variations on this. Is there something I am missing that would solve getting it from cache or do I just need to work around it?

2

2 Answers

1
votes

This is a known issue when requesting your own clientId as a scope when using B2C. The B2C service returns a "scope" value of "/" instead of your clientId which breaks caching. They're working on a fix but for now to work around it you should create a custom scope on your app registration and use that instead. You can track this issue to be notified when the fix has been rolled out.

0
votes

For anyone having the same problem Thomas was correct checkout this article to create a custom scope and then put the scope in your requests:

const signInRequest = {
  scopes: ["xxx/api/user.read"],
};

const silentRefreshRequest = {
  scopes: ["xxx/api/user.read"],
};

It appears to fix the scoping problem when retrieving the token from cache