31

I have been able to properly setup sign-up/sign-in policy for a tenant I'm testing. I have set the Reset Password property to allow everybody to reset their password using their email. Currently the user signs up using their email (also their username), first name, and last name.

However, when I click on the "I forgot my password" link on the sign in page, B2C just redirects me back to the same page.

How can I resolve this.

ΩmegaMan
  • 29,542
  • 12
  • 100
  • 122
Riz
  • 6,486
  • 19
  • 66
  • 106
  • Regarding gpilotino's point of reset password redirecting back to login page- I found that I did not have fully qualified paths for the password reset url, along w/ a combined sign in/sign up caused this to happen. Once I gave a fully qualified url (debug diff from release) this worked correctly. – A. Smith Aug 17 '18 at 21:18

3 Answers3

43

There are two different mechanisms for Password Reset in Azure AD B2C:

  1. Sign-in Policy: No work required by the application, clicking on "I forgot my password" redirects the user automatically to a generic Microsoft-branded password reset page.

  2. Sign-up/sign-in Policy: This requires the application to do some extra work. Clicking on "I forgot my password" redirects the user back to the application with an error code. The application needs to detect that the error code in the request and then further redirect the user to the Azure AD B2C Password Reset Policy. The Password reset policy can be customized extensively.

Going into more details as to how to implement the second approach, here's the code that hooks up into the AuthenticationFailed notification and redirects to your own PasswordReset controller action, from the B2C Sign-up/Sign-in quickstart, Startup.Auth.cs

private Task AuthenticationFailed(AuthenticationFailedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification)
{
    notification.HandleResponse();

    if (notification.ProtocolMessage.ErrorDescription != null && notification.ProtocolMessage.ErrorDescription.Contains("AADB2C90118"))
    {
        // If the user clicked the reset password link, redirect to the reset password route
        notification.Response.Redirect("/Account/ResetPassword");
    }
    else if (notification.Exception.Message == "access_denied")
    {
        // If the user canceled the sign in, redirect back to the home page
        notification.Response.Redirect("/");
    }
    else
    {
        notification.Response.Redirect("/Home/Error?message=" + notification.Exception.Message);
    }

    return Task.FromResult(0);
}

And here's the code PasswordReset controller action that redirects the user to the Password Reset B2C policy, from the same B2C Sign-up/Sign-in quickstart, Account Controller

public void ResetPassword()
{
    if (!Request.IsAuthenticated)
    {
        HttpContext.GetOwinContext().Authentication.Challenge(
        new AuthenticationProperties() { RedirectUri = "/" }, Startup.PasswordResetPolicyId);
    }
}

Just for sake of completeness, make sure you checkout the full guide/overview of setting up an Azure AD B2C Sign-up/Sign-in Policy

