Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Forgot Password in ADB2C - (AADB2C90118), How to run a specific user flow?

Problem

I am trying to handle the 'Reset password' user-flow in my application. Upon clicking the 'Forgot Password' link, the OnRemoteFailure OpenId event is successfully triggered, successfully redirecting to the specified url 'Home/ResetPassword', but instead or redirecting to the ADB2C reset password screen, it's redirecting back to the sign-in/sign-up page.

Background

The sign-up/sign-in policy works successfully but as per Microsoft docs: https://docs.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-reference-policies:

" A sign-up or sign-in user flow with local accounts includes a Forgot password? link on the first page of the experience. Clicking this link doesn't automatically trigger a password reset user flow.

Instead, the error code AADB2C90118 is returned to your application. Your application needs to handle this error code by running a specific user flow that resets the password. To see an example, take a look at a simple ASP.NET sample that demonstrates the linking of user flows. "

Active Directory B2C Settings

AppSettings

UserFlows

UserFlows

Code

OpenIdEvent

protected virtual Task OnRemoteFailure(RemoteFailureContext context)
{
    context.HandleResponse();
    // Handle the error code that Azure AD B2C throws when trying to reset a password from the login page
    // because password reset is not supported by a "sign-up or sign-in policy"
    if (context.Failure is OpenIdConnectProtocolException && context.Failure.Message.Contains("AADB2C90118"))
    {
        // If the user clicked the reset password link, redirect to the reset password route
        context.Response.Redirect("/Home/ResetPassword");                
    }
    else if (context.Failure is OpenIdConnectProtocolException && context.Failure.Message.Contains("access_denied"))
    {
        context.Response.Redirect("/");
    }
    else
    {
        context.Response.Redirect("/Home/Error?message=" + WebUtility.UrlEncode(context.Failure.Message));                
    }          

    return Task.FromResult(0);
}

HomeController

public IActionResult ResetPassword()
{
    var redirectUrl = Url.Action(nameof(HomeController.Index), "Home");
    var properties = new AuthenticationProperties { RedirectUri = redirectUrl };
    properties.Items[AzureADB2COptionsExtended.PolicyAuthenticationProperty] = _adb2cOptions.ResetPasswordPolicyId;
    return Challenge(properties, AzureADB2CDefaults.AuthenticationScheme);
}

OpenIdSignInSignUp

A lot of examples I found use OWIN... There is very limited documentation on ASP.Net Core 2.2 w/ ADB2C.

like image 572
Dash Avatar asked Aug 08 '19 09:08

Dash


1 Answers

The Sign-up-sign-in policy now has built-in support for password resets without a second "password-reset" user flow. It is quite confusing with all the documentation and samples out there but this is the latest docs and it works for us!

https://docs.microsoft.com/en-us/azure/active-directory-b2c/force-password-reset?pivots=b2c-user-flow

like image 162
Ian M Davies Avatar answered Oct 31 '22 11:10

Ian M Davies