简体   繁体   English

在 ADB2C 中忘记密码 - (AADB2C90118),如何运行特定的用户流程?

[英]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.单击“忘记密码”链接后,成功触发 OnRemoteFailure OpenId 事件,成功重定向到指定的 url“Home/ResetPassword”,但不是重定向到 ADB2C 重置密码屏幕,而是重定向回登录/登录-向上页面。

Background背景

The sign-up/sign-in policy works successfully but as per Microsoft docs: https://learn.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-reference-policies :注册/登录策略成功运行,但根据 Microsoft 文档: https://learn.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.相反,错误代码 AADB2C90118 会返回到您的应用程序。 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.要查看示例,请查看演示用户流链接的简单 ASP.NET 示例。 "

Active Directory B2C Settings活动目录 B2C 设置

应用程序设置

UserFlows用户流程

用户流程

Code代码

OpenIdEvent打开IdEvent

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.我发现很多使用 OWIN 的例子......关于 ASP.Net Core 2.2 w/ADB2C 的文档非常有限。

Here is the complete sample for your reference. 以下是完整的样本供您参考。 It works fine on my side. 它在我身边很好用。 You can download that sample and check the code. 您可以下载该示例并检查代码。

The Sign-up-sign-in policy now has built-in support for password resets without a second "password-reset" user flow. Sign-up-sign-in 策略现在内置了对密码重置的支持,无需第二个“密码重置”用户流程。 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 https://docs.microsoft.com/en-us/azure/active-directory-b2c/force-password-reset?pivots=b2c-user-flow

Answer that was posted in the question:在问题中发布的答案:

For anyone else having the same or similar issue, make sure to keep an eye out on the OpenIdConnectEvents.对于遇到相同或类似问题的任何其他人,请务必留意 OpenIdConnectEvents。 We have been experimenting with ADB2C/OpenID and had test code.我们一直在试验 ADB2C/OpenID 并有测试代码。 This code was obviously invalid.这段代码显然是无效的。

protected virtual Task OnRedirectToIdentityProvider(RedirectContext context)
{
    string policy = "";
    context.Properties.Items.TryGetValue(AzureADB2COptionsExtended.PolicyAuthenticationProperty, out policy);
    if (!string.IsNullOrEmpty(policy) && !policy.ToLower().Equals(_adb2cOptions.DefaultPolicy.ToLower()))
    {
        context.ProtocolMessage.Scope = OpenIdConnectScope.OpenId;
        context.ProtocolMessage.ResponseType = OpenIdConnectResponseType.IdToken;
        context.ProtocolMessage.IssuerAddress = context.ProtocolMessage.IssuerAddress.ToLower().Replace(_adb2cOptions.DefaultPolicy.ToLower(), policy.ToLower());
    }
    return Task.FromResult(0);
}

Normally, the ResetPassword flow you configured in your appsettings.json is called automatically when using the Microsoft.Identity.Web package.通常,您在appsettings.json配置的 ResetPassword 流会在使用Microsoft.Identity.Web包时自动调用。 In your case B2C_1_SSPR .在你的情况下B2C_1_SSPR That means you must define a custom user flow with this Id.这意味着您必须使用此 ID 定义自定义用户流。 (I guess SSPR = self-service password reset) (我猜SSPR=自助密码重置)

The only thing you need in this default case is call the following in your Startup :在这种默认情况下,您唯一需要的是在您的Startup调用以下内容:

services.AddMicrosoftIdentityWebAppAuthentication(Configuration, "ActiveDirectoryB2C");

This works like a charm.这就像一个魅力。

However, you decided to deal with all this stuff by yourself and not to use the Microsft.Identity.Web library for all processing.但是,您决定自己处理所有这些事情,而不是使用Microsft.Identity.Web库进行所有处理。 In this case you are able to handle Password-reset by yourself.在这种情况下,您可以自行处理密码重置。

But let's have a look at the Microsft.Identity.Web .但是让我们看看Microsft.Identity.Web They integrated an AccountController that handles the processing of the B2C custom flows (in this case the ResetPassword action).他们集成了一个AccountController来处理 B2C 自定义流的处理(在本例中是ResetPassword操作)。

The exception handling for AADB2C90118 can be found in the source code of the Identity package: AADB2C90118的异常处理可以在Identity包的源码中找到:

 if (isOidcProtocolException && message.Contains(ErrorCodes.B2CForgottenPassword))
 {
     // If the user clicked the reset password link, redirect to the reset password route
     context.Response.Redirect($"{context.Request.PathBase}/MicrosoftIdentity/Account/ResetPassword/{SchemeName}");
 }

See the latest "Self-Service Password Reset" policy (custom or non-custom) from Microsoft docs.请参阅 Microsoft 文档中的最新“自助服务密码重置”策略(自定义或非自定义)

From the doc:从文档:

"The new password reset experience is now part of the sign-up or sign-in policy. When the user selects the Forgot your password? link, they are immediately sent to the Forgot Password experience. Your application no longer needs to handle the AADB2C90118 error code, and you don't need a separate policy for password reset." “新的密码重置体验现在是注册或登录策略的一部分。当用户选择忘记密码?链接时,他们会立即发送到忘记密码体验。您的应用程序不再需要处理 AADB2C90118错误代码,您不需要单独的密码重置策略。”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM