gpt4 book ai didi

C# 事件目录 : Get domain name of user?

转载 作者:IT王子 更新时间:2023-10-29 04:30:08 25 4
gpt4 key购买 nike

我知道以前有人问过这种类型的问题,但现在其他方法都不行。

就目前而言,我们的 Windows 服务轮询 AD,给定一个 LDAP(即 LDAP://10.32.16.80)和该 AD 服务器中要搜索的用户组列表。它检索那些给定组中的所有用户,同时递归地在这些组中搜索更多组。然后将每个用户添加到另一个应用程序已验证用户列表。

应用程序的这一部分运行成功。但是,我们需要每个用户的友好域名(即他们的登录域/用户名的一部分)

因此,如果有一个用户是 TEST 域的一部分,名为 Steve:TEST/steve 是他的登录名。我能够在 AD 中找到史蒂夫,但是我还需要“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;

最佳答案

这篇文章帮助我理解了如何使用 Active Directory。
Howto: (Almost) Everything In Active Directory via C#

从现在开始,如果您需要进一步的帮助,请在评论中通过适当的问题告诉我,我会尽我所知为您解答。

编辑#1

你最好改用这个例子的过滤器。我已经编写了一些示例代码来简要说明如何使用 System.DirectoryServicesSystem.DirectoryServices.ActiveDirectory namespace 。 System.DirectoryServices.ActiveDirectory 命名空间用于检索有关林中域的信息。

private IEnumerable<DirectoryEntry> GetDomains() {
ICollection<string> domains = new List<string>();

// Querying the current Forest for the domains within.
foreach(Domain d in Forest.GetCurrentForest().Domains)
domains.Add(d.Name);

return domains;
}

private string GetDomainFullName(string friendlyName) {
DirectoryContext context = new DirectoryContext(DirectoryContextType.Domain, friendlyName);
Domain domain = Domain.GetDomain(context);
return domain.Name;
}

private IEnumerable<string> GetUserDomain(string userName) {
foreach(string d in GetDomains())
// From the domains obtained from the Forest, we search the domain subtree for the given userName.
using (DirectoryEntry domain = new DirectoryEntry(GetDomainFullName(d))) {
using (DirectorySearcher searcher = new DirectorySearcher()){
searcher.SearchRoot = domain;
searcher.SearchScope = SearchScope.Subtree;
searcher.PropertiesToLoad.Add("sAMAccountName");
// The Filter is very important, so is its query string. The 'objectClass' parameter is mandatory.
// Once we specified the 'objectClass', we want to look for the user whose login
// login is userName.
searcher.Filter = string.Format("(&(objectClass=user)(sAMAccountName={0}))", userName);

try {
SearchResultCollection results = searcher.FindAll();

// If the user cannot be found, then let's check next domain.
if (results == null || results.Count = 0)
continue;

// Here, we yield return for we want all of the domain which this userName is authenticated.
yield return domain.Path;
} finally {
searcher.Dispose();
domain.Dispose();
}
}
}

在这里,我没有测试这段代码,可能有一些小问题需要修复。为了帮助您,此示例按原样提供。我希望这会有所帮助。

编辑#2

我找到了另一条出路:

  1. 您首先要查看是否可以在您的域中找到该用户帐户;
  2. 如果找到,则获取该域的 NetBIOS 名称;和
  3. 将其连接到反斜杠 (****) 和找到的登录名。

下面的示例使用了一个 NUnit TestCase,您可以自己测试它,看看它是否满足您的要求。

[TestCase("LDAP://fully.qualified.domain.name", "TestUser1")] 
public void GetNetBiosName(string ldapUrl, string login)
string netBiosName = null;
string foundLogin = null;

using (DirectoryEntry root = new DirectoryEntry(ldapUrl))
Using (DirectorySearcher searcher = new DirectorySearcher(root) {
searcher.SearchScope = SearchScope.Subtree;
searcher.PropertiesToLoad.Add("sAMAccountName");
searcher.Filter = string.Format("(&(objectClass=user)(sAMAccountName={0}))", login);

SearchResult result = null;

try {
result = searcher.FindOne();

if (result == null)
if (string.Equals(login, result.GetDirectoryEntry().Properties("sAMAccountName").Value))
foundLogin = result.GetDirectoryEntry().Properties("sAMAccountName").Value
} finally {
searcher.Dispose();
root.Dispose();
if (result != null) result = null;
}
}

if (!string.IsNullOrEmpty(foundLogin))
using (DirectoryEntry root = new DirectoryEntry(ldapUrl.Insert(7, "CN=Partitions,CN=Configuration,DC=").Replace(".", ",DC="))
Using DirectorySearcher searcher = new DirectorySearcher(root)
searcher.Filter = "nETBIOSName=*";
searcher.PropertiesToLoad.Add("cn");

SearchResultCollection results = null;

try {
results = searcher.FindAll();

if (results != null && results.Count > 0 && results[0] != null) {
ResultPropertyValueCollection values = results[0].Properties("cn");
netBiosName = rpvc[0].ToString();
} finally {
searcher.Dispose();
root.Dispose();

if (results != null) {
results.Dispose();
results = null;
}
}
}

Assert.AreEqual("FULLY\TESTUSER1", string.Concat(netBiosName, "\", foundLogin).ToUpperInvariant())
}

我的灵感来源是:
Find the NetBios Name of a domain in AD

关于C# 事件目录 : Get domain name of user?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4249139/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com