资源“此处的 GUID 值"不存在或其查询的引用属性对象之一不存在 [英] Resource 'GUID value here' does not exist or one of its queried reference-property objects are not present
问题描述
我正在尝试更改 Azure AD 用户密码.
用户已经使用隐式流程和adal
库在SPA应用程序中进行了身份验证.
通话时:
return await graphClient.Me.Request().UpdateAsync(new User{密码配置文件 = 新的密码配置文件{密码 = userPasswordModel.NewPassword,ForceChangePasswordNextSignIn = false},});
我收到此异常:
<块引用>{"代码:Request_ResourceNotFound 消息:资源'35239a3d-67e3-4560-920a-2e9ce027aeab' 不存在或其之一查询的引用属性对象不存在. 内部错误 "}
调试我使用 Microsoft Client SDK
获得的访问令牌我看到这个 GUID 指的是 oid
和 sub代码> 属性.见下文:
这是我用来获取令牌的代码:
IConfidentialClientApplication clientApp =ConfidentialClientApplicationBuilder.Create(Startup.clientId).WithAuthority(string.Format(AuthorityFormat, Startup.tenant)).WithRedirectUri(Startup.redirectUri).WithClientSecret(Startup.clientSecret).建造();var authResult = await clientApp.AcquireTokenForClient(new[] { MSGraphScope }).ExecuteAsync();返回 authResult.AccessToken;
我在 SPA 应用程序中使用了隐式流程.在执行 ClaimsPrincipal.Current
时,我看到我的用户已通过身份验证并且所有声明都存在.
我在 GitHub 和 Microsoft Docs 上阅读了很多文档,但我仍然不清楚如何实现这一点.顺便说一句,我正在使用这些 Microsoft Graph 包:
<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");IEnumerablerequestScopes = jwtToken.Audiences.Select(a => $"{a}/.default");var authResult = clientApp.AcquireTokenOnBehalfOf(new[] { MSGraphScope }, userAssertion).ExecuteAsync().GetAwaiter().GetResult();返回 authResult.AccessToken;
但现在我收到错误:
<块引用>权限不足,无法完成操作.授权请求被拒绝
经过长时间的调试会话(8 小时左右),我终于在看到
Postman 的Authorization
请求标头中使用的访问令牌与我使用 Microsoft Graph API 获取的格式属性具有相同的格式属性.我只是使用 jwt.io 比较了它们.所以我一定是叫错了什么...
我用 clientApp.AcquireTokenForClient
代替:
var authResult = await clientApp.AcquireTokenForClient(new[] { MSGraphScope }).ExecuteAsync();返回 authResult.AccessToken;
哪里:
MSGraphScope = "https://graph.microsoft.com/.default"
I'm trying to change an Azure AD user password.
The user is already authenticated in a SPA application using the implicit flow and the adal
library.
While calling:
return await graphClient.Me.Request().UpdateAsync(new User
{
PasswordProfile = new PasswordProfile
{
Password = userPasswordModel.NewPassword,
ForceChangePasswordNextSignIn = false
},
});
I'm getting this exception:
{"Code: Request_ResourceNotFound Message: Resource '35239a3d-67e3-4560-920a-2e9ce027aeab' does not exist or one of its queried reference-property objects are not present. Inner error "}
Debugging the access token I got with Microsoft Client SDK
I see that this GUID is referring to the oid
and sub
properties. See below:
This is the code I use to acquire the token:
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;
I'm using the implicit flow in a SPA application. While doing ClaimsPrincipal.Current
I see that my user is authenticated and all claims are present.
I've read a lot of docs @ GitHub and Microsoft Docs but it's still not clear in my mind how to implement this. By the way, I'm using these Microsoft Graph packages:
<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" />
I guess I'm not approaching this correclty because instead of acquiring a token for the application I should acquire a token for the user. Should I use clientApp.AcquireTokenOnBehalfOf
instead?
If so what's the recommended way of acquiring a token for the currently logged in user using Microsoft Graph API SDK?
Can you shed some light?
####### EDIT #######
I was able to make some progress using this:
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;
but now I'm getting the error:
insufficient privileges to complete the operation. authorization_requestdenied
After a long debugging session (8 hours or so) I was finally able to get what I wanted after I saw this answer by @Michael Mainer.
This is the "right" code I put together:
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;
}
}
Note 1:
graphClient.Users[graphUser.ObjectId]
is being used instead ofgraphClient.Me
Note 2:
.ToGraphUserAccount()
is from Microsoft.Graph.Auth.
I had a sample PATCH
request in Postman that correctly set a new password for the user.
The Access Token used in Postman's Authorization
request-header had the same formatproperties from the one I was acquiring with Microsoft Graph API. I just compared them using jwt.io. So I must've been calling something wrongly...
I used clientApp.AcquireTokenForClient
instead:
var authResult = await clientApp.AcquireTokenForClient(new[] { MSGraphScope }).ExecuteAsync();
return authResult.AccessToken;
where:
MSGraphScope = "https://graph.microsoft.com/.default"
这篇关于资源“此处的 GUID 值"不存在或其查询的引用属性对象之一不存在的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!