【发布时间】: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