使用登录名在Active Directory中查找用户

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

我的“Skeleton”AD搜索function通常如下所示:

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),那么这是有效的,但我根本不知道如何根据“domain \ user”语法查找用户。

任何指针?

您需要设置一个filter(DirectorySearcher.Filter),如:

“(&(objectCategory =人)(objectClass的=用户)(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)。

更新:这与您的问题无关,但您发布的示例并未对其使用的一次性对象调用Dispose。 与所有一次性对象一样,这些对象(DirectoryEntry,DirectorySearcher,SearchResultCollection)应始终使用using语句进行处理。 有关详细信息,请参阅此post 。

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

但有一个问题:sAMAccountName似乎已折旧: 用于支持运行旧版操作系统的客户端和服务器的登录名,例如Windows NT 4.0,Windows 95,Windows 98和LAN Manager。 此属性必须少于20个字符才能支持较旧的客户端。

这仍然是最好的方法吗? 或者是否有更“现代”的字段来查询? (Windows 2003 Active Directory,Windows XP或2003客户端,.net 3.0)

编辑:再次感谢。 我们的结构有点复杂:我们有一个很大的“domain.com”森林,有几个区域办事处的域名。 基本上:Login是“something \ username”,完整域名是something.domain.com,邮件是user@domain.com(没有东西),但主要名称是user@something.domain.com。 我将手动“翻译”某些\ username到username@something.domain.com,因为这似乎是最强大的方式。 特别是因为我想保留自动发现function。

登录名(Pre-Windows 2000)

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

登录名(Windows 2000及更高版本)

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