Ресурс «Значение GUID здесь» не существует или отсутствует один из его запрашиваемых объектов ссылочных свойств. - PullRequest
1 голос
/ 11 июня 2019

Я пытаюсь изменить пароль пользователя Azure AD.

Пользователь уже аутентифицирован в приложении SPA с использованием неявного потока 1006 * и библиотеки 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Внутренний ошибка \ г \ п "}

Отладка токена доступа, который я получил с помощью Microsoft Client SDK Я вижу, что этот GUID относится к свойствам oid и sub. Смотрите ниже:

enter image description here

Это код, который я использую для получения токена:

 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

1 Ответ

2 голосов
/ 12 июня 2019

После долгого сеанса отладки (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;
    }
}

Примечание 1: graphClient.Users[graphUser.ObjectId] используется вместо graphClient.Me

Примечание 2: .ToGraphUserAccount() от Microsoft.Graph.Auth.

У меня был пример PATCH запроса в Почтальон , который правильно установил новый пароль для пользователя.

enter image description here

токен доступа , используемый в заголовке запроса 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"
...