7

我可能只是愚蠢,但我正在尝试使用登录名(“域\用户”)从 C# 在 Active Directory 中查找用户。

我的“骨架”广告搜索功能通常如下所示:

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 中的“我们的用户”OU),这将起作用,但我根本不知道如何根据“域\用户”语法查找用户.

任何指针?

4

3 回答 3

9

您需要设置一个过滤器(DirectorySearcher.Filter),例如:

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

请注意,您只为属性 sAMAccountName 指定用户名(不包括域)。要搜索域\用户,首先找到所需域的命名上下文,然后在那里搜索 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)。

更新:这与您的问题无关,但您发布的示例并未在其使用的一次性对象上调用 Dispose。与所有一次性对象一样,这些对象(DirectoryEntry、DirectorySearcher、SearchResultCollection)应始终被处置,通常使用 using 语句。有关更多信息,请参阅此帖子

于 2008-10-02T10:44:17.043 回答
0

谢谢。我想我可以通过指定“LDAP://{0}.somedomain.com/DC={0},DC=somedomain,DC=com”来获取域(至少在我的 AD 中),将 {0} 替换为域,至少在我们的环境中有效。

但是有一个问题: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”,完整的域是 some.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 回答