Friday 16 August 2019

SharePoint On premises People Picker with Azure AD Graph Api

Search Users and Groups From Azure AD


Requirement:

We have to integrate our SharePoint on premises People Picker with Azure AD, so user can search users/groups coming from Azure AD.

Steps:


  1. Graph API
  2. Inherit web part with SPClaimsProvider class
  3. Call Graph API in FillSearchMethod
  4. Deployment

1: Graph API

To find Azure AD users, groups, All users/ groups etc we have to use Graph API provided by Microsoft. In simple language if developer requires to search something from Azure AD Graph Api full fill this requirements. To read more about available Graph APIs please visit Microsoft documentation.
URL Graph API Documentation: https://docs.microsoft.com/en-us/graph/use-the-api

Following APIs will be used to search users and groups from Azure AD for People Picker:
  • Create Authentication Token: https://login.microsoftonline.com/{TenantID}/oauth2/token
    Example: https://login.microsoftonline.com/2909k32e-b3db-4aad-86o4-n3f7b65t235h/oauth2/token
    Response in Postman:
  • Search User: 
    https://graph.microsoft.com/v1.0/users?$filter=displayName eq 'Derrick Ramirez'
    Response in Postman:
  • Search Group: 
    https://graph.microsoft.com/v1.0/groups/?$filter=startswith(displayName,'aa_azureapps')
    Response in Postman:

2: Inherit web part with SPClaimProvider class

  • Create a Empty web part using visual studio (Farm solution or Sandbox)
  • Inherit class like this public class ClaimProvider : SPClaimProvider
  • Implement this class just by right clicking on SPClaimProvider, it will generate multiple methods FillClaimsForEntity, FillResolve, FillEntityTypes, FillSearch for now we just have to add code in FillSearch Method protected override void FillSearch(Uri context, string[] entityTypes, string searchPattern, string hierarchyNodeID, int maxCount, SPProviderHierarchyTree searchTree) { //Call Graph API here }

3: Call Graph API in FillSearchMethod

  1. Customize FillSearch Method: Your FillSearch Method should look like this: protected override void FillSearch(Uri context, string[] entityTypes, string searchPattern, string hierarchyNodeID, int maxCount, SPProviderHierarchyTree searchTree) { try { string NameOfUserOrGroup = searchPattern.ToLower(); APIResponseObject usersgroups = new APIResponseObject(); usersgroups = SearchUsersGroupFromAzureAD(NameOfUserOrGroup, "SecretKey", "GraphApiUrl", "ClientId"); //Get these keys from Azure Portal // string claimType = GenerateClaimType.GetClaimType("Email"); foreach (var user in usersgroups.value) { PickerEntity entity = CreatePickerEntity(); //If its group name because Azure AD doesn't have UPN So if (user.userPrincipalName == null || user.userPrincipalName == "") { //entity.Claim = CreateClaimForSTS(claimType, user.displayName); entity.Description = user.displayName; entity.DisplayText = user.displayName; entity.EntityData[PeopleEditorEntityDataKeys.DisplayName] = user.displayName; entity.EntityType = SPClaimEntityTypes.SecurityGroup; } //else its user name else { //entity.Claim = CreateClaimForSTS(claimType, user.mail); entity.Description = user.mail; entity.DisplayText = user.displayName; entity.EntityData[PeopleEditorEntityDataKeys.DisplayName] = user.mail; entity.EntityType = SPClaimEntityTypes.User; entity.EntityType = SPClaimEntityTypes.FormsRole; } entity.IsResolved = true; searchTree.AddEntity(entity); } } catch (Exception ex) { } }
  2. Call Graph API Method
    Here you can call Graph API the way which suits you just like to call Rest API using C# webclient. Note: To Call Graph API first we have create token using /oauth2/token api. public RootObject SearchUsersGroupFromAzureAD(string SearchPattern, string ClientSecret, string GraphApiUrl, string ClientId) { try { var client = new WebClient(); byte[] byteArray = Encoding.ASCII.GetBytes(""); //Call this API https://graph.microsoft.com/v1.0/users?$filter=displayName eq 'Derrick Ramirez' string Url = "https://graph.microsoft.com/v1.0/users?$filter=displayName eq 'SearchPattern'"; var allAdUsers = client.DownloadData(new Uri(Url)); if(allAdUsers != null || allAdUsers !=""){ string encodeUsers = Encoding.ASCII.GetString(allAdUsers); JavaScriptSerializer serilizeObject = new JavaScriptSerializer(); RootObject Users = serilizeObject.Deserialize<RootObject>(encodeUsers); return Users;} else{ //Call this API https://graph.microsoft.com/v1.0/groups/?$filter=startswith(displayName,'aa_azureapps') string Url = "https://graph.microsoft.com/v1.0/groups/?$filter=startswith(displayName,'SearchPattern')"; var allAdUsers = client.DownloadData(new Uri(Url)); string encodeUsers = Encoding.ASCII.GetString(allAdUsers); JavaScriptSerializer serilizeObject = new JavaScriptSerializer(); RootObject Users = serilizeObject.Deserialize<RootObject>(encodeUsers); return Users; } } catch (Exception ex) { throw; } }
  3. Convert API response to Deserialize Object

public class Value { //public List<object> businessPhones { get; set; } public string displayName { get; set; } public string givenName { get; set; } public string jobTitle { get; set; } public string mail { get; set; } public string mobilePhone { get; set; } public string officeLocation { get; set; } public object preferredLanguage { get; set; } public string surname { get; set; } public string userPrincipalName { get; set; } public string id { get; set; } } public class RootObject { public List<Value> value { get; set; }

}
Deployment: Just add, install and enable this web part and enjoy to fetch Azure AD users and Groups. Unit Test:

After Deployment visit web application depends you have enabled this feature for farm level or specific web application then go to Site permissions and enter user email or group name. It will return you result from Azure AD. If you have any query feel free to comment, i will try my best to resolve on my earliest. Thanks
Search Users and Groups From Azure AD



No comments:

Post a Comment