【问题标题】:how to change AD B2C user password using ms graph api from within asp.net mvc如何在 asp.net mvc 中使用 ms graph api 更改 AD B2C 用户密码
【发布时间】:2021-02-26 13:11:09
【问题描述】:

我想允许用户通过提供当前密码和新密码来更改我的应用程序中的密码(不是重置,而是实际更改)。

看着documentation,我试过了,调用没有失败,但是旧密码和新密码都不起作用,我不得不删除用户。作为参考,我将发布我的代码:

    var graphClient = GetGraphServiceClient();

    var identity = new ObjectIdentity
    {
        Issuer = Globals.Tenant,
        IssuerAssignedId = userEmail,
        SignInType = "emailAddress"
    };

    var user = new User
    {
        PasswordProfile = new PasswordProfile
        {
            Password = newPassword
        },
        Identities = new ObjectIdentity[] { identity }
    };

    await graphClient.Users[userId]
        .Request()
        .UpdateAsync(user);

我从文档中推测并环顾四周,这不是执行此操作的正确方法,因为我需要代表已登录用户而不是应用程序执行此操作。但是,对于 AD B2C,在门户下,我无法向我注册的应用授予除 open_id 或 offline_access 之外的委托权限。

在遇到this 之后,我认为我需要使用登录用户的访问令牌而不是应用程序的访问令牌来实际尝试此调用。所以我将用户的令牌代码分配给一个声明,以便我以后可以访问它:

//in startup.auth.cs
 private async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedNotification notification)
        {
            try
            {
                notification.AuthenticationTicket.Identity.AddClaim(new Claim("access_token", notification.Code));

...

//in changePassword() method:
            //retrieve user access code from the claim stored previously when logging them in.
            var userToken = ClaimsPrincipal.Current.FindFirst("access_token").Value;

            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri(Globals.GraphApiEndpoint);
                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", userToken);
                try
                {
                    JObject o = JObject.FromObject(new
                    {
                        currentPassword,
                        newPassword
                    });
                    await client.PostAsJsonAsync($"v1.0/me/changePassword/", o.ToString());

                }
                catch(Exception ex)
                {
                    //never any exception. always succeeds!
                }
            }

无论我输入什么密码,上述方法总是成功。但密码显然根本没有改变。我究竟做错了什么?有没有其他方法可以做到这一点?

编辑:如果我执行以下操作,我的第一种方法似乎有效:

            var user = new User
            {
                PasswordProfile = new PasswordProfile
                {
                    Password = newPassword,
                    ForceChangePasswordNextSignIn = false
                },
                Identities = new ObjectIdentity[] { identity }
            };

            var userInfo = await graphClient.Users[userId]
                .Request()
                .UpdateAsync(user);

但是,现在的问题是我无法首先使用用户的旧密码进行验证,因为它只接受新密码并更新它。有什么想法吗?

编辑 2:通过邮递员尝试并在尝试使用获取用户令牌的第二种方法并在“v1.0/me/changePassword/”端点请求它时得到“x5t 无效”后,我能够找到此回复here:

“很遗憾,B2C 租户不支持此方法来重置密码,因为 B2C 租户的 Graph API 中没有 UserAuthenticationMethod.ReadWrite.all 权限。B2C 租户中唯一可用的委托权限是offline_access 和 openID。在 B2C 租户中重置密码的可用方法是管理员通过 Azure 门户执行密码重置或使用密码重置策略。

目前仅标准 Azure AD 租户支持通过 Graph API 重置密码。您可以在我们的反馈门户上发布关于 B2C 租户中此功能的想法。”

所以我猜我以某种方式能够使用图形 api 更改上面的密码配置文件这一事实不应该发生?

【问题讨论】:

  • 感谢@JasSuri-MSFT。这就是我得出的结论。我刚刚更新了我的帖子。令人沮丧的是,我不得不花这么多时间来做这件事,而不是在文档中明确指出。 AD B2C 团队确实需要改进他们的文档。到目前为止,我尝试做的每一件事都因为文档混乱或缺失而陷入困境。
  • 你学到的东西并不意外。 AAD B2C 包含 B2C 和 AAD 功能,具体取决于您使用的端点。在此处查看说明stackoverflow.com/a/62693315/8357357
  • 我不知道为什么它不会出乎意料。我希望这样的产品具有一致性,而不是所有地方的特殊情况。

标签: asp.net-mvc microsoft-graph-api azure-ad-b2c


【解决方案1】:

B2C 租户中唯一可用的委派权限是 offline_access 和 openID。

这不是真的。

要调用 Microsoft Graph API,您必须使用 AAD auth flow 而不是 AAD B2C 身份验证流。因此,您无需使用与您的 b2c 用户流使用的相同的 AAD 应用程序(应用程序注册)。

您可以创建一个新的 AAD 应用,其类型为仅限此组织目录中的帐户(仅限您的 b2c 租户 - 单一租户) 或 任何组织目录中的帐户(任何 Azure AD 目录 -多租户)。

然后您可以将 Microsoft Graph 权限 UserAuthenticationMethod.ReadWrite.all 分配给它,并使用这个新的 AAD 应用生成访问令牌以调用 Microsoft Graph。

类型为任何身份提供者或组织目录中的帐户(用于使用用户流对用户进行身份验证)的 AAD 应用无法添加 Microsoft 委派权限。

我们可以成功调用Microsoft Graph Explorer中的POST https://graph.microsoft.com/v1.0/me/changePassword为B2C用户修改密码,这也证明Microsoft Graph确实适用于B2C用户。

同理,使用Update user修改密码也是可行的。

但是,现在的问题是我无法首先使用 用户的旧密码,因为它只接受新密码和更新 它。有什么想法吗?

我不太明白can't first validate this using the user's old password 是什么意思。如果您需要调查此方向,请提供有关此问题的更多详细信息。

【讨论】:

  • 我可以通过策略路由来做到这一点——这允许我确认旧密码,然后按照标准做法提供新密码。这就是我所说的“验证用户的旧密码”的意思。
  • 我知道我们现在可以使用 AD 而不是 AD B2C 身份验证流程来做这种事情,但我的观点仍然像它在 B2C 门户中所说的那样以及根据您的开发人员所说的 AD B2C 只允许 open_id 和离线委托权限。我最初提供的链接指向微软开发人员回复的微软论坛,该论坛指出完全相同的事情。如果你错过了,这里又是:docs.microsoft.com/en-us/answers/questions/246207/…
  • 至于您刚刚提供的信息,您必须承认这很混乱,也没有明确说明我必须使用 AAD 而不是 AD B2C auth flow 才能使用 Microsoft Graph API。如果我不应该将 Graph API 与 AD B2C 一起使用,那么为什么您的文档声称我可以? docs.microsoft.com/en-us/azure/active-directory-b2c/…
  • @Riz 我没有错过。你能试试我的建议吗?
  • 嗨@SebastianBudka,我已经用这个链接发布了一个答案:docs.microsoft.com/en-us/azure/active-directory-b2c/… 但显然 Machavity 已经不必要地删除了它。希望对您有所帮助。
猜你喜欢
  • 2018-01-16
  • 2018-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多