Saca
  • 10,355
  • 1
  • 34
  • 47
  • Thanks for a great answer. I'm trying to work this into an Azure Mobile App, and there doesn't seem to be any provision for handling notification failed scenarios. Any ideas on that one? TIA – Bill Noel Mar 01 '17 at 18:55
  • 1
    @nhwilly using the Microsoft recommended AppAuth-iOS library (or AppAuth-Android) and its OIDAuthState.authState(byPresenting:presenting:callback:) method, then when the user taps "I forgot my password" in the web view your user should be redirected back to your app (using the redirect URI you provided) and in the callback you defined, you should get a nil authState and an error. The error will contain the code, "AADB2C90118". If you detect that, you know that you now need to redirect to the reset password page as mentioned above. – jj0b May 11 '17 at 22:57
  • Thanks. Finally found some samples and worked it out. – Bill Noel May 15 '17 at 18:13
  • 3
    I'm still experiencing this issue. I'm using ADb2C to login into the API management developer portal. It looks like clicking on "I forgot my password" does NOT redirect the user back to the application. It redirects to the same login form instead. You can test it by yourself here: http://agid-apim-test.portal.azure-api.net/ I've tried setting a password reset policy into the API management security-identity settings but with no success. cc @saca – gpilotino Dec 19 '17 at 08:56
  • 1
    This does not work for me? I just keep getting routed to the same sign-in/sign-up policy when I am setting my password reset policy in the action method. Any ideas? – Viktor Jan 19 '18 at 13:52
  • 1
    any idea how I can capture response in MSAL for angular application? – K.Z Feb 02 '18 at 17:42
  • @Viktor make sure your policy names are lowercase in your web.config – pconnor88 Feb 06 '18 at 10:03
  • 3
    UserVoice [Go Direct to Password Reset from Sign-In/Sign-Up](https://feedback.azure.com/forums/169401-azure-active-directory/suggestions/33494830-go-direct-to-password-reset-from-sign-in-sign-up) – spottedmahn Mar 01 '18 at 17:05
  • 1
    Oddly, I can get the sample code to work with a 'sign up/sign in' policy. However, my users should never be able to create an account, so I need this to work with just 'sign in'. It doesn't. I get "you cannot reset your password at this time because your administrator has not configured password reset for your organization." The login page appears to be very different between the two policies. Have you ever actually tested this with only the 'sign in' policy? – Quark Soup May 06 '18 at 22:55
  • You are probably hitting the regular Azure AD page, not the Azure AD B2C page. Can you confirm that the URL has your policy in it? – Saca May 07 '18 at 06:12
  • 1
    Under what circumstances is this redirect with error code behavior for forgot password events helpful, useful, or even remotely sensical? The overwhelmingly vast majority of "forgot password" use cases simply need the user to be automatically routed to a forgot password form and allowed to submit a forgot password request, receive the email, confirm, reset password, get on with life, etc. What is going on at Microsoft with AD B2C?????? Asleep at the wheel it seems. – JTW Apr 09 '19 at 18:29
  • Can I somehow disable the 1st option of branded MS password reset? I do not want the link in username/password window at all ... – Honza P. Aug 22 '19 at 12:13
21

I've been experiencing the same problem, and came up a JavaScript workaround to point the "Forget Password" url directly to the "reset password" policy without changing the code in your connected web app (web/mobile/whatever)

1. I assume you have 3 standard policies like screenshot below:

Standard User flows

2. Go to you "Signup and sign in policy" and enable Javascript

a. click you "Signup and sign in policy" -> Properties

b. Enable JavaScript as per screenshot below

Enable Javascript

3. Following that Microsoft article, it will guide you in how to create a custom UI for your Sign in/Sign up pages

a. Download the ready made template (Ocean Blue) for sing in/sign up (By the way it looks much better than the built in classic old one; where you can change the background and logo too)

https://github.com/Azure-Samples/Azure-AD-B2C-page-templates/tree/master/ocean_blue

There you will find other templates too.

b. Upload this folder as it is to any hosting or Azure blob storage

c. Just make sure you enable CORS for your hosting or Azure (easy way through Azure Storage Explorer)

4. Write the Javascript required.

  • Point your Sign-in/Sign-up policy to your template html as per screenenter image description here
  • go to your policy and Run workflow, if you see it working go to next step
  • Add the required Javascript; On link clicked, we are taking the current url which is the signsignup, replace the policy name by the reset policy, make sure you put here your policy names (not mine), or leave it as the instructions if you are using the same policy names

    <script>
    $(function() {
        console.log( "ready!" );
    
        //Change Forget Password Text
        $('#forgotPassword').html('Reset My Password');
    
    
        //Handle Forget password click  (fixing ADB2C error)
        $( "#forgotPassword" ).click(function(e) {
            e.preventDefault();
    
    
            var oldUrl = window.location.href;
            var newUrl = oldUrl.replace('B2C_1_signupsignin1','B2C_1_passwordreset1');
    
            window.location.href = newUrl;
    
        });
    
      });
    

N.B: Let me know if I have missed any step, I tried to be elaborating as much as possible.

Bishoy Hanna
  • 4,539
  • 1
  • 29
  • 31
  • 1
    This is a great answer for when you are trying to use the out-of-the-box flows as much as possible and don't need to run any custom code in the application. Thanks for sharing, it's working great for me! – Garrison Neely Nov 22 '19 at 18:22
  • 2
    @Garisson, very happy to know it has fixed your problem , and yea its out of the box solution – Bishoy Hanna Nov 23 '19 at 22:43
  • 1
    Thanks, just need another handler for the cancel link in the "Send varification" page. – Chris Gunawardena Apr 07 '20 at 10:02
  • @ChrisGunawardena - you don't need to handle that specially. This url is the callback url you set in flow and then you have it in the flow's url. – Miq Jul 27 '20 at 21:45
  • 1
    https://learn.microsoft.com/en-us/azure/active-directory-b2c/javascript-samples#guidelines-for-using-javascript says not to bind a click event on "" (#forgotPassword) – ninjaas Dec 01 '20 at 19:43
0

Instead of choosing the 'Recommended' user flow in the Azure portal for the B2C instance, you could also try with the 'Standard' one - although it doesn't look so nice as the former.