使用 DirectorySynchronization 时获取 Microsoft Active Directory 属性 "memberOf" 的正确方法
Correct way to get Microsoft Active Directory attribute "memberOf" when using DirectorySynchronization
我定期读取应用程序的活动目录以将当前状态存储在数据库中。
为了减少数据量,我使用 DirectorySynchronization 仅获取自上次查询以来的更改。
但是现在我还需要使用 DirectorySynchronization 时 DirectorySearcher 未提供的属性“memberOf”。
目前我得到了每个找到的条目的 DirectoryEntry,但是随后提供的属性比我需要的多,这与实际意图相矛盾。
有没有一种方法可以设置使用 DirectoryEntry 读取哪些属性,类似于使用 DirectorySearcher 的 PropertiesToLoad,或者有没有更好的方法来在使用 DirectorySynchronization 时读取属性“memberOf”?
代码摘录:
using System.DirectoryServices;
DirectoryEntry searchRoot = new DirectoryEntry(domain, username,password, AuthenticationTypes.Secure);
DirectorySearcher dirSearch = new DirectorySearcher(searchRoot);
dirSearch.PropertiesToLoad.Add("samaccountname");
dirSearch.PropertiesToLoad.Add("distinguishedname");
dirSearch.PropertiesToLoad.Add("mail");
//filter to user objects
dirSearch.Filter = "(objectCategory=person)";
dirSearch.Filter = "(objectClass=user)";
byte[] cookie = null;
DirectorySynchronization sync = new DirectorySynchronization(DirectorySynchronizationOptions.ObjectSecurity,cookie);
dirSearch.DirectorySynchronization = sync;
using (searchRoot)
{
using (SearchResultCollection results = dirSearch.FindAll())
{
foreach (SearchResult result in results)
{
DirectoryEntry dirEntry = result.GetDirectoryEntry();
List<string> memberOf = new List<string>();
PropertyValueCollection prop = dirEntry.Properties["memberof"];
foreach(var member in prop)
{
memberOf.Add((string)member);
}
}
}
cookie = sync.GetDirectorySynchronizationCookie();
}
But now I also need the attribute "memberOf" which is not provided by the DirectorySearcher when using DirectorySynchronization.
memberOf
是目录计算出来的一个特殊属性,所以DirectorySynchronization
没有提供(实际上用的是DirSync control)。唯一可以提供DirectorySynchronization
的是目录真正的修改,属于用户DN添加到member
属性中的group
对象(哪种触发memberOf
重新计算)
At the moment I get the DirectoryEntry for each found entry, but then more attributes are delivered than I need, which contradicts the actual intention.
GetDirectoryEntry
执行新的目录搜索并加载所有属性(它没有 link DirectorySearcher
设置和先前的搜索)。
因此,您可以使用另一个 DirectorySearcher
(将只加载 memberOf
),而不是 GetDirectoryEntry
,它将在每个循环中执行一次搜索(示例没有任何强测试,即 null
值等):
using (searchRoot)
{
using (SearchResultCollection results = dirSearch.FindAll())
{
// A new DirectorySearcher
DirectorySearcher anotherDirectorySearcher = new DirectorySearcher(searchRoot);
anotherDirectorySearcher.PropertiesToLoad.Add("memberOf");
foreach (SearchResult result in results)
{
// A new filter on each loop in order to look for an single entry
anotherDirectorySearcher.Filter = $"(samaccountname={(string)result.Properties["samaccountname"][0]})";
List<string> memberOf = new List<string>();
foreach(var member in anotherDirectorySearcher.FindOne().Properties["memberOf"])
{
memberOf.Add((string)member);
}
}
}
cookie = sync.GetDirectorySynchronizationCookie();
}
注意:
dirSearch.Filter = "(objectCategory=person)";
// Here you override the previous one (the Filter property is a string)
dirSearch.Filter = "(objectClass=user)";
// If you want both, you can use:
dirSearch.Filter = "(&(objectCategory=person)(objectClass=user))";
我定期读取应用程序的活动目录以将当前状态存储在数据库中。 为了减少数据量,我使用 DirectorySynchronization 仅获取自上次查询以来的更改。 但是现在我还需要使用 DirectorySynchronization 时 DirectorySearcher 未提供的属性“memberOf”。
目前我得到了每个找到的条目的 DirectoryEntry,但是随后提供的属性比我需要的多,这与实际意图相矛盾。
有没有一种方法可以设置使用 DirectoryEntry 读取哪些属性,类似于使用 DirectorySearcher 的 PropertiesToLoad,或者有没有更好的方法来在使用 DirectorySynchronization 时读取属性“memberOf”?
代码摘录:
using System.DirectoryServices;
DirectoryEntry searchRoot = new DirectoryEntry(domain, username,password, AuthenticationTypes.Secure);
DirectorySearcher dirSearch = new DirectorySearcher(searchRoot);
dirSearch.PropertiesToLoad.Add("samaccountname");
dirSearch.PropertiesToLoad.Add("distinguishedname");
dirSearch.PropertiesToLoad.Add("mail");
//filter to user objects
dirSearch.Filter = "(objectCategory=person)";
dirSearch.Filter = "(objectClass=user)";
byte[] cookie = null;
DirectorySynchronization sync = new DirectorySynchronization(DirectorySynchronizationOptions.ObjectSecurity,cookie);
dirSearch.DirectorySynchronization = sync;
using (searchRoot)
{
using (SearchResultCollection results = dirSearch.FindAll())
{
foreach (SearchResult result in results)
{
DirectoryEntry dirEntry = result.GetDirectoryEntry();
List<string> memberOf = new List<string>();
PropertyValueCollection prop = dirEntry.Properties["memberof"];
foreach(var member in prop)
{
memberOf.Add((string)member);
}
}
}
cookie = sync.GetDirectorySynchronizationCookie();
}
But now I also need the attribute "memberOf" which is not provided by the DirectorySearcher when using DirectorySynchronization.
memberOf
是目录计算出来的一个特殊属性,所以DirectorySynchronization
没有提供(实际上用的是DirSync control)。唯一可以提供DirectorySynchronization
的是目录真正的修改,属于用户DN添加到member
属性中的group
对象(哪种触发memberOf
重新计算)
At the moment I get the DirectoryEntry for each found entry, but then more attributes are delivered than I need, which contradicts the actual intention.
GetDirectoryEntry
执行新的目录搜索并加载所有属性(它没有 link DirectorySearcher
设置和先前的搜索)。
因此,您可以使用另一个 DirectorySearcher
(将只加载 memberOf
),而不是 GetDirectoryEntry
,它将在每个循环中执行一次搜索(示例没有任何强测试,即 null
值等):
using (searchRoot)
{
using (SearchResultCollection results = dirSearch.FindAll())
{
// A new DirectorySearcher
DirectorySearcher anotherDirectorySearcher = new DirectorySearcher(searchRoot);
anotherDirectorySearcher.PropertiesToLoad.Add("memberOf");
foreach (SearchResult result in results)
{
// A new filter on each loop in order to look for an single entry
anotherDirectorySearcher.Filter = $"(samaccountname={(string)result.Properties["samaccountname"][0]})";
List<string> memberOf = new List<string>();
foreach(var member in anotherDirectorySearcher.FindOne().Properties["memberOf"])
{
memberOf.Add((string)member);
}
}
}
cookie = sync.GetDirectorySynchronizationCookie();
}
注意:
dirSearch.Filter = "(objectCategory=person)";
// Here you override the previous one (the Filter property is a string)
dirSearch.Filter = "(objectClass=user)";
// If you want both, you can use:
dirSearch.Filter = "(&(objectCategory=person)(objectClass=user))";