Retrieving All Users In Azure AD Application Roles Programmatically

Background
 
Essentially, there are two ways by which Azure AD application roles can be retrieved - either using HTTP REST calls (Graph API) or using Azure AD SDK. This article covers the details of the second approach to query and to retrieve all users in an application role using Azure AD managed providers.
 
Since we are interested in getting the users from an Azure AD application role, we would need the application role Id against which we will be querying. So, we will first retrieve all the role Ids from an Azure AD application.
 
Note - This article assumes you have a basic understanding of Azure AD and application roles. If not, then it is highly recommended for you to go through this article before moving ahead. 
 
Code 
  1. public static Dictionary<stringstring> GetAllAppRoles()  
  2. {  
  3.     get  
  4.     {  
  5.        if (appRolesDictionary == null || appRolesDictionary.Count == 0)  
  6.        {  
  7.            appRolesDictionary = new Dictionary<stringstring>();  
  8.             string tenantID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid Jump ").Value;  
  9.             Uri servicePointUri = new Uri(("https://graph.windows.net Jump ");  
  10.             Uri serviceRoot = new Uri(servicePointUri, tenantID);  
  11.    
  12.             ActiveDirectoryClient activeDirectoryClient = new ActiveDirectoryClient(serviceRoot, async () => await UserHelper.GetTokenForApplication());  
  13.              IPagedCollection<IApplication> retrievedApps = activeDirectoryClient.Applications.Where(w => w.AppId.Equals(ConfigHelper.ClientId)).ExecuteAsync().Result;  
  14.              if (retrievedApps != null)  
  15.              {  
  16.                 Application adApp = (Application)retrievedApps.CurrentPage.FirstOrDefault();  
  17.                 if (adApp != null)  
  18.                 {  
  19.                     adApp.AppRoles.ToList().ForEach(e =>  
  20.                     {  
  21.                         appRolesDictionary.Add(e.DisplayName, e.Id.ToString());  
  22.                      });  
  23.                   }  
  24.               }  
  25.           }  
  26.    
  27.            return appRolesDictionary;  
  28.       }  
  29.   }  
The snippet above builds a dictionary with the key as application role name and value as its Id. The ConfigHelper.Client is nothing but the Azure AD application Id which is registered and to which application roles are associated.
 
Now, the next part! We will now be creating a method which accepts two arguments, i.e., application role id and service principle Id. For those who do not know what service principle Id is, without going to technicalities, we can just say in simple terms that it is the object Id present along with your application Id in Azure AD app registration details and can be retrieved easily using Azure portal (From the enterprise app sections in Azure AD).
 
Now, let's take a look at the core method.
  1. public static List<IUser> GetAllUsersInAppRole(string servicePrincipalObjectId, string appRoleId)  
  2. {  
  3.      string tenantID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid Jump ").Value;  
  4.      Uri servicePointUri = new Uri("https://graph.windows.net Jump ");  
  5.      Uri serviceRoot = new Uri(servicePointUri, tenantID);  
  6.      ActiveDirectoryClient activeDirectoryClient = new ActiveDirectoryClient(serviceRoot, async () => await GetTokenForApplication());  
  7.    
  8.       List<IUser> users = new List<IUser>();  
  9.       var guidAppRoleId = Guid.Parse(appRoleId);  
  10.       var appRoleAssignmentsPaged = activeDirectoryClient.ServicePrincipals.GetByObjectId(servicePrincipalObjectId).AppRoleAssignedTo.ExecuteAsync().Result;  
  11.       var appRoleAssignments = EnumerateAllAsync(appRoleAssignmentsPaged);  
  12.    
  13.        var userObjectIds = appRoleAssignments.Where(a => a.Id == guidAppRoleId && a.PrincipalType == "User").Select(a => a.PrincipalId.ToString()).ToList();  
  14.    
  15.       foreach (var userObjectId in userObjectIds)  
  16.        {  
  17.           users.Add(activeDirectoryClient.Users.Where(w => w.ObjectId.Equals(userObjectId)).ExecuteAsync().Result.CurrentPage.FirstOrDefault());  
  18.        }  
  19.    
  20.         return users;  
  21. }  
There is an addtional extension method we have used to enumrate all the paged collections.
  1. public static IEnumerable<T> EnumerateAllAsync<T>(this IPagedCollection<T> pagedCollection)  
  2. {  
  3.    return EnumerateAllAsync(pagedCollection, Enumerable.Empty<T>());  
  4. }  
  5.    
  6. private static IEnumerable<T> EnumerateAllAsync<T>(this IPagedCollection<T> pagedCollection, IEnumerable<T> previousItems)  
  7. {  
  8.      var newPreviousItems = previousItems.Concat(pagedCollection.CurrentPage);  
  9.    
  10.       if (pagedCollection.MorePagesAvailable == false)  
  11.       {  
  12.             return newPreviousItems;  
  13.        }  
  14.    
  15.         var newPagedCollection = pagedCollection.GetNextPageAsync().Result;  
  16.         return EnumerateAllAsync(newPagedCollection, newPreviousItems);  
  17. }  
And, that's it. Now, the method call can be made quite conveniently as -
  1. Dictionary<stringstring> allAppRoles = GetAllAppRoles();  
  2.    
  3. allAppRoles.TryGetValue(roleName, out string roleId);  
  4. List<IUser> appRoleUsers = GetAllUsersInAppRole("app_object_Id",roleId)  
Hope this helps someone! Happy coding!
Ebook Download
View all
Learn
View all