0
votes

I am using below code to get all user information such as DisplayName ,Office ,Manager name ,Office Phones etc.

But for few users ,its not returning Mobile Phone and Office Phone information.

using Microsoft.Graph;
using Microsoft.Identity.Client;
using System;

namespace MSGraphAPI
{
    class Program
    {


        private static string clientId = "XXXXXXXXXX";


        private static string tenantID = "XXXXX";


        private static string objectId = "XXXXX";


        private static string clientSecret = "XXXX";

        static async System.Threading.Tasks.Task Main(string[] args)
        {




            //     IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
            //.Create(clientId)
            //.WithTenantId(tenantID)
            //.WithClientSecret(clientSecret)
            //.Build();

            //        ClientCredentialProvider authProvider = new ClientCredentialProvider(confidentialClientApplication);

            //        GraphServiceClient graphClient = new GraphServiceClient(authProvider);

            //        var users = await graphClient.Users
            //            .Request()
            //            .GetAsync();

            int Flag = 0;
            var tenantId = "XXXXX.onmicrosoft.com";

            // The client ID of the app registered in Azure AD
            var clientId = "XXXX";

            // *Never* include client secrets in source code!
            var clientSecret = "XXXXX"; // Or some other secure place.

            // The app registration should be configured to require access to permissions
            // sufficient for the Microsoft Graph API calls the app will be making, and
            // those permissions should be granted by a tenant administrator.
             var scopes = new string[] { "https://graph.microsoft.com/.default" };


            // Configure the MSAL client as a confidential client
            var confidentialClient = ConfidentialClientApplicationBuilder
                .Create(clientId)
                .WithAuthority($"https://login.microsoftonline.com/XXXX.onmicrosoft.com/v2.0")
                .WithClientSecret(clientSecret)
                .Build();

            // Build the Microsoft Graph client. As the authentication provider, set an async lambda
            // which uses the MSAL client to obtain an app-only access token to Microsoft Graph,
            // and inserts this access token in the Authorization header of each API request. 
            GraphServiceClient graphServiceClient =
                new GraphServiceClient(new DelegateAuthenticationProvider(async (requestMessage) => {

        // Retrieve an access token for Microsoft Graph (gets a fresh token if needed).
        var authResult = await confidentialClient
            .AcquireTokenForClient(scopes)
            .ExecuteAsync();

        // Add the access token in the Authorization header of the API request.
        requestMessage.Headers.Authorization =
            new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", authResult.AccessToken);
                })
                );

            // Make a Microsoft Graph API query
            var users = await graphServiceClient.Users.Request().GetAsync();


            // var groups = await graphServiceClient.Groups.Request().GetAsync();

            //   IGraphServiceUsersCollectionPage userss = await graphServiceClient.Users.Request().GetAsync();




            do
            {
                        foreach (User user in users)
                        {




                            Console.WriteLine(user.DisplayName);
                            Console.WriteLine(user.BusinessPhones);
                            Console.WriteLine(user.MobilePhone);



                           // Console.WriteLine($"{user.Id}");
                            Flag++;
                        }
                    }
                    while (users.NextPageRequest != null && (users = await users.NextPageRequest.GetAsync()).Count > 0);

                    Console.WriteLine("------");


            Console.WriteLine(Flag);
        }
    }
}

I have tried below scope:

var scopes = new string[] { "https://graph.microsoft.com/User.ReadWrite.All"};

But, this throws an exception :

MsalServiceException: AADSTS70011: The provided request must include a 'scope' input parameter. The provided value for the input parameter 'scope' is not valid. The scope https://graph.microsoft.com/User.ReadWrite.All is not valid. Trace ID: XXXX-c578-42af-8bd2-7ddd54ee9201

I cross checked in Azure Active Directory Portal,all users are configured with Business Phones and Mobile Phones. Please help.

2

2 Answers

0
votes

First of all your scope deceleration is not correct. Microsoft Graph doesn't support multiple scope assignment as you trying to assign as list of string which also not in right format. Additionally not scopes it would be scope

In C# array of string usually declare as List<string>

You could try following code snippet which work fine as expected.

    //Token Request End Point
    string tokenUrl = $"https://login.microsoftonline.com/YourTenant.onmicrosoft.com/oauth2/v2.0/token";
    var tokenRequest = new HttpRequestMessage(HttpMethod.Post, tokenUrl);

    //I am Using client_credentials as It is mostly recommended
    tokenRequest.Content = new FormUrlEncodedContent(new Dictionary<string, string>
    {
        ["grant_type"] = "client_credentials",
        ["client_id"] = "b6695c7be-a695-4aea-ad87-e6921e61f659",
        ["client_secret"] = "Vxf1SluKbgu4PF0Nf_Your_Secret_Yp8ns4sc=",
        ["scope"] = "https://graph.microsoft.com/.default" 
    });

    dynamic json;
    AccessTokenClass results = new AccessTokenClass();
    HttpClient client = new HttpClient();

    var tokenResponse = await client.SendAsync(tokenRequest);

    json = await tokenResponse.Content.ReadAsStringAsync();
    results = JsonConvert.DeserializeObject<AccessTokenClass>(json);


    //New Block For Accessing Data from Microsoft Graph Rest API
    HttpClient _client = new HttpClient();
    HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, string.Format("https://graph.microsoft.com/v1.0/users"));
    //Passing Token For this Request
    request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", results.access_token);
    HttpResponseMessage response = await _client.SendAsync(request);
    //Get User List With Business Phones and Mobile Phones
    dynamic objGpraphUserList = JsonConvert.DeserializeObject<dynamic>(await response.Content.ReadAsStringAsync());

Class Used:

 public class AccessTokenClass
    {
        public string token_type { get; set; }
        public string expires_in { get; set; }
        public string resource { get; set; }
        public string access_token { get; set; }
    }

I got this response See the screenshot below:

enter image description here

Hope this would help you.

0
votes

Microsoft Graph API returns the user in a pagination format so to get the next list of users you will have to query the url which is mentioned in @odata.nextLink of your current response and that will give you next set of users.

To achieve this you can run a for loop till the time @odata.nextLink returns NULL value.

Update:

  1. Queried graph api to fetch users Fetching users

  2. Queried graph api with "@odata.nextLink" to get next set of users. Fetching users with nextLink