Friday, October 14, 2016

Retrieve paginated data from Azure AD via Microsoft Graph Client library

In this post I will show how to retrieve paginated data from Azure AD using MS Graph .Net client library. As we already saw from previous examples (see e.g. Create Azure AD group and set group owner using Microsoft Graph Client library) client library is adopted for asynchronous usage (we can call its methods asynchronously using async/await C# keywords). In addition to that it also restricts number of objects returned from single request, e.g. when you get list of users via GraphServiceClient.Users.Request().GetAsync() call it will return only 100 users. In order to get other users we will need to load all pages by 100 users each. The following example shows how to do it:

   1: static async void enumUsers()
   2: {
   3:     var graph = new GraphServiceClient(new AzureAuthenticationProvider());
   4:     try
   5:     {
   6:         var users = await graph.Users.Request().GetAsync();
   7:         int requestNumber = 1;
   8:         while (users.Count > 0)
   9:         {
  10:             Console.WriteLine("Request number: {0}", requestNumber++);
  11:             foreach (var u in users)
  12:             {
  13:                 Console.WriteLine("User: {0} ({1})", u.DisplayName,
  14:                     u.UserPrincipalName);
  15:             }
  16:  
  17:             if (users.NextPageRequest != null)
  18:             {
  19:                 users = await users.NextPageRequest.GetAsync();
  20:             }
  21:             else
  22:             {
  23:                 break;
  24:             }
  25:         }
  26:     }
  27:     catch (ServiceException x)
  28:     {
  29:         Console.WriteLine("Exception occured: {0}", x.Error);
  30:     }
  31: }
  32:  
  33:  
  34:  
  35: public class AzureAuthenticationProvider : IAuthenticationProvider
  36: {
  37:     public async Task AuthenticateRequestAsync(HttpRequestMessage request)
  38:     {
  39:         string clientId = ConfigurationManager.AppSettings["ClientId"];
  40:         string clientSecret = ConfigurationManager.AppSettings["ClientSecret"];
  41:         string authority = ConfigurationManager.AppSettings["AuthorityUrl"];
  42:     
  43:         AuthenticationContext authContext = new AuthenticationContext(authority);
  44:     
  45:         ClientCredential creds = new ClientCredential(clientId, clientSecret);
  46:     
  47:         Console.WriteLine("before: get token");
  48:         AuthenticationResult authResult = await
  49: authContext.AcquireTokenAsync("https://graph.microsoft.com/", creds);
  50:         Console.WriteLine("after: get token {0}", authResult.AccessToken);
  51:     
  52:         request.Headers.Add("Authorization", "Bearer " + authResult.AccessToken);
  53:     }
  54: }

I.e. we call graph.Users.Request().GetAsync() first (line 6) and then call graph.Users.NextPageRequest.GetAsync() (line 19) until next page won’t be empty. For convenience I also added number of request made to Graph API to the console (line 10) so it will be visible how many requests are needed for iterating through all users. For authentication we use application id and secret in custom AzureAuthenticationProvider as described in the following article: Work with Azure AD via Microsoft Graph API.

2 comments: