C# Active Directory:获取用户的域名?
我知道以前曾有人问过此类问题,但其他方法现在让我失败。
按照目前的情况,我们的 Windows 服务会轮询 AD,给定 LDAP(即 LDAP://10.32.16.80)和该 AD 服务器中要搜索的用户组列表。 它检索这些给定组中的所有用户,并递归地搜索这些组以查找更多组。 然后,每个用户都会添加到另一个应用程序经过身份验证的用户列表中。
这部分应用程序已成功运行。但是,我们需要每个用户的友好域名(即他们的登录域/用户名的一部分),
因此,如果有一个用户是 TEST 域的一部分,名为 Steve:TEST/steve 是他的登录名。 我能够在 AD 中找到 steve,但是我还需要将“TEST”与他的 AD 信息一起存储。
同样,我可以通过使用目录搜索器和给定的 LDAP IP 很好地找到“steve”,但是给定 LDAP IP,我如何找到友好的域名?
当我尝试以下代码时,在尝试访问“defaultNamingContext”时出现错误:
System.Runtime.InteropServices.COMException (0x8007202A):身份验证机制未知。
下面是代码:
private string SetCurrentDomain(string server)
{
string result = string.Empty;
try
{
logger.Debug("'SetCurrentDomain'; Instantiating rootDSE LDAP");
DirectoryEntry ldapRoot = new DirectoryEntry(server + "/rootDSE", username, password);
logger.Debug("'SetCurrentDomain'; Successfully instantiated rootDSE LDAP");
logger.Debug("Attempting to retrieve 'defaultNamingContext'...");
string domain = (string)ldapRoot.Properties["defaultNamingContext"][0]; //THIS IS WHERE I HIT THE COMEXCEPTION
logger.Debug("Retrieved 'defaultNamingContext': " + domain);
if (!domain.IsEmpty())
{
logger.Debug("'SetCurrentDomain'; Instantiating partitions/configuration LDAP entry");
DirectoryEntry parts = new DirectoryEntry(server + "/CN=Partitions,CN=Configuration," + domain, username, password);
logger.Debug("'SetCurrentDomain'; Successfully instantiated partitions/configuration LDAP entry");
foreach (DirectoryEntry part in parts.Children)
{
if (part.Properties["nCName"] != null && (string)part.Properties["nCName"][0] != null)
{
logger.Debug("'SetCurrentDomain'; Found property nCName");
if ((string)part.Properties["nCName"][0] == domain)
{
logger.Debug("'SetCurrentDomain'; nCName matched defaultnamingcontext");
result = (string)part.Properties["NetBIOSName"][0];
logger.Debug("'SetCurrentDomain'; Found NetBIOSName (friendly domain name): " + result);
break;
}
}
}
}
logger.Debug("finished setting current domain...");
}
catch (Exception ex)
{
logger.Error("error attempting to set domain:" + ex.ToString());
}
return result;
}
编辑
我添加了此示例方法以尝试建议,但当我在搜索器上调用“FindAll()”时,出现异常:“未指定错误”。 传入的字符串为:“CN=TEST USER,CN=Users,DC=tempe,DC=ktregression,DC=com”
private string GetUserDomain(string dn)
{
string domain = string.Empty;
string firstPart = dn.Substring(dn.IndexOf("DC="));
string secondPart = "CN=Partitions,CN=Configuration," + firstPart;
DirectoryEntry root = new DirectoryEntry(secondPart, textBox2.Text, textBox3.Text);
DirectorySearcher searcher = new DirectorySearcher(root);
searcher.SearchScope = SearchScope.Subtree;
searcher.ReferralChasing = ReferralChasingOption.All;
searcher.Filter = "(&(nCName=" + firstPart + ")(nETBIOSName=*))";
try
{
SearchResultCollection rs = searcher.FindAll();
if (rs != null)
{
domain = GetProperty(rs[0], "nETBIOSName");
}
}
catch (Exception ex)
{
}
return domain;
I know that this type of question has been asked before, but other methods are failing me right now.
As it stands our windows service polls AD, given an LDAP (i.e. LDAP://10.32.16.80) and a list of usergroups within that AD server to search for.
It retrieves all users within those given groups, recursively searching those groups for more groups as well.
Each user is then added to another applications authenticated users list.
This part of the application is running successfully. However, we're in need of each user's friendly domain name (i.e. the part of their login DOMAIN/username)
So if there is a user that is part of TEST domain, named Steve: TEST/steve is his login.
I'm able to find steve in the AD, however I also need "TEST" to be stored along with his AD information.
Again, I can find 'steve' fine by using a directory searcher and the LDAP IP I'm given, but given the LDAP IP, how can I find the friendly domain name?
When I try the following code I'm given an error when attempting to access the 'defaultNamingContext':
System.Runtime.InteropServices.COMException (0x8007202A): The authentication mechanism is unknown.
Here is the code:
private string SetCurrentDomain(string server)
{
string result = string.Empty;
try
{
logger.Debug("'SetCurrentDomain'; Instantiating rootDSE LDAP");
DirectoryEntry ldapRoot = new DirectoryEntry(server + "/rootDSE", username, password);
logger.Debug("'SetCurrentDomain'; Successfully instantiated rootDSE LDAP");
logger.Debug("Attempting to retrieve 'defaultNamingContext'...");
string domain = (string)ldapRoot.Properties["defaultNamingContext"][0]; //THIS IS WHERE I HIT THE COMEXCEPTION
logger.Debug("Retrieved 'defaultNamingContext': " + domain);
if (!domain.IsEmpty())
{
logger.Debug("'SetCurrentDomain'; Instantiating partitions/configuration LDAP entry");
DirectoryEntry parts = new DirectoryEntry(server + "/CN=Partitions,CN=Configuration," + domain, username, password);
logger.Debug("'SetCurrentDomain'; Successfully instantiated partitions/configuration LDAP entry");
foreach (DirectoryEntry part in parts.Children)
{
if (part.Properties["nCName"] != null && (string)part.Properties["nCName"][0] != null)
{
logger.Debug("'SetCurrentDomain'; Found property nCName");
if ((string)part.Properties["nCName"][0] == domain)
{
logger.Debug("'SetCurrentDomain'; nCName matched defaultnamingcontext");
result = (string)part.Properties["NetBIOSName"][0];
logger.Debug("'SetCurrentDomain'; Found NetBIOSName (friendly domain name): " + result);
break;
}
}
}
}
logger.Debug("finished setting current domain...");
}
catch (Exception ex)
{
logger.Error("error attempting to set domain:" + ex.ToString());
}
return result;
}
edit
I added this sample method in order to attempt a suggestion but am getting an exception: "Unspecified error" when I hit the "FindAll()" call on the searcher.
The string being passed in is: "CN=TEST USER,CN=Users,DC=tempe,DC=ktregression,DC=com"
private string GetUserDomain(string dn)
{
string domain = string.Empty;
string firstPart = dn.Substring(dn.IndexOf("DC="));
string secondPart = "CN=Partitions,CN=Configuration," + firstPart;
DirectoryEntry root = new DirectoryEntry(secondPart, textBox2.Text, textBox3.Text);
DirectorySearcher searcher = new DirectorySearcher(root);
searcher.SearchScope = SearchScope.Subtree;
searcher.ReferralChasing = ReferralChasingOption.All;
searcher.Filter = "(&(nCName=" + firstPart + ")(nETBIOSName=*))";
try
{
SearchResultCollection rs = searcher.FindAll();
if (rs != null)
{
domain = GetProperty(rs[0], "nETBIOSName");
}
}
catch (Exception ex)
{
}
return domain;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
本文帮助我了解如何使用 Active Directory。
Howto:(几乎)一切通过 C# 在 Active Directory 中
从现在起,如果您需要进一步的帮助,请在评论中提出适当的问题告诉我,我将尽我所知为您解答。
编辑 #1
您最好使用此示例的过滤器。我编写了一些示例代码来简要展示如何使用
System.DirectoryServices
和System.DirectoryServices.ActiveDirectory
命名空间。 System.DirectoryServices.ActiveDirectory 命名空间用于检索有关林中域的信息。在这里,我没有测试这段代码,可能有一些小问题需要修复。此示例按原样提供,旨在为您提供帮助。我希望这会有所帮助。
编辑 #2
我找到了另一种出路:
下面的示例使用一个NUnit TestCase,您可以自己测试它,看看它是否满足您的要求。
我的灵感来源是:
查找 AD 中域的 NetBios 名称
This article helped me much to understand how to work with the Active Directory.
Howto: (Almost) Everything In Active Directory via C#
From this point forward, if you require further assitance, please let me know with proper questions in comment, and I shall answer them for you to the best of my knowledge.
EDIT #1
You had better go with this example's filter instead. I have written some sample code to briefly show how to work with the
System.DirectoryServices
andSystem.DirectoryServices.ActiveDirectory
namespaces. The System.DirectoryServices.ActiveDirectory namespace is used to retrieve information about the domains within your Forest.Here, I didn't test this code and might have some minor issue to fix. This sample is provided as-is for the sake of helping you. I hope this will help.
EDIT #2
I found out another way out:
The example below uses a NUnit TestCase which you can test for yourself and see if it does what you are required to.
The source from which I inspired myself is:
Find the NetBios Name of a domain in AD
由于我找不到任何示例代码,我想分享我自己的解决方案。这将搜索 DirectoryEntry 对象的父对象,直到它到达domainDNS 类。
像这样使用它:
我没有森林来测试它,但理论上这应该会削减它。
Since I could not find any example code I would like to share my own solution. This will search the parents of the DirectoryEntry object until it hits the domainDNS class.
Use it like this:
I haven't got a forest to test it on but in theory this should cut it.
您可以使用 Environment.UserDomainName 属性。
You can retrieve the name of the domain that the current user is on using the Environment.UserDomainName Property.
也许不完全正确,但是......
因为 de.Path 的值是
Maybe not entirely correct but...
Because the value of de.Path is