资源“此处的 GUID 值”不存在或其查询的引用属性对象之一不存在

Posted

技术标签:

【中文标题】资源“此处的 GUID 值”不存在或其查询的引用属性对象之一不存在【英文标题】:Resource 'GUID value here' does not exist or one of its queried reference-property objects are not present 【发布时间】:2019-10-26 01:37:18 【问题描述】:

我正在尝试更改 Azure AD 用户密码。

用户已在 SPA 应用程序中使用 隐式流adal 库进行身份验证。

通话时:

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 指的是oidsub 属性。见下文:

这是我用来获取令牌的代码:

 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;

但现在我得到了错误:

权限不足,无法完成操作。 授权请求被拒绝

【问题讨论】:

刚刚发布了这个问题,我发现了这个github.com/AzureAD/microsoft-authentication-library-for-dotnet/… 我有点困惑。您提到使用隐式 OAuth 授权,但您获得的令牌包含 Roles 而不是 scp。角色是应用程序应对(客户端凭据),这意味着您在这里没有使用隐式。您想要的是使用 Directory.AccessAsUser.All 范围的隐式。 澄清一下,应用程序范围 (roles) 不能用于重置用户密码。只有委托范围支持重置密码。这确保了任何密码重置都可以被审核回特定用户(正如他们所说的“窒息的喉咙”)。 @MarcLaFleur 感谢您的光临和澄清。我求助于使用原始的clientApp.AcquireTokenForClient 而不是clientApp.AcquireTokenOnBehalfOf。在下面发布了答案。 【参考方案1】:

经过长时间的调试(大约 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"

【讨论】:

以上是关于资源“此处的 GUID 值”不存在或其查询的引用属性对象之一不存在的主要内容,如果未能解决你的问题,请参考以下文章

无法找到资源。 说明: HTTP 404。您正在查找的资源(或者它的一个依赖项)可能已被移除,或其名称已更改

MVC 3.0错误 HTTP 404您正在查找的资源(或者它的一个依赖项)可能已被移除,或其名称已更改,或暂时不可用。请检查以下 URL 并确保其拼写正确。

约束或其锚点是不是引用不同视图层次结构中的项目?这是违法的

说明: HTTP 404。您正在查找的资源(或者它的一个依赖项)可能已被移除,或其名称已更改 【怎么解决呢?】

“您正在寻找的资源(或其依赖项之一)”错误 WCF REST

Azure SQL 托管实例错误“无法加载 DLL odsole70.dll 或其引用的 DLL 之一”