在 Active Directory 中查找具有登录名的用户

本文关键字:登录 用户 Active Directory 查找 | 更新日期: 2023-09-27 17:47:23

我可能只是愚蠢,但我试图使用登录名("域''用户")从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中的"我们的用户"OU),则可以工作,但是我根本不知道如何根据"域''用户"语法查找用户。

有什么指示吗?

在 Active Directory 中查找具有登录名的用户

你需要设置一个过滤器(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)。

更新:这与您的问题无关,但是您发布的示例不会对其使用的一次性物品调用"处理"。 像所有一次性对象一样,这些对象(DirectoryEntry,DirectorySearcher,SearchResultCollection)应始终被释放,通常使用using 语句。 有关更多信息,请参阅此帖子。

谢谢。我想我可以通过指定"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 Client, .net 3.0)

编辑:再次感谢。我们的结构有点复杂:我们有一个很大的"domain.com"森林,有几个区域办事处的域名。本质上:登录名是"something''username",我们 something.domain.com 的完整域,邮件是 user@domain.com 的(没有东西),但主体名称是 user@something.domain.com。我将手动将某些内容''用户名"翻译"为 username@something.domain.com,因为这似乎是最强大的方法。特别是因为我想保留自动发现功能。

登录名(Windows 2000 之前)

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

登录名(视窗2000及以上版本)

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