Dany G Dany G - 2 months ago 28
C# Question

Azure active directory get all users - (possibly deadlock)

I have 150 users in Azure Active directory and I'm getting them this way:

public List<Generic.UserAAD> GetUsersAAD()
{
ActiveDirectoryClient activeDirectoryClient = AuthenticationHelper.GetActiveDirectoryClientAsApplication();

IPagedCollection<IUser> usersA = activeDirectoryClient.Users.ExecuteAsync().Result;
List<IUser> queryUsers = new List<IUser>();
List<Generic.UserAAD> listUsers = new List<Generic.UserAAD>();

do
{
List<IUser> queryUsersList = usersA.CurrentPage.ToList();
queryUsers.AddRange(queryUsersList);
usersA = usersA.MorePagesAvailable ? usersA = usersA.GetNextPageAsync().Result : null;
} while (usersA != null);

if (queryUsers.Count > 0)
{
listUsers = queryUsers.Select(u => new Generic.UserAAD { DName = u.DisplayName, UName= u.UserPrincipalName }).ToList();
}

return listUsers;
}


And this is the AuthenticationHelper Class:

public class AuthenticationHelper
{
public static async Task<string> AcquireTokenAsyncForApplication()
{
return await GetTokenForApplication().ConfigureAwait(false);
}


public static ActiveDirectoryClient GetActiveDirectoryClientAsApplication()
{
Uri servicePointUri = new Uri(Constantes.graphUrl);
Uri serviceRoot = new Uri(servicePointUri, Constantes.tenantId);
ActiveDirectoryClient activeDirectoryClient = new ActiveDirectoryClient(serviceRoot,
async () => await AcquireTokenAsyncForApplication().ConfigureAwait(false));
return activeDirectoryClient;
}


public static async Task<string> GetTokenForApplication()
{
AuthenticationContext authContext = new AuthenticationContext(Constantes.authority, false);
ClientCredential clientCred = new ClientCredential(Constantes.clientId, Constantes.appKey);
AuthenticationResult authenticationResult = authContext.AcquireTokenAsync(Constantes.graphUrl,
clientCred).Result;
var token = authenticationResult.AccessToken;
return token;
}
}


So the problem is that it works perfect in local but after deploying it on Azure Web App and executing the service that calls GetUsersAAD() method, doesn't work, the http request freezes and after some minutes I get a 500 error with timeout.

This is a WebApi2 proyect on AspNet MVC.

So I really would apreciate any help you can give me, thanks.

Answer

Ok, after reading and searching a lot I was able to make it works, it seems that .Result it's prone to deadlocks and It's not recommended on async methods, also I was making bad use of async/await/task callings, so the way I make it works was:

public async Task<List<Generic.UserAAD>> GetUsersAAD()
{
    ActiveDirectoryClient activeDirectoryClient = AuthenticationHelper.GetActiveDirectoryClientAsApplication();

    Task<IPagedCollection<IUser>> usersTask = activeDirectoryClient.Users.ExecuteAsync();
    IPagedCollection<IUser> usersA = await usersTask;
    List<IUser> queryUsers = new List<IUser>();
    List<Generic.UserAAD> listUsers = new List<Generic.UserAAD>();

    do
    {
        List<IUser> queryUsersList = usersA.CurrentPage.ToList();
        queryUsers.AddRange(queryUsersList);
        usersA = usersA.MorePagesAvailable ? await usersA.GetNextPageAsync() : null;
    } while (usersA != null);

    if (queryUsers.Count > 0)
    {
        listUsers = queryUsers.Select(u => new Generic.UserAAD { DName = u.DisplayName, UName= u.UserPrincipalName }).ToList();
    }

    return listUsers;
}

I had to adjust the method to async Task and the callings to it.

Comments