C# 按用户上的自定义属性搜索Active Directory B2C

C# 按用户上的自定义属性搜索Active Directory B2C,c#,azure-ad-b2c,C#,Azure Ad B2c,我们使用B2C并将客户编号存储为用户的扩展字段。单个用户可以有一个或多个客户,这些客户存储在逗号分隔的字符串中 我现在所做的工作效率很低: 1.获取所有用户 2.获取每个用户的扩展属性 3.检查他们是否具有所需的扩展属性,以及该属性是否包含我想要的客户。 4.建立一个我想要的用户列表 Adclient是IActiveDirectoryClient var users = (await GetAllElementsInPagedCollection(await AdClient.Users.Exe

我们使用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

编辑-其他信息:

我可以像这样查询Graph 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);
var filter = $"$filter={idpExtensionAttribute} eq '{userType.ToString()}' and {emailExtensionAttribute} eq '{emailAddress}'";
https://graph.windows.net/$AzureADDomain/users?`$filter=extension_d2fbadd878984184ad5eab619d33d016_idp eq '$idp' and extension_d2fbadd878984184ad5eab619d33d016_email eq '$email'&api-version=1.6
var authContext=await ActiveDirectoryClientFactory.GetAuthenticationContext(AuthConfiguration.Tenant,
AuthConfiguration.graphhurl、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\u graphApiHttpService.GetAll(url,authContext.AccessToken);

然而,在我的示例中,我需要使用substringof进行过滤,但Azure Graph API不支持这一点

我没有使用该库,但我们正在使用Graph 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);
var filter = $"$filter={idpExtensionAttribute} eq '{userType.ToString()}' and {emailExtensionAttribute} eq '{emailAddress}'";
https://graph.windows.net/$AzureADDomain/users?`$filter=extension_d2fbadd878984184ad5eab619d33d016_idp eq '$idp' and extension_d2fbadd878984184ad5eab619d33d016_email eq '$email'&api-version=1.6
我们还通过PowerShell使用REST调用返回所需用户的Graph API。带有关联筛选器的URI如下所示:

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);
var filter = $"$filter={idpExtensionAttribute} eq '{userType.ToString()}' and {emailExtensionAttribute} eq '{emailAddress}'";
https://graph.windows.net/$AzureADDomain/users?`$filter=extension_d2fbadd878984184ad5eab619d33d016_idp eq '$idp' and extension_d2fbadd878984184ad5eab619d33d016_email eq '$email'&api-version=1.6

这两个选项都将返回符合筛选条件的所有用户。

我将使用System.DirectoryServices中的普通DirectorySearcher类

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

我看到这篇文章是想检索具有特定自定义属性值的所有用户。以下是我最终的实现:

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\u扩展的完整属性名。

当您说“扩展”字段时,它是一个扩展属性,其名称格式为“extension\u guid\u someName”?首先,扩展属性是如何放在用户帐户上的?这是通过图形API实现的吗?(即,用户是由AD B2C创建的,然后使用Graph API对其进行更新?)是的,通过扩展字段,我指的是具有该格式的扩展属性。它们是使用graph API创建的,或者更准确地说,我使用的是ActiveDirectoryClient类,我假设这是在后台使用graph API是的,ActiveDirectoryClient围绕graph API进行包装。您可以通过ActiveDirectoryClient.Context.ExecuteAsync访问原始接口,从@nboettcher的答案执行查询。但是,存在一个问题:$filter不支持“contains”操作,多值属性仅支持“startswith”和“any”(并且您无法创建多值扩展属性):(未来可能有希望(但Azure AD Graph API中没有希望-Microsoft宣布迁移到Microsoft Graph API)终于有时间测试了,我设法查询了扩展属性,但是我发现你不能搜索属性的一部分字符串(子字符串),你对此有什么想法吗?