Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在Active Directory中查找具有登录名的用户_C#_Active Directory - Fatal编程技术网

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

C# 在Active Directory中查找具有登录名的用户,c#,active-directory,C#,Active Directory,我可能很愚蠢,但我正在尝试使用登录名(“域\用户”)从C#在Active Directory中查找用户 我的“骨架”广告搜索功能通常如下所示: de = new DirectoryEntry(string.Format("LDAP://{0}", ADSearchBase), null, null, AuthenticationTypes.Secure); ds = new DirectorySearcher(de); ds.SearchScope = SearchScope.Subtree;

我可能很愚蠢,但我正在尝试使用登录名(“域\用户”)从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),这就行了,但我根本不知道如何根据“域\用户”语法查找用户

有指针吗?

您需要设置一个过滤器(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语句进行处理。有关更多信息,请参阅。

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

但有一个问题:sAMAccountName似乎被贬低了:

这仍然是最好的方法吗?还是有一个更“现代”的领域可以查询?(Windows 2003 Active Directory、Windows XP或2003客户端、.net 3.0)

编辑:再次感谢。我们的结构有点复杂:我们有一个大的“domain.com”森林,有几个区域办事处的域。本质上:登录名是“something\username”,完整域是us something.domain.com,邮件是user@domain.com(不带某物),但主要名称是user@something.domain.com. 我将手动将某物\username“翻译”为username@something.domain.com,因为这似乎是最可靠的方法。尤其是因为我想保留自动发现功能。

登录名(Windows 2000之前的版本)

登录名(Windows 2000及以上版本)


我认为更现代的方法是使用userPrincipalName属性——它是RFC822格式(通常是用户的电子邮件地址)。但是我总是使用sAMAccountName。如何首先找到所需域的命名上下文,然后在那里搜索?
"(&(objectCategory=person)(objectClass=user)(!sAMAccountType=805306370)(sAMAccountName=John))"
"(&(objectCategory=person)(objectClass=user)(!sAMAccountType=805306370)(userPrincipalName=John))"