3

ActiveDirectoryにクエリを実行してユーザーの存在を確認するコードがいくつかあります。私は約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);
}

フォールスネガティブが発生する提案や理由はありますか?

4

1 に答える 1

4

いくつかのこと:

  • まず、LDAP フィルターで "anr=" (あいまいな名前解決) を使用してみてください。名前に関連するいくつかの属性が検索され、検索が容易になります。UserID は、実際の「共通名」の一部ではない可能性があります (CN=user1)

  • 次に、objectClass の代わりに objectCategory を使用します。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 でのディレクトリ セキュリティ プリンシパルの管理

于 2009-12-01T21:45:04.650 に答える