2

We are using custom policies for Sign in and reset password in Azure B2C, when user is resetting his password and after doing all the process, when user tries to login using new password and OTP, below error is getting displayed and then user is continuously asked for new access code.

HTTP/1.1 400 Bad Request
Cache-Control: private
Allow: OPTIONS,TRACE,GET,HEAD,POST
Content-Type: application/json; charset=utf-8
x-ms-gateway-requestid: a6264e6b-e73e-45e1-aab9-71c5916e1215
Access-Control-Expose-Headers: Content-Length, Content-Encoding
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: POST, OPTIONS
Set-Cookie: x-ms-cpim-trans=; domain=****; expires=Fri, 02-Sep-2011 12:14:12 GMT; path=/; SameSite=None; secure; HttpOnly
X-Frame-Options: DENY
Public: OPTIONS,TRACE,GET,HEAD,POST
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Date: Thu, 02 Sep 2021 12:14:12 GMT
Content-Length: 296

{"error":"invalid_grant","error_description":"AADB2C90088: The provided grant has not been issued for this endpoint. Actual Value : B2C_1A_MFA_phone_or_email and Expected Value : B2C_1A_PasswordReset\r\nCorrelation ID: ******\r\nTimestamp: 2021-09-02 12:14:12Z\r\n"}

When the user has changed his password and click continue, below requests generated and you can see first token request is successful, but it is again trying for second token request and getting failed with above error. Network logs

What we are expecting here is that user should automatically get logged in, once he reset his password, rather then navigating back to log in screen and asking credentials again.

4 Answers4

3

The issue is that you are using the refresh token (RT) from the Password Reset policy to fetch a new token, but you are using the RT against the Sign In policy.

You need to make sure you select the correct Account object in your MSAL cache and use that against the matching B2C policy in your acquireTokenSilent() call.

Jas Suri - MSFT
  • 10,605
  • 2
  • 10
  • 20
1

You can access accounts in your msal instance with instance.getAllAccounts(), it appears to append any new account object each time you make a loginRedirect invocation. You may need to select the correct account in the array when you pass in the account object to acquireTokenSilent

const accounts = instance.getAllAccounts();
const account = accounts[index];

const authResult = await instance.acquireTokenSilent({
    scopes: config.authentication.scopes,
    account: account
});
sharifxu
  • 25
  • 9
0
    ### Its my implementation in react ###       
          const [account, setAccount] = useState();

useEffect(() => {
    if (props.authConfig) {
  
        const cachedAccounts = instance.getAllAccounts();
        let account;
        if (cachedAccounts.length < 1) {
            setAccount(undefined);
        } else {
            account = cachedAccounts.filter((cachedAccount) => 
            cachedAccount.username)?.[0];
        }
        if (account) {
            account.name = `${account.idTokenClaims.given_name} 
             ${account.idTokenClaims.family_name}`;
        setAccount(account);

        }
 
    } else {
     
        setAccount(undefined);
    }
}, [props.authConfig]);
     
  We need to make sure we select the correct Account object in 
  the MSAL 
  cache and use that against the matching B2C policy in the 
  acquireTokenSilent() call.
Fahad Rana
  • 11
  • 4
0

If you are using built in policies there is now built in password reset functionality for sign in and sign up flows. Check bellow articles for more information.

Danny Boy
  • 355
  • 3
  • 10