azure-ad-b2c / samples

Azure AD B2C custom policy solutions and samples.
825 stars 596 forks source link

MFA incorrectly requested when access token expires (but refresh token is still valid) #429

Open iamalexmang opened 2 years ago

iamalexmang commented 2 years ago

Hi,

We implemented MFA through our policies, but based on customer requested ended up writing the custom policies to support MFA using the Authenticator App and a phone number (text messages + calls). At the heart of it, we used this sample https://github.com/azure-ad-b2c/samples/tree/master/policies/mfa-email-or-phone,

The reason I'm opening up this issue is due to fact that the experience differs between the two form factors (namely MFA vs. phone) in that if a user choses to validate their authn request using the Authenticator app and the access token expires (but prior to the expiration of the refresh token), neither the authentication login page (requesting the authentication credentials) nor the multi-factor authentication page appear. However, if the user logged in and validated their authentication using their phone, after the expiration of the access token (still prior to the expiration of the refresh token), they are requested to do MFA again (despite not being asked to provide a valid username and password).

Can I kindly ask for your assistance in understanding why this behaviour occurs and how we could fix it by streamlining the experience users are getting? Ideally, if the user has a valid authentication and proved their identity through MFA (irrelevant whether it was using the Authenticator App or a phone call/text message), their authentication remains valid based and are not asked only to redo the MFA step for a single MFA factor type.

iamalexmang commented 2 years ago

For reference, in order to implement MFA using the one-time password generated by the Authenticator app, we followed this documentation: https://docs.microsoft.com/en-us/azure/active-directory-b2c/multi-factor-auth-technical-profile

JasSuri commented 2 years ago

Thats odd, RT calls dont invoke the policy in such a way to create a redirect. Is there some error returned as part of the RT token call which results in the redirection to AAD B2C in the first place?

iamalexmang commented 2 years ago

@JasSuri, I'm providing here a video to elaborate the issue: https://1drv.ms/u/s!AiH6U1JLlpoBpZceEc9CNSUpdq1Zsg?e=rIf4pO

At 15:05, the user logged in successfully and successfully validated MFA using a mobile phone number. At 17:37, the user opens the application again and is immediately prompted to redo the MFA step, without being asked for the authentication credentials - I find this to be unnecessary, but open to debate. At this time, the refresh token was still valid, but the access token was not. The user chose the Authentication App MFA factor, but was not prompted to provide the One Time Code from the authenticator app; instead, he is immediately taken to the application protected by B2C.

Some time later, at 18:08, the access token was expired again, but the refresh token was not. This time, instead of choosing the Authenticator App One Time Password factor, the user chose to provide the code transmitted to their phone number.

However, unlike the Authenticator App step, the user must wait for the code to be sent and fill it in, thus having a different experience in comparison to the Authenticator App experience.

JasSuri commented 2 years ago

When you say “ the user opens the application again” - what does that mean? Did the user close the browser and reopen it?

At this time, the refresh token was still valid, but the access token was not.

How did you evaluate this? From the video it would appear that tokens are not in the localStorage cache, causing the redirect to B2C.

Try this test

  1. Open the policy using Run Now link from Azure portal
  2. Sign in
  3. Open Run Now link in a new tab, but remove prompt=login parameter from URL
  4. Do you reproduce the issue?
iamalexmang commented 2 years ago

@JasSuri Yes, the user is closing the browser and opening it up again.

I also tried to reproduce the steps you mentioned and was able to reproduce the error following the steps as they are. I know that the refresh token is valid because it is configured to be valid for 24 hours. When I try to reproduce the steps after a full 24-hours, I'm getting the additional login screen displayed which prompts for the username and password - this doesn't happen when the access token is expired, but the refresh token is not.

JasSuri commented 2 years ago

If the user closes the browser, then you will lose the content of the localStorage, which holds the tokens. So, the application will redirect the user to AAD B2C, where the session cookie is analyzed for SSO. The behavior of closing and reopening the browser can be simulated by the test I mentioned. If the issue reproduces with my test, then there is an issue with the SSO Management at the technical profile level.

When the issue reproduces after 24 hours, and you see an additional U/P screen, then the Web Session SSO Cookie has expired, maximum 24hours, unless you use KMSI. At this point, you will just be doing a fresh logon.

Two different behaviors, two different causes here.