如何在 Active Directory 中查找用户?
一些示例用户名是:
contoso\ian
[email protected]
[email protected]
contoso.com\ian
需要注意的是,我不知道域名,而且我不应该对其进行硬编码。
有一些堆栈溢出的示例代码失败了。
using System.DirectoryServices;
/// <summary>
/// Gets the email address, if defined, of a user from Active Directory.
/// </summary>
/// <param name="userid">The userid of the user in question. Make
/// sure the domain has been stripped first!</param>
/// <returns>A string containing the user's email address, or null
/// if one was not defined or found.</returns>
public static string GetEmail(string userid)
{
DirectorySearcher searcher;
SearchResult result;
string email;
// Check first if there is a slash in the userid
// If there is, domain has not been stripped
if (!userid.Contains("\\"))
{
searcher = new DirectorySearcher();
searcher.Filter = String.Format("(SAMAccountName={0})", userid);
searcher.PropertiesToLoad.Add("mail");
result = searcher.FindOne();
if (result != null)
{
email = result.Properties["mail"][0].ToString();
}
}
return email;
}
它特别确保您没有传递完整的用户名。例如
Bad: avatopia\ian
Bad: avatar\ian
Good: ian
Good: ian
因为不允许你通过域名,所以无法区分两个用户
ian
ian
另一个人在 sackoverflow 上有同样的问题,但接受的答案表明你必须:
首先找到命名上下文 所需的域名
我不知道什么是“命名上下文”,而且我不知道“所需域”是什么。我真的不想编写正则表达式来尝试将用户名解析为域名和帐户名,例如
domain.something\user-name
进入
domain.something
user-name
因为我知道在某些边缘情况下我会出错(例如
[email protected]
。我想要在 Active Directory 中查找用户的正确的、预期的方法。
CodeProject 上有一个不错的页面 如何在 Active Directory 中执行几乎所有操作,但您无法通过用户名查找用户信息。
我希望我可以给我的域控制器(无论它是谁,无论它在哪里,无论它叫什么)一个用户名,它会找出该用户属于哪个域,与该域控制器对话,并获得工作完成了。
这对我有用。
您应该能够区分不同域控制器上的不同用户(即域/用户名),因为 ldappath 会有所不同。根据您的说法,您不在乎,因为您未指定 ldapppath。
您正在大肆剥离 User.Identity.Name 的域/。但我不确定你在担心什么,你只需要把绳子砍成两半,当你第一次遇到“”时,就该砍了。
如果您不喜欢这样,可以使用“正确的方式”:http://msdn.microsoft.com/en-us/library/ms973834.aspx
这也很好http://geekswithblogs.net/mhamilton/archive/2005/09/30/55621.aspx
/// This is some imaginary code to show you how to use it
Session["USER"] = User.Identity.Name.ToString();
Session["LOGIN"] = RemoveDomainPrefix(User.Identity.Name.ToString()); // not a real function :D
string ldappath = "LDAP://your_ldap_path";
// "LDAP://CN=<group name>, CN =<Users>, DC=<domain component>, DC=<domain component>,..."
Session["cn"] = GetAttribute(ldappath, (string)Session["LOGIN"], "cn");
Session["displayName"] = GetAttribute(ldappath, (string)Session["LOGIN"], "displayName");
Session["mail"] = GetAttribute(ldappath, (string)Session["LOGIN"], "mail");
Session["givenName"] = GetAttribute(ldappath, (string)Session["LOGIN"], "givenName");
Session["sn"] = GetAttribute(ldappath, (string)Session["LOGIN"], "sn");
/// working code
public static string GetAttribute(string ldappath, string sAMAccountName, string attribute)
{
string OUT = string.Empty;
try
{
DirectoryEntry de = new DirectoryEntry(ldappath);
DirectorySearcher ds = new DirectorySearcher(de);
ds.Filter = "(&(objectClass=user)(objectCategory=person)(sAMAccountName=" + sAMAccountName + "))";
SearchResultCollection results = ds.FindAll();
foreach (SearchResult result in ds.FindAll())
{
OUT = GetProperty(result, attribute);
}
}
catch (Exception t)
{
// System.Diagnostics.Debug.WriteLine(t.Message);
}
return (OUT != null) ? OUT : string.Empty;
}
public static string GetProperty(SearchResult searchResult, string PropertyName)
{
if (searchResult.Properties.Contains(PropertyName))
{
return searchResult.Properties[PropertyName][0].ToString();
}
else
{
return string.Empty;
}
}
对于域名/用户名
public static string GetDomain(string s)
{
int stop = s.IndexOf("\\");
return (stop > -1) ? s.Substring(0, stop + 1) : null;
}
public static string GetLogin(string s)
{
int stop = s.IndexOf("\\");
return (stop > -1) ? s.Substring(stop + 1, s.Length - stop - 1) : null;
}
对于用户名@域名样式
public static string GetDomain(string s) //untested
{
int stop = s.IndexOf("@");
return (stop > -1) ? s.Substring(stop + 1, s.Length - stop - 1) : null;
}
public static string GetLogin(string s) //untested
{
int stop = s.IndexOf("@");
return (stop > -1) ? s.Substring(0, stop) : null;
}
我不知道纯.net方法。但您可以使用 win32 的 CredUIParseUserName。