0

I need to get all users and their roles(including the roles names and the roles values) in an Azure Application.

What I've done is to retrieve all users and include the appRoleAssignments. The problem is that in the array of appRoleAssignment objects there is only the appRoleId for each role.

Since it would take a lot of http calls to first get all users and then for each appRoleAssignment in each user to retrieve the needed data for the roles by appRoleAssignment Id.

How can I optimize the retrieval of all users and their roles from Azure ?

I think it's possible to use batching and combine the logic for getting all users and their roles(including role name and role value) in to a single API Call, but not sure how to do it.

This is what I have right now:

var users = await graphClient.Users
        .Request()
        .Expand("appRoleAssignments")
        .GetAsync();
Sovak
  • 373
  • 1
  • 5
  • 17

1 Answers1

0

As far as I know, there is no way to get user role assignment records with app role names together by one API calling.

I can understand that if you want to get the information above for all of your users, that will be a lot of requests and leads to bad performance. I think you can get all app role information in your directory and get all role assignment records, match them one by one by using AppRoleId.I write a simple console app for you, just try the code below:

using Microsoft.Graph;
using Microsoft.Graph.Auth;
using Microsoft.Identity.Client;

using System;

using System.Collections.Generic;


namespace graphsdktest
{
    class Program
    {
        static void Main(string[] args)
        {
            var clientId = "";
            var clientSecret = "";
            var tenantID = "";
            IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
                .Create(clientId)
                .WithTenantId(tenantID)
                .WithClientSecret(clientSecret)
                .Build();

            ClientCredentialProvider authenticationProvider = new ClientCredentialProvider(confidentialClientApplication);

            var graphClient = new GraphServiceClient(authenticationProvider);

            var roleResult = graphClient.ServicePrincipals.Request().Select(app => new { app.AppRoles }).Top(999).GetAsync().GetAwaiter().GetResult();

            var appRoleList = new List<AppRole>();
            var userRoleAssigments = new List<User>();

            var RolePageIterator = PageIterator<ServicePrincipal>
                .CreatePageIterator(graphClient, roleResult, (app) =>
                {
                    if (app.AppRoles.GetEnumerator().MoveNext())
                    {

                        foreach (var appRole in app.AppRoles)
                        {
                            appRoleList.Add(appRole);
                        }
                    }
                    return true;
                });
            //get all app role information
            RolePageIterator.IterateAsync().GetAwaiter().GetResult();

            var roleAssigmentResult = graphClient.Users.Request().Expand("appRoleAssignments").GetAsync().GetAwaiter().GetResult();


            var RoleAssigmentPageIterator = PageIterator<User>
                .CreatePageIterator(graphClient, roleAssigmentResult, (user) =>
                {
                    userRoleAssigments.Add(user);
                    return true;
                });
            //get all role assigment records
            RoleAssigmentPageIterator.IterateAsync().GetAwaiter().GetResult();

            foreach (var user in userRoleAssigments)
            {
                if (user.AppRoleAssignments.Count > 0)
                {
                    Console.WriteLine("app role assigment of user :" + user.DisplayName);
                    foreach (var ras in user.AppRoleAssignments)
                    {
                        var roleName = (ras.AppRoleId.ToString().Equals("00000000-0000-0000-0000-000000000000") ? "Default Access" : appRoleList.Find(item => item.Id == ras.AppRoleId).DisplayName);
                        Console.WriteLine("roleID:" + ras.AppRoleId + " appName:" + ras.ResourceDisplayName + " roleName:" + roleName);
                    }

                }

            }

        }
    }

}

Result: enter image description here

Per my test, the whole request spends about 9 seconds.

Stanley Gong
  • 11,522
  • 1
  • 8
  • 16