Find user in Azure Active Directory group using graph api
I would like to have some sort of people select functionality with autocomplete functionality in my asp.net mvc 5 application to find a user in a specific Azure AD group. This is a demo "todo" application that allows you to assign a todo to a user in a group.
I've tried both the Graph API directly and the Azure Graph client library, but I don't seem to find a way to achieve what I want. The graph api allows you to get the members of the group, but adding the "startswith" filter fails because when you add the filter, the api only returns the directory object, which does not include, for example, the DisplayName property ... the client library does not help much except for the batch functionality that offers way, but with a lot of overhead ... Then I would need to get the filtered result of the user regardless of group membership (using the user list stuff in the api), all the members of the group, and then fetch the correct result set with Linq ... .will work fine for dev / testing,but in a production with several hundred users that would be insane ...
Any ideas or suggestions would be much appreciated. Thank you!
EDIT
Below is my code which is called from the client side Javascript to find the user;
- AccessGroupId is the Azure AD group used to authorize users. Only members of this group can access the web application that I am processing in custom OWin Middleware
- The method is intended to be used to find a user in this group
The code works fine as below only filtering is applied, which is intent with pre input (which comes from textbox to ui). I get all members of an access group.
public async Task<JsonResult> FindUser(string pre)
{
string AccessGroupId = ConfigurationManager.AppSettings["AccessGroupId"];
AuthenticationContext authCtx = new AuthenticationContext(String.Format(CultureInfo.InvariantCulture, "{0}/{1}", SecurityConfiguration.LoginUrl, SecurityConfiguration.Tenant));
ClientCredential credential = new ClientCredential(SecurityConfiguration.ClientId, SecurityConfiguration.AppKey);
AuthenticationResult assertionCredential = await authCtx.AcquireTokenAsync(SecurityConfiguration.GraphUrl, credential);
var accessToken = assertionCredential.AccessToken;
var graphUrl = string.Format("https://graph.windows.net/mytenant.onmicrosoft.com/groups/{0}/members?api-version=2013-11-08, AccessGroupId );
HttpClient client = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, graphUrl);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
HttpResponseMessage response = await client.SendAsync(request);
String responseString = await response.Content.ReadAsStringAsync();
JObject jsonReponse = JObject.Parse(responseString);
var l = from r in jsonReponse["value"].Children()
select new
{
UserObjectId = r["objectId"].ToString(),
UserPrincipalName = r["userPrincipalName"].ToString(),
DisplayName = r["displayName"].ToString()
};
//users = Newtonsoft.Json.JsonConvert.DeserializeObject<List<User>>(responseString);
return Json(l, JsonRequestBehavior.AllowGet);
}
When I add a filter to the same api call, instead of returning members (users, groups and / or contacts), it returns directory objects (which do not have a displayName) which are not very useful in the above code unless I will be asking the api again (in batch) to fetch the username, but that looks like a lot of overhead to me.
var graphUrl = string.Format("https://graph.windows.net/mytenant.onmicrosoft.com/groups/{0}/members?api-version=2013-11-08&$filter=startswith(displayName,'{1}')", AccessGroupId, pre);
source to share
I would highlight two possible approaches:
- Make requests to the Graph API using a dedicated JS library. You still need to take care of the accesstokens and take a look at ADAL.js
Sample application (not complete at the time of this writing) available at: AzureADSamples WebApp-GroupClaims-DotNet
Have a look at AadPickerLibrary.js
- Try using ActiveDirectoryClient
It will look something like this:
public async Task<JsonResult> FindUser(string pre) {
ActiveDirectoryClient client = AADHelper.GetActiveDirectoryClient();
IPagedCollection<IUser> pagedCollection = await client.Users.Where(u => u.UserPrincipalName.StartsWith(pre, StringComparison.CurrentCultureIgnoreCase)).ExecuteAsync();
if (pagedCollection != null)
{
do
{
List<IUser> usersList = pagedCollection.CurrentPage.ToList();
foreach (IUser user in usersList)
{
userList.Add((User)user);
}
pagedCollection = await pagedCollection.GetNextPageAsync();
} while (pagedCollection != null);
}
return Json(userList, JsonRequestBehavior.AllowGet);
}
A more detailed sample is available at: AzureADSamples WebApp-GraphAPI-DotNet
source to share