Active Directory 未在 C# 中找到所有用户

发布于 2024-08-13 23:16:49 字数 1067 浏览 7 评论 0原文

我有一些代码可以查询 Active Directory 以验证用户是否存在。我正在尝试验证大约 1300 个 id 的长列表。我尝试了多种方法来验证用户帐户(LINQ to AD、DirectorySearcher(有或没有父 DirectoryEntry)以及链接到 WinNT:// 路径的 DirectoryEntry)。每次都会回来说几个用户不存在。如果我在代码中硬编码它们的用户 ID 并单独执行,它就会验证存在性。如果我尝试在 foreach 循环中执行此操作,则会出现一些漏报。

这是我现在正在使用的代码。

static string[] userIDs = new string[] "user1","user2","user3","user4","user5","user6","user7","user8"...,"user1300"};

List<string> nonExistingUsers = new List<string>();
List<string> ExistingUsers = new List<string>();
foreach (string s in userIDs)
{
 DirectorySearcher search = new DirectorySearcher();
 search.Filter = String.Format("(SAMAccountName={0})", s);
 search.PropertiesToLoad.Add("cn");
 DirectorySearcher ds = new DirectorySearcher(de, "(&(objectClass=user)(cn=" + s + "))", new string[] { "Name" }, SearchScope.Subtree);
 SearchResultCollection resultCollection = ds.FindAll();
 SearchResult result = search.FindOne();
 if (result != null)
  ExistingUsers.Add(s);
 else
  nonExistingUsers.Add(s);
}

我收到漏报的任何建议或原因?

I have some code that queries Active Directory to verify user existence. I am trying to verify a long list of about 1300 ids. I've tried several methods to verify if a user account (LINQ to AD, DirectorySearcher (with and without a parent DirectoryEntry) and also a DirectoryEntry that links to the WinNT:// path). Every time it will come back and say that several users do not exist. If I hardcode their userids in the code and execute for individually, it validates existence. If I try and do it in a foreach loop, I get several false negatives.

Here's the code I am using right now..

static string[] userIDs = new string[] "user1","user2","user3","user4","user5","user6","user7","user8"...,"user1300"};

List<string> nonExistingUsers = new List<string>();
List<string> ExistingUsers = new List<string>();
foreach (string s in userIDs)
{
 DirectorySearcher search = new DirectorySearcher();
 search.Filter = String.Format("(SAMAccountName={0})", s);
 search.PropertiesToLoad.Add("cn");
 DirectorySearcher ds = new DirectorySearcher(de, "(&(objectClass=user)(cn=" + s + "))", new string[] { "Name" }, SearchScope.Subtree);
 SearchResultCollection resultCollection = ds.FindAll();
 SearchResult result = search.FindOne();
 if (result != null)
  ExistingUsers.Add(s);
 else
  nonExistingUsers.Add(s);
}

Any suggestions or reasons why I am getting the false negatives?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

滥情哥ㄟ 2024-08-20 23:16:49

有几点:

  • 首先,尝试在 LDAP 过滤器中使用“anr=”(不明确的名称解析) - 它会搜索多个与名称相关的属性并使搜索更容易。 UserID 可能不是实际“通用名称”(CN=user1) 的一部分

  • 其次,使用 objectCategory 而不是 objectClass - objectCategory 是单值和索引的,因此搜索速度要快一些

  • 第三:为什么你首先调用 .FindAll() 然后在下一行调用 .FindOne() ?似乎根本没有必要......

  • WinNT:// 实际上只是为了向后兼容,如果您需要处理本地计算机帐户 - 尽可能避免它,它也会暴露更少的属性比 LDAP

这是我编写的代码:

static string[] userIDs = new string[] "user1","user2","user3","user4","user5","user6","user7","user8"...,"user1300"};

DirectoryEntry searchRoot = new DirectoryEntry("LDAP://cn=Users,dc=YourComp,dc=com");

List<string> nonExistingUsers = new List<string>();
List<string> ExistingUsers = new List<string>();

foreach (string s in userIDs)
{
   DirectorySearcher search = new DirectorySearcher(searchRoot);

   search.SearchScope = SearchScope.Subtree;
   search.Filter = string.Format("(&(objectCategory=person)(anr={0}))", s);

   SearchResultCollection resultCollection = ds.FindAll();

   if(resultCollection != null && resultCollection.Count > 0)
      ExistingUsers.Add(s);
   else
      nonExistingUsers.Add(s);
}

这在你的场景中有效吗?

另外,如果您使用 .NET 3.5 或更高版本,事情会变得更加容易 - 请参阅:

管理 .NET Framework 3.5 中的目录安全主体

Couple of things:

  • first of all, try using the "anr=" (ambiguous name resolution) in your LDAP filter - it searches several name-related attributes and make searching easier. The UserID might not be part of the actual "common name" (CN=user1)

  • secondly, use the objectCategory instead of objectClass - the objectCategory is single-valued and indexed and thus a fair bit faster on searches

  • thirdly: why are you first calling .FindAll() and then .FindOne() on the next line? Doesn't seem really necessary at all....

  • WinNT:// really is only for backward compatibility and if you need to deal with local computer accounts - try to avoid it whenever possible, it also exposes a lot less properties than LDAP

Here's my code I'd write:

static string[] userIDs = new string[] "user1","user2","user3","user4","user5","user6","user7","user8"...,"user1300"};

DirectoryEntry searchRoot = new DirectoryEntry("LDAP://cn=Users,dc=YourComp,dc=com");

List<string> nonExistingUsers = new List<string>();
List<string> ExistingUsers = new List<string>();

foreach (string s in userIDs)
{
   DirectorySearcher search = new DirectorySearcher(searchRoot);

   search.SearchScope = SearchScope.Subtree;
   search.Filter = string.Format("(&(objectCategory=person)(anr={0}))", s);

   SearchResultCollection resultCollection = ds.FindAll();

   if(resultCollection != null && resultCollection.Count > 0)
      ExistingUsers.Add(s);
   else
      nonExistingUsers.Add(s);
}

Does that work in your scenario??

Also, if you're using .NET 3.5 or higher, things got a lot easier - see:

Managing Directory Security Principals in the .NET Framework 3.5

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文