[英]Correct way to get Microsoft Active Directory attribute “memberOf” when using DirectorySynchronization
I regularly read out the active directory for an application to store the current state in a database.我定期读出应用程序的活动目录,以将当前 state 存储在数据库中。 To reduce the amount of data I use DirectorySynchronization to get only the changes since the last query.
为了减少数据量,我使用 DirectorySynchronization 仅获取自上次查询以来的更改。 But now I also need the attribute "memberOf" which is not provided by the DirectorySearcher when using DirectorySynchronization.
但是现在我还需要使用 DirectorySynchronization 时 DirectorySearcher 未提供的属性“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.目前,我为每个找到的条目获取了 DirectoryEntry,但是随后传递的属性比我需要的要多,这与实际意图相矛盾。
Is there a way to set which attributes are read with DirectoryEntry, similar to PropertiesToLoad with DirectorySearcher or is there better way to read the attribute "memberOf" when using DirectorySynchronization?有没有办法设置使用 DirectoryEntry 读取哪些属性,类似于使用 DirectorySearcher 的 PropertiesToLoad,或者在使用 DirectorySynchronization 时是否有更好的方法来读取属性“memberOf”?
Code excerpt:代码摘录:
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.
但是现在我还需要使用 DirectorySynchronization 时 DirectorySearcher 未提供的属性“memberOf”。
memberOf
is a special attribute computed by the directory, so it's not provided by DirectorySynchronization
(which uses in fact DirSync control ). memberOf
是由目录计算的特殊属性,因此DirectorySynchronization
不提供它(它实际上使用DirSync 控件)。 The only thing that could provide DirectorySynchronization
is the directory's real modification, which belongs to a user's DN added to a group
object in the member
attribute (which kind of triggers a memberOf
recomputation)唯一能提供
DirectorySynchronization
的是目录的真实修改,它属于一个用户的 DN 添加到member
属性中的group
object (哪种触发了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.
目前,我为每个找到的条目获取了 DirectoryEntry,但是随后传递的属性比我需要的要多,这与实际意图相矛盾。
GetDirectoryEntry
performs a new directory search and loads all the attributes (it has no link with the DirectorySearcher
settings and previous search). GetDirectoryEntry
执行新的目录搜索并加载所有属性(它与DirectorySearcher
设置和以前的搜索没有链接)。
So, instead of the GetDirectoryEntry
, you can use another DirectorySearcher
(that will load just the memberOf
) that will do a single search on each loop (example without any strong tests, ie. null
values etc.):因此,您可以使用另一个
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();
}
Note that:注意:
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))";
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.