2017-10-18 7 views
12

Nous utilisons B2C et stockons les numéros de client comme champ d'extension sur les utilisateurs. Un seul utilisateur peut avoir un ou plusieurs clients et ils sont stockés dans une chaîne séparée par des virgules.Recherche dans Active Directory B2C par propriété personnalisée sur l'utilisateur

Ce que je fais est maintenant très inefficace: 1. Obtenir tous les utilisateurs 2. Obtenir les propriétés d'extension de chaque utilisateur 3. Vérifiez si elles ont la propriété d'extension souhaitée et si elle contient le client que je veux. 4. Construire une liste des utilisateurs que je veux.

AdClient est IActiveDirectoryClient

var users = (await GetAllElementsInPagedCollection(await AdClient.Users.ExecuteAsync())).ToList(); 
var customersUsers = users.Where(user => user.AccountEnabled.HasValue && user.AccountEnabled.Value).Where(user => 
    { 
     var extendedProperty = ((User) user).GetExtendedProperties().FirstOrDefault(extProp => extProp.Key == customersExtendedProperty.Name).Value?.ToString(); 
     return extendedProperty != null && extendedProperty.Contains(customerId); 
    }).ToList(); 

Je veux être en mesure de le faire dans une requête à l'aide de la ActiveDirectory AdClient. Si j'essaie cela, j'obtiens des erreurs que les méthodes ne sont pas supportées, ce qui est logique car je suppose qu'une requête est en cours de construction en arrière-plan pour interroger Active Directory.

Edition - Informations complémentaires:

j'ai pu interroger l'API graphique comme celui-ci:

var authContext = await ActiveDirectoryClientFactory.GetAuthenticationContext(AuthConfiguration.Tenant, 
AuthConfiguration.GraphUrl, AuthConfiguration.ClientId, AuthConfiguration.ClientSecret); 
var url = $"https://graph.windows.net:443/hansaborgb2c.onmicrosoft.com/users?api-version=1.6&$filter={customersExtendedProperty.Name} eq '{customerId}'"; 
var users = await _graphApiHttpService.GetAll<User>(url, authContext.AccessToken); 

Cependant, dans mon exemple je dois utiliser substringof pour filtrer, mais ce n'est pas pris en charge par l'API Azure Graph.

+0

Quand vous dites champ « extension », est-il une propriété extenion qui a un nom dans le format « extension_guid_someName »? Et comment les propriétés d'extension sont-elles placées sur le compte d'utilisateur en premier lieu? Est-ce par l'intermédiaire de l'API graphique? (c'est-à-dire que l'utilisateur est créé par AD B2C et que l'API graphique est utilisée pour le mettre à jour?) –

+0

Oui, par champ d'extension, j'entends la propriété d'extension avec ce format. Ils sont créés à l'aide de l'API graphique ou, plus exactement, j'utilise la classe ActiveDirectoryClient et je suppose que cela utilise l'API graphique en arrière-plan. – ruffen

+0

Oui, ActiveDirectoryClient s'enroule autour de l'API graphique. Vous pouvez accéder à l'interface brute via ActiveDirectoryClient.Context.ExecuteAsync pour effectuer des requêtes à partir de la réponse de @ nboettcher. Cependant, il y a un problème: $ filter ne supporte pas l'opération 'contains', seulement 'startswith' et 'any' pour les propriétés multi-valuées (et vous ne pouvez pas créer de propriété étendue multi-valuée) :(Peut-être y a-t-il de l'espoir (mais pas dans Azure AD Graph API - Microsoft a annoncé le mouvement à Microsoft Graph API) – Aloraman

Répondre

4

Je n'utilise pas cette bibliothèque, mais nous faisons une recherche très similaire en utilisant l'API Graph. J'ai construit un filtre qui recherchera les utilisateurs qui correspondent à deux valeurs d'attribut d'extension que je recherche. Le filtre ressemble à ceci:

var filter = $"$filter={idpExtensionAttribute} eq '{userType.ToString()}' and {emailExtensionAttribute} eq '{emailAddress}'"; 

Nous avons également utilisé REST appels via PowerShell à l'API graphique qui renverra les utilisateurs souhaités. L'URI avec le filtre associé ressemble à ceci:

https://graph.windows.net/$AzureADDomain/users?`$filter=extension_d2fbadd878984184ad5eab619d33d016_idp eq '$idp' and extension_d2fbadd878984184ad5eab619d33d016_email eq '$email'&api-version=1.6 

Ces deux options renvoient tous les utilisateurs qui correspondent aux critères de filtrage.

+0

Enfin eu le temps de tester cela, et j'ai réussi à interroger les propriétés de l'extension, mais j'ai trouvé que vous ne pouvez pas rechercher une propriété pour une partie de son chaîne (sous-chaîne), avez-vous une idée pour cela? – ruffen

3

J'utilise la classe normale DirectorySearcher de System.DirectoryServices

private void Search() 
{ 
    // GetDefaultDomain as start point is optional, you can also pass a specific 
    // root object like new DirectoryEntry ("LDAP://OU=myOrganisation,DC=myCompany,DC=com"); 
    // not sure if GetDefaultDomain() works in B2C though :(
    var results = FindUser("extPropName", "ValueYouAreLookingFor", GetDefaultDomain()); 

    foreach (SearchResult sr in results) 
    { 
     // query the other properties you want for example Accountname 
     Console.WriteLine(sr.Properties["sAMAccountName"][0].ToString()); 
    } 
    Console.ReadKey(); 
} 

private DirectoryEntry GetDefaultDomain() 
{ // Find the default domain 
    using (var dom = new DirectoryEntry("LDAP://rootDSE")) 
    { 
     return new DirectoryEntry("LDAP://" + dom.Properties["defaultNamingContext"][0].ToString()); 
    } 
} 

private SearchResultCollection FindUser(string extPropName, string searchValue, DirectoryEntry startNode) 
{ 
    using (DirectorySearcher dsSearcher = new DirectorySearcher(startNode)) 
    { 
     dsSearcher.Filter = $"(&(objectClass=user)({extPropName}={searchValue}))"; 
     return dsSearcher.FindAll(); 
    } 
}