当前位置: 首页 > 编程语言 > C#

C#ActiveDirectory:获取用户的域名?分享

时间:2023-04-10 19:16:53 C#

C#ActiveDirectory:获取用户的域名?我知道以前有人问过这种类型的问题,但其他方法现在让我失望了。当我们的Windows服务轮询AD时,给定一个LDAP(即LDAP://10.32.16.80)和该AD服务器中要搜索的用户组列表。它检索那些给定组中的所有用户,递归地搜索这些组以查找更多组。然后将每个用户添加到另一个应用程序的已验证用户列表中。应用程序的这一部分成功运行。但是,我们需要每个用户的友好域名(即他们的登录域/用户名的一部分)因此,如果有一个用户属于名为Steve的TEST域:TEST/steve是他的登录名。我能够在AD中找到史蒂夫,但我还需要“TEST”与他的AD信息一起存储。同样,我可以使用目录搜索器和我提供的LDAPIP找到“Steve”,但是如果给出LDAPIP,我如何才能找到友好的域名?当我尝试以下代码时,我在尝试访问“defaultNamingContext”时遇到错误:System.Runtime.InteropServices.COMException(0x8007202A):身份验证机制未知。这是代码:privatestringSetCurrentDomain(stringserver){stringresult=string.Empty;try{logger.Debug("'SetCurrentDomain';实例化rootDSELDAP");DirectoryEntryldapRoot=newDirectoryEntry(server+"/rootDSE",username,password);logger.Debug("'SetCurrentDomain';成功实例化rootDSELDAP");logger.Debug("正在尝试检索'defaultNamingContext'...");字符串域=(字符串)ldapRoot.Properties["defaultNamingContext"][0];//这是我遇到COMEXCEPTION的地方logger.Debug("Retrieved'defaultNamingContext':"+domain);if(!domain.IsEmpty()){logger.Debug("'SetCurrentDomain';实例化分区/配置LDAP条目");DirectoryEntryparts=newDirectoryEntry(server+"/CN=Partitions,CN=Configuration,"+domain,username,password);logger.Debug("'SetCurrentDomain';成功实例化分区/配置LDAP条目");foreach(DirectoryEntrypartinparts.Children){if(part.Properties["nCName"]!=null&&(string)part.Properties["nCName"][0]!=null){logger.Debug("'SetCurrentDomain';FoundpropertynCName");if((string)part.Properties["nCName"][0]==domain){logger.Debug("'SetCurrentDomain';nCNamematcheddefaultnamingcontext");result=(string)part.Properties["NetBIOSName"][0];logger.Debug("'SetCurrentDomain';FoundNetBIOSName(friendlydomainname):"+result);break;}}}}logger.Debug("finishedsettingcurrentdomain...");}catch(Exceptionex){logger.Error("错误试图设置域:"+ex.ToString());}returnresult;}编辑我添加了这个示例方法以尝试建议,但是当我点击搜索器上的"FindAll()"调用时,我得到了异常:“未指定的错误”传入的字符串是:"CN=TESTUSER,CN=Users,DC=tempe,DC=ktregression,DC=com"privatestringGetUserDomain(stringdn){stringdomain=string.Empty;字符串firstPart=dn.Substring(dn.IndexOf("DC="));stringsecondPart="CN=Partitions,CN=Configuration,"+firstPart;DirectoryEntryroot=newDirectoryEntry(secondPart,textBox2.Text,textBox3.Text);DirectorySearchersearcher=newDirectorySearcher(root);searcher.SearchScope=SearchScope.Subtree;searcher.ReferralChasing=ReferralChasingOption.All;searcher.Filter="(&(nCName="+firstPart+")(nETBIOSName=*))";尝试{SearchResultCollectionrs=searcher.FindAll();if(rs!=null){domain=GetProperty(rs[0],"nETBIOSName");}}catch(Exceptionex){}返回域;这篇文章帮助我了解了如何使用ActiveDirectory。Howto:(几乎)通过C#在ActiveDirectory中的所有内容从现在开始,如果您需要进一步的帮助,请在评论中告诉我正确的问题,我将尽我所知回答。编辑#1你最好在这个例子中使用过滤器。我写了一些示例代码来简要说明如何使用System.DirectoryServices和System.DirectoryServices.ActiveDirectory命名空间。System.DirectoryServices.ActiveDirectory命名空间用于检索有关林中域的信息。privateIEnumerableGetDomains(){ICollection域=newList();//查询当前林中的域。foreach(Forest.GetCurrentForest().Domains中的域d)domains.Add(d.Name);返回域;}privatestringGetDomainFullName(stringfriendlyName){DirectoryContextcontext=newDirectoryContext(DirectoryContextType.Domain,friendlyName);域域=Domain.GetDomain(context);返回域名。}privateIEnumerableGetUserDomain(stringuserName){foreach(stringdinGetDomains())//从森林获得的域中,我们搜索给定用户名的域子树。使用(DirectoryEntrydomain=newDirectoryEntry(GetDomainFullName(d))){使用(DirectorySearchersearcher=newDirectorySearcher()){searcher.SearchRoot=domain;searcher.SearchScope=SearchScope.Subtree;searcher.PropertiesToLoad.Add("sAMAccountName");//Filter很重要,它的查询字符串也很重要。'objectClass'参数之三是强制性的。//一旦我们指定了“objectClass”,我们想要查找其登录名//login为userName的用户。searcher.Filter=string.Format("(&(objectClass=user)(sAMAccountName={0}))",userName);尝试{SearchResultCollection结果=searcher.FindAll();//如果找不到用户,那么让我们检查下一个域。如果(结果==null||results.Count=0)继续;//在这里,我们产生回报,因为我们想要这个用户名经过身份验证的所有域。yieldreturndomain.Path;}最后{searcher.Dispose();域名.Dispose();}}}在这里,我没有测试此代码,可能还有一些小问题需要解决,此示例按原样提供以帮助您。我希望这个能帮上忙。编辑#2我找到了另一种出路:您首先必须查看是否可以在您的域中找到用户帐户;如果找到,获取域NetBIOS名称;并将其与反斜杠(****)连接起来,然后找到的登录名。下面的示例使用了NUnitTestCase,您可以自己测试一下,看看它是否符合您的要求。[TestCase("LDAP://fully.qualified.domain.name","TestUser1")]publicvoidGetNetBiosName(stringldapUrl,stringlogin)stringnetBiosName=null;字符串foundLogin=null;使用(DirectoryEntryroot=newDirectoryEntry(ldapUrl))使用(DirectorySearchersearcher=newDirectorySearcher(root){searcher.SearchScope=SearchScope.Subtree;searcher.PropertiesToLoad.Add("sAMAccountName");searcher.Filter=string.Format("(&(objectClass=user)(sAMAccountName={0}))",login);SearchResultresult=null;try{result=searcher.FindOne();if(result==null)if(string.Equals(login,结果.GetDirectoryEntry().Properties("sAMAccountName").Value))foundLogin=result.GetDirectoryEntry().Properties("sAMAccountName").Value}finally{searcher.Dispose();root.Dispose();if(result!=null)result=null;}}if(!string.IsNullOrEmpty(foundLogin))使用(DirectoryEntryroot=newDirectoryEntry(ldapUrl.Insert(7,"CN=Partitions,CN=Configuration,DC=").Replace(".",",DC="))使用DirectorySearchersearcher=newDirectorySearcher(root)searcher.Filter="nETBIOSName=*";searcher.PropertiesToLoad.Add("cn");SearchResultCollection结果=null;尝试{结果=searcher.FindAll();if(results!=null&&results.Count>0&&results[0]!=null){ResultPropertyValueCollectionvalues=results[0].Properties("cn");netBiosName=rpvc[0].ToString();}最后{searcher.Dispose();根.处置();if(results!=null){results.Dispose();结果=空;}}}Assert.AreEqual("FULLYTESTUSER1",string.Concat(netBiosName,"",foundLogin).ToUpperInvariant())}我启发自己的来源是:FindingtheNetBiosnameofadomaininADSinceIcouldn'tfind任何示例代码,我想为此分享我自己的解决方案将搜索DirectoryEntry对象的父级,直到它到达domainDNS类。使用System.DirectoryServices;publicstaticclassMethods{publicstaticTldap_get_value(PropertyValueCollectionproperty){objectvalue=null;foreach(属性中的对象tmpValue)value=tmpValue;返回(T)值;}publicstaticstringldap_get_domainname(DirectoryEntryentry){if(entry==null||entry.Parent==null)returnnull;使用(DirectoryEntryparent=entry.Parent){if(ldap_get_value(parent.Properties["objectClass"])=="domainDNS")returnldap_get_value(parent.Properties["dc"]);否则返回ldap_get_domainname(父);}}}像这样用它:string[]_properties=newstring[]{"objectClass","distinguishedName","samAccountName","userPrincipalName","displayName","mail","title","company","thumbnailPhoto","useraccountcontrol"};stringaccount="我的用户名";//或者更好://stringaccount="my-user-name@DOMAIN.local";使用(DirectoryEntryldap=newDirectoryEntry()){使用(DirectorySearchersearcher=newDirectorySearcher(ldap)){searcher.PropertiesToLoad.AddRange(_properties);如果(account.Contains('@'))searcher.Filter="(userPrincipalName="+account+")";elsesearcher.Filter="(samAccountName="+account+")";varuser=searcher.FindOne().GetDirectoryEntry();Console.WriteLine("名称:"+Methods.ldap_get_value(user.Properties["displayName"]));Console.WriteLine("域名:"+Methods.ldap_get_domainname(user));Console.WriteLine("登录:"+Methods.ldap_get_domainname(user)+"\"+Methods.ldap_get_value(user.Properties["samAccountName"]));我没有森林来测试它,但理论上这应该会减少它您可以使用Environment.UserDomainName属性来检索当前用户所在的域的名称。字符串域名;domainName=System.Environment.UserDomainName;也许不太正确,但是...DirectoryEntrydirEntry=newDirectoryEntry();DirectorySearcherdirSearcher=newDirectorySearcher(dirEntry);dirSearcher.SearchScope=SearchScope.Subtree;dirSearcher.Filter=字符串。Format("(&(objectClass=user)(|(cn={0})(sn={0}*)(givenName={0})(sAMAccountName={0}*)))",userName);varsearchResults=dirSearcher.FindAll();foreach(SearchResultsrinsearchResults){varde=sr.GetDirectoryEntry();stringuser=de.Properties["SAMAccountName"][0].ToString();字符串域=de.Path.ToString().Split(new[]{",DC="},StringSplitOptions.None)[1];MessageBox.Show(域+"/"+用户);}因为de.Path的值为LDAP://CN=FullName,DC=Domain,DC=Local以上是C#学习教程:C#ActiveDirectory:获取用户的域名?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: