2017-10-18 234 views
12

我们使用B2C并将客户编号作为扩展字段存储在用户上。一个用户可以拥有一个或多个客户,并且它们以逗号分隔的字符串存储。通过用户的自定义属性搜索Active Directory B2C

我现在正在做的效率非常低: 1.获取所有用户 2.获取扩展性能上的每个用户 3.检查他们是否有所需的扩展属性,如果它包含了我想要的客户。 4.构建我想要的用户列表。

AdClient的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(); 

我希望能够使用的AdClient在一个查询中这样做是为了ActiveDirectory中。如果我尝试这样做,我得到的错误,方法不支持,这是有道理的,因为我假设查询是在幕后构建查询Active Directory。

编辑 - 额外的信息:

我能够查询图API是这样的:

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); 

然而,在我的例子中,我需要使用substringof过滤,但这不支持通过Azure图形API。

+0

,是它具有的格式为“extension_guid_someName”名称的extenion财产?如何扩展属性放在用户帐户上呢?那是通过Graph API吗? (即用户是由AD B2C创建的,然后使用图形API来更新它?) –

+0

是的,扩展字段I是指具有该格式的扩展属性。它们是使用图形API创建的,或者更准确地说,我使用的是ActiveDirectoryClient类,我假设这是在后台使用Graph API – ruffen

+0

是的,ActiveDirectoryClient包装图形API。您可以通过ActiveDirectoryClient.Context.ExecuteAsync 访问原始界面,以执行来自@ nboettcher答案的查询。但是,有一个问题:$ filter不支持'contains'操作,只有'startswith'和'any'用于多值属性(并且你不能创建多值扩展属性):(可能将来会有希望(但不是在Azure AD Graph API中 - 微软宣布移动到Microsoft Graph API) – Aloraman

回答

4

我没有使用该库,但我们正在使用Graph API进行非常类似的搜索。我已经构建了一个过滤器,用于查找匹配两个我正在寻找的扩展属性值的用户。该过滤器如下所示:

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

我们还通过PowerShell使用REST调用Graph API来返回所需的用户。具有关联过滤器的URI如下所示:

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

这两个选项都会返回任何符合过滤条件的用户。

+0

终于有时间来测试这个了,我设法查询扩展属性,但是我发现你不能搜索属性的一部分字符串(子串),你有这个想法吗? – ruffen

3

当你说“扩展”字段,我会用正常的DirectorySearcher类,从的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(); 
    } 
} 
相关问题