7

私は愚かなのかもしれませんが、ログイン名 (「ドメイン\ユーザー」) を使用して、C# から Active Directory でユーザーを見つけようとしています。

私の「スケルトン」AD 検索機能は通常、次のようになります。

de = new DirectoryEntry(string.Format("LDAP://{0}", ADSearchBase), null, null, AuthenticationTypes.Secure);
ds = new DirectorySearcher(de);
ds.SearchScope = SearchScope.Subtree;
ds.PropertiesToLoad.Add("directReports");
ds.PageSize = 10;
ds.ServerPageTimeLimit = TimeSpan.FromSeconds(2);
SearchResult sr = ds.FindOne();

これで、ユーザーの完全な DN (ADSearchBase は通常、Active Directory の「Our Users」OU を指します) があれば機能しますが、「domain\user」構文に基づいてユーザーを検索する方法がわかりません。 .

ポインタはありますか?

4

3 に答える 3

9

次のようなフィルタ(DirectorySearcher.Filter)を設定する必要があります。

"(&(objectCategory = person)(objectClass = user)(sAMAccountName = {0}))"

プロパティsAMAccountNameにはユーザー名(ドメインなし)のみを指定することに注意してください。domain \ userを検索するには、最初に必要なドメインの名前付けコンテキストを見つけてから、そこでsAMAccountNameを検索します。

ちなみに、String.Formatを使用してLDAPクエリ文字列を作成する場合は、通常、特殊文字をエスケープするように注意する必要があります。アカウント名はおそらく必要ありませんが、ユーザーの名(givenNameプロパティ)や姓(snプロパティ)などの他のプロパティで検索している場合は必要になる可能性があります。これを行うためのユーティリティメソッドEscapeFilterLiteralがあります。次のように文字列を作成します。

String.Format("(&(objectCategory=person)(objectClass=user)(sn={0}))", 
              EscapeFilterLiteral(lastName, false)); 

ここで、EscapeFilterLiteralは次のように実装されます。

public static string EscapeFilterLiteral(string literal, bool escapeWildcards)
{
    if (literal == null) throw new ArgumentNullException("literal");

    literal = literal.Replace("\\", "\\5c");
    literal = literal.Replace("(", "\\28");
    literal = literal.Replace(")", "\\29");
    literal = literal.Replace("\0", "\\00");
    literal = literal.Replace("/", "\\2f");
    if (escapeWildcards) literal = literal.Replace("*", "\\2a");
    return literal;
}

この実装では、*文字をリテラルの一部(escapeWildcard = true)またはワイルドカード文字(escapeWildcard = false)として扱うことができます。

更新:これはあなたの質問とは何の関係もありませんが、あなたが投稿した例では、使用する使い捨てオブジェクトの廃棄を呼び出していません。すべての使い捨てオブジェクトと同様に、これらのオブジェクト(DirectoryEntry、DirectorySearcher、SearchResultCollection)は、通常はusingステートメントを使用して常に破棄する必要があります。詳細については、この投稿を参照してください。

于 2008-10-02T10:44:17.043 に答える
0

ありがとう。「LDAP://{0}.somedomain.com/DC={0},DC=somedomain,DC=com」を指定し、{0} を少なくとも私の環境では機能するドメイン。

ただし、1 つの質問: sAMAccountName は減価償却されているようです: Windows NT 4.0、Windows 95、Windows 98、LAN Manager などの古いバージョンのオペレーティング システムを実行しているクライアントとサーバーをサポートするために使用されるログオン名です。古いクライアントをサポートするには、この属性を 20 文字未満にする必要があります。

これはまだ最善のアプローチですか?または、クエリするより「モダンな」フィールドはありますか? (Windows 2003 Active Directory、Windows XP または 2003 クライアント、.net 3.0)

編集:ありがとうございました。私たちの構造は少し複雑です。大きな "domain.com" フォレストがあり、支社用のドメインがいくつかあります。本質的に: ログインは「something\username」、完全なドメイン us something.domain.com、メールは user@domain.com (something なし) ですが、プリンシパル名は user@something.domain.com です。これが最も堅牢な方法と思われるため、something\username を username@something.domain.com に手動で「変換」します。特に、自動検出機能を維持したいので.

于 2008-10-02T11:57:04.917 に答える
-1

ログオン名 (Windows 2000 より前)

"(&(objectCategory=person)(objectClass=user)(!sAMAccountType=805306370)(sAMAccountName=John))"

ログオン名 (Windows 2000 以降)

"(&(objectCategory=person)(objectClass=user)(!sAMAccountType=805306370)(userPrincipalName=John))"
于 2013-08-13T18:03:49.887 に答える