我正在尝试更改Azure AD用户密码。
已经使用隐式流和adal
库在 SPA 应用程序中对用户进行了身份验证。
调用时:
return await graphClient.Me.Request().UpdateAsync(new User
{
PasswordProfile = new PasswordProfile
{
Password = userPasswordModel.NewPassword,
ForceChangePasswordNextSignIn = false
},
});
我遇到此异常:
{“代码:Request_ResourceNotFound \ r \ n消息:资源 '35239a3d-67e3-4560-920a-2e9ce027aeab'不存在或其中之一 查询的参考属性对象不存在。\ r \ n \ r \ n内部 错误\ r \ n“}
调试通过Microsoft Client SDK
获得的访问令牌,我看到此 GUID 是指oid
和sub
属性。见下文:
这是我用来获取令牌的代码:
IConfidentialClientApplication clientApp =
ConfidentialClientApplicationBuilder.Create(Startup.clientId)
.WithAuthority(string.Format(AuthorityFormat, Startup.tenant))
.WithRedirectUri(Startup.redirectUri)
.WithClientSecret(Startup.clientSecret)
.Build();
var authResult = await clientApp.AcquireTokenForClient(new[] { MSGraphScope }).ExecuteAsync();
return authResult.AccessToken;
我正在 SPA 应用程序中使用隐式流程。在进行ClaimsPrincipal.Current
时,我看到我的用户已经过身份验证,并且所有声明都存在。
我已经阅读了很多@GitHub和Microsoft Docs的文档,但是我仍然不清楚如何实现它。 顺便说一下,我正在使用以下Microsoft Graph软件包:
<package id="Microsoft.Graph" version="1.15.0" targetFramework="net461" />
<package id="Microsoft.Graph.Auth" version="0.1.0-preview.2" targetFramework="net461" />
<package id="Microsoft.Graph.Core" version="1.15.0" targetFramework="net461" />
我想我并没有解决这个问题,因为我应该为用户获取令牌,而不是为应用程序获取令牌。我应该改用clientApp.AcquireTokenOnBehalfOf
吗?
如果是,建议使用Microsoft Graph API SDK为当前登录用户获取令牌的推荐方法是什么?
你能阐明一些想法吗?
####### 编辑 #######
使用此功能,我可以取得一些进步
var bearerToken = ClaimsPrincipal.Current.Identities.First().BootstrapContext as string;
JwtSecurityToken jwtToken = new JwtSecurityToken(bearerToken);
var userAssertion = new UserAssertion(jwtToken.RawData, "urn:ietf:params:oauth:grant-type:jwt-bearer");
IEnumerable<string> requestedScopes = jwtToken.Audiences.Select(a => $"{a}/.default");
var authResult = clientApp.AcquireTokenOnBehalfOf(new[] { MSGraphScope }, userAssertion).ExecuteAsync().GetAwaiter().GetResult();
return authResult.AccessToken;
但是现在我得到了错误:
权限不足,无法完成操作。 authorization_requestdenied
答案 0 :(得分:2)
经过长时间的调试(大约8个小时),在看到@Michael Mainer的this answer之后,我终于能够得到想要的东西。
这是我编写的“正确”代码:
public async Task<User> ChangeUserPassword(UserPasswordModel userPasswordModel)
{
try
{
var graphUser = ClaimsPrincipal.Current.ToGraphUserAccount();
var newUserInfo = new User()
{
PasswordProfile = new PasswordProfile
{
Password = userPasswordModel.NewPassword,
ForceChangePasswordNextSignIn = false
},
};
// Update the user...
return await graphClient.Users[graphUser.ObjectId].Request().UpdateAsync(newUserInfo);
}
catch(Exception e)
{
throw e;
}
}
注意1:使用
graphClient.Users[graphUser.ObjectId]
代替graphClient.Me
注释2:
.ToGraphUserAccount()
来自Microsoft.Graph.Auth。
我在Postman中有一个示例PATCH
请求,可以为用户正确设置新密码。
Postman的Authorization
请求标头中使用的访问令牌具有与我使用Microsoft Graph API获取的格式\属性相同的格式\属性。我只是使用jwt.io比较了它们。所以我一定打错了电话...
我改用clientApp.AcquireTokenForClient
:
var authResult = await clientApp.AcquireTokenForClient(new[] { MSGraphScope }).ExecuteAsync();
return authResult.AccessToken;
其中:
MSGraphScope = "https://graph.microsoft.com/.default"