按用户 属性 自定义搜索 Active Directory B2C

Searching Active Directory B2C by custom property on User

我们正在使用 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 GraphAPI不支持这个。

我没有使用那个库,但我们正在使用 Graph API 进行非常相似的搜索。我构建了一个过滤器,用于查找与我要查找的两个扩展属性值相匹配的用户。过滤器看起来像这样:

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

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

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

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

我会使用 System.DirectoryServices

中的普通 DirectorySearcher Class
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();
    }
}

我遇到了这个 post 希望检索具有特定自定义属性值的所有用户。这是我最终得到的实现:

var filter = $"{userOrganizationName} eq '{organizationName}'";
// Get all users (one page)
var result = await graphClient.Users
    .Request()
    .Filter(filter)
    .Select($"id,surname,givenName,mail,{userOrganizationName}")
    .GetAsync();

其中 userOrganizationName 是 b2c_extension 完整属性名称。