Authentication 资源';此处的GUID值';不存在或其查询的引用特性对象之一不存在

Authentication 资源';此处的GUID值';不存在或其查询的引用特性对象之一不存在,authentication,microsoft-graph-api,access-token,change-password,microsoft-graph-sdks,Authentication,Microsoft Graph Api,Access Token,Change Password,Microsoft Graph Sdks,我正在尝试更改Azure广告用户密码 用户已经在SPA应用程序中使用隐式流和adal库进行身份验证 打电话时: return await graphClient.Me.Request().UpdateAsync(new User { PasswordProfile = new PasswordProfile { Password = us

我正在尝试更改Azure广告用户密码

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

打电话时:

return await graphClient.Me.Request().UpdateAsync(new User
                {
                    PasswordProfile = new PasswordProfile
                    {
                        Password = userPasswordModel.NewPassword,
                        ForceChangePasswordNextSignIn = false
                    },
                });
我得到一个例外:

{“代码:请求\u 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 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" />
但现在我得到了一个错误:

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


经过长时间的调试(8个小时左右),我终于能够在看到@Michael Mainer之后得到我想要的东西

这是我编写的“正确”代码:

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;
    }
}
其中:

MSGraphScope = "https://graph.microsoft.com/.default"

经过长时间的调试(8个小时左右),我终于能够在看到@Michael Mainer之后得到我想要的东西

这是我编写的“正确”代码:

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;
    }
}
其中:

MSGraphScope = "https://graph.microsoft.com/.default"

发布这个问题后,我发现我有点困惑。您提到使用隐式OAuth授权,但您获得的令牌包含
Roles
而不是
scp
。角色是应用程序cope(客户端凭据),这意味着您没有在此处使用隐式。您想要的是使用
目录.AccessAsUser.All
作用域来隐含。只是澄清一下,应用程序作用域(
角色
)不能用于重置用户密码。只有委派的作用域支持重置密码。这确保了任何密码重置都可以被审核回特定的用户(“他们说这是一个让人窒息的喉咙)。@Marclafler感谢您的来访和澄清。我求助于使用原始的
clientApp.AcquireTokenForClient
,而不是
clientApp.AcquireTokenOnBehalfOf
。在下面贴了一个答案。刚贴完这个问题,我发现我有点困惑。您提到使用隐式OAuth授权,但您获得的令牌包含
Roles
而不是
scp
。角色是应用程序cope(客户端凭据),这意味着您没有在此处使用隐式。您想要的是使用
目录.AccessAsUser.All
作用域来隐含。只是澄清一下,应用程序作用域(
角色
)不能用于重置用户密码。只有委派的作用域支持重置密码。这确保了任何密码重置都可以被审核回特定的用户(“他们说这是一个让人窒息的喉咙)。@Marclafler感谢您的来访和澄清。我求助于使用原始的
clientApp.AcquireTokenForClient
,而不是
clientApp.AcquireTokenOnBehalfOf
。在下面贴出了答案。