Как установить URL ресурса для GraphServiceClient для получения групп? - PullRequest
0 голосов
/ 25 июня 2019

Я пытаюсь получить группы AD из API Graph, используя значение конечной точки groups:src1, которое я получаю от _claims_sources в токене доступа JWT .

Мой клиент используетУчетные данные клиента и могут извлекать информацию для всех пользователей и групп в AD.

Вот как я его настраиваю:

private async Task<IList<Group>> GetUserGroupsAsync(string endpoint)
{
    // Endpoint is from the claims in a previous OIDC request

    // Setup a client if it does not exist
    PrepareGraphApiClient();

    // I can fetch my groups using the methods in the client
    // var groupPage = await graphServiceClient.Me.MemberOf.Request().GetAsync();

    // This is where I would like to use the resource URL received from the
    // claims I receive in a previous OIDC request
    var groupPageFromUrl = ???

    ...
}

private void PrepareGraphApiClient()
{
    if (graphServiceClient != null) return;

    try
    {
        AuthenticationContext authority = new AuthenticationContext(oidcOptions.Authority);
        ClientCredential clientCredential = new ClientCredential(oidcOptions.ClientId, oidcOptions.ClientSecret);

        var graphApiResource = "https://graph.microsoft.com";
        AuthenticationResult authenticationResult = authority.AcquireTokenAsync(graphApiResource, clientCredential).Result;

        graphServiceClient = new GraphServiceClient(new DelegateAuthenticationProvider(
            async requestMessage =>
            {
                // Add token to outgoing requests
                requestMessage.Headers.Authorization =
                    new AuthenticationHeaderValue("Bearer", authenticationResult.AccessToken);
            }));
    }
    catch (Exception ex)
    {
        logger.LogDebug($"Could not create the graph client {ex}");
        throw;
    }
}

Могу ли я использовать URL ресурса из утверждений с GraphServiceClientили мне нужно настроить HttpClient для выполнения запроса?

1 Ответ

1 голос
/ 26 июня 2019

Конечная точка, указанная в _claim_sources.src1, предназначена для Azure AD Graph, поэтому используемый вами токен должен быть для API Azure AD Graph (https://graph.windows.net), а не для Microsoft Graph (https://graph.microsoft.com).Это также означает, что вы не можете использовать Microsoft Graph SDK, так как запросы и ответы API принципиально отличаются.

У вас есть два варианта:

  1. (рекомендуется) Использованиетот факт, что конечная точка указывается только как указание на необходимость поиска и совершения эквивалентного вызова Microsoft Graph с использованием Microsoft Graph SDK:

    var memberOfIds = await graphServiceClient
            .Users[userObjectId]                          # from the 'oid' in access token
            .GetMemberObjects(securityEnabledOnly: true) # true if groupMembershipClaims is "SecurityGroup", false if it's "All"
            .Request()
            .PostAsync();
    
  2. Используйте заданную конечную точку и создайте свои собственные запросы к Microsoft Graph, используя (например) HttpClient.Быстрый и грязный пример:

    using (var client = new HttpClient())
    {
        # Always get the token right before you use it. ADAL will take care of getting a new one
        # if needed, or using an existing cached token if not.
        authenticationResult = 
            authority.AcquireTokenAsync("https://graph.windows.net", clientCredential)
        client.DefaultRequestHeaders.Authorization = 
            new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
    
        # Make the API request to Azure AD Graph. Note we have to include the api-version and
        # the request body.
        HttpResponseMessage response = await client.PostAsync(
            $"{src}?api-version=1.6", new StringContent(
                "{'securityEnabledOnly': true}", # true if groupMembershipClaims is "SecurityGroup", false if it's "All"
                UnicodeEncoding.UTF8,
                "application/json"));
        if (response.IsSuccessStatusCode)
        {
            # Note we're deserializing as if it were a Microsoft Graph response to getMemberObjects,
            # rather than an Azure AD Graph response. Though it works, this is somewhat risky, and
            # it would be more correct to explicitly define the form of an Azure AD Graph response.
            var memberOfIds = JsonConvert.DeserializeObject<DirectoryObjectGetMemberObjectsCollectionResponse>(
                await response.Content.ReadAsStringAsync()).Value;
        }
    }
    

В качестве примечания, я замечаю, что у вас есть призыв приобрести токен вне из DelegateAuthenticationProvider вы передали в библиотеку Microsoft Graph.Вы должны поместить AcquireTokenAsync call в , чтобы он получал свежий токен для каждого запроса Microsoft Graph.Библиотека (ADAL) позаботится об использовании кэшированного токена (если таковой имеется) или создании нового запроса токена (если ни один из них не доступен или если срок действия доступных периодов истек).Примерно так:

    graphServiceClient = new GraphServiceClient(new DelegateAuthenticationProvider(
        async requestMessage =>
        {
            // Get fresh token
            AuthenticationResult authenticationResult = 
                await authority.AcquireTokenAsync(graphApiResource, clientCredential);

            // Add token to outgoing requests
            requestMessage.Headers.Authorization =
                new AuthenticationHeaderValue("Bearer", authenticationResult.AccessToken);
        }));
...