C# 如何从 AD DirectoryEntry 获取 DOMAIN\USER?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/941002/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I get DOMAIN\USER from an AD DirectoryEntry?
提问by laktak
How can I get the Windows user and domain from an Active Directory DirectoryEntry (SchemaClassName="user") object?
如何从 Active Directory DirectoryEntry (SchemaClassName="user") 对象获取 Windows 用户和域?
The user name is in the sAMAccountName property but where can I look up the domain name?
用户名在 sAMAccountName 属性中,但我可以在哪里查找域名?
(I can't assume a fixed domain name because the users are from various subdomains.)
(我不能假设一个固定的域名,因为用户来自不同的子域。)
采纳答案by laktak
I found a partitions container in CN=Partitions,CN=Configuration that contains all domains.
我在 CN=Partitions,CN=Configuration 中找到了一个包含所有域的分区容器。
When you match the user to the partion you can read the real domain name from the nETBIOSName+"\"+sAMAccountName property.
当您将用户与分区匹配时,您可以从 nETBIOSName+"\"+sAMAccountName 属性中读取真实的域名。
回答by joshua.ewer
If you are using the System.DirectoryServiceslibraries, you should have a SearchResultsCollection from a DirectorySearcher.
如果您正在使用System.DirectoryServices库,则您应该拥有来自 DirectorySearcher 的 SearchResultsCollection。
Within each SearchResult's Properties collection, there is a "distinguishedname" property. That will contain all the DC parts that make up the domain your directory entry belongs to.
在每个 SearchResult 的 Properties 集合中,都有一个“distinguishedname”属性。这将包含构成目录条目所属域的所有 DC 部分。
回答by marc_s
You won't find what you're looking for in the DirectoryEntry, unfortunately.
不幸的是,您不会在 DirectoryEntry 中找到您要查找的内容。
You have the sAMAccountName
which typically is something like myuser
(without the domain). You have the distinguishedName
which is something like LDAP://cn=joe myuser,cn=Users,dc=yourCompany,dc=com
. You also have a userPrincipalName
but that's usually a name in the format of [email protected]
.
你有sAMAccountName
通常是这样的myuser
(没有域)。你有distinguishedName
类似的东西LDAP://cn=joe myuser,cn=Users,dc=yourCompany,dc=com
。您也有一个,userPrincipalName
但通常是[email protected]
.
But you won't find any attribute that has the domain\MyUser
in it, unfortunately. You'll have to put that together from your information about the domain name, and the sAMAccountName of the DirectoryEntry.
但domain\MyUser
不幸的是,您不会找到任何包含 的属性。您必须将有关域名的信息和 DirectoryEntry 的 sAMAccountName 放在一起。
For more information and some excellent Excel sheets on all the LDAP and WinNT properties in System.DirectoryServices, check out the Hilltop Labwebsite by ADSI MVP Richard Mueller.
有关 System.DirectoryServices 中所有 LDAP 和 WinNT 属性的更多信息和一些出色的 Excel 表格,请查看ADSI MVP Richard Mueller的Hilltop Lab网站。
Marc
马克
回答by laktak
This assumes that results
is a SearchResultCollection obtained from a DirectorySearcher, but you should be able to get the objectsid from a DirectoryEntry directly.
这假定它results
是从 DirectorySearcher 获得的 SearchResultCollection,但您应该能够直接从 DirectoryEntry 获取 objectid。
SearchResult result = results[0];
var propertyValues = result.Properties["objectsid"];
var objectsid = (byte[])propertyValues[0];
var sid = new SecurityIdentifier(objectsid, 0);
var account = sid.Translate(typeof(NTAccount));
account.ToString(); // This give the DOMAIN\User format for the account
回答by tchimev
To get the DirectoryEntry domain name you can use recursion on
directoryEntry.Parent
.
And then if directoryEntry.SchemaClassName == "domainDNS"
you can get the domain name like this:
要获取 DirectoryEntry 域名,您可以在
directoryEntry.Parent
. 然后,如果directoryEntry.SchemaClassName == "domainDNS"
您可以像这样获得域名:
directoryEntry.Properties["Name"].Value
回答by WWC
1) You can get the userPrincipalName from the DirectoryEntry.
1) 您可以从 DirectoryEntry 中获取 userPrincipalName。
2) Then, split the UPN up between the Username and Domain Name.
2) 然后,在用户名和域名之间拆分 UPN。
3) Then call GetNetBIOSName() on it.
3) 然后在其上调用 GetNetBIOSName()。
public static DirectoryEntry GetDirectoryObject(string strPath)
{
if (strPath == "")
{
strPath = ConfigurationManager.AppSettings["LDAPPath"]; //YOUR DEFAULT LDAP PATH ie. LDAP://YourDomainServer
}
string username = ConfigurationManager.AppSettings["LDAPAccount"];
string password = ConfigurationManager.AppSettings["LDAPPassword"];
//You can encrypt and decrypt your password settings in web.config, but for the sake of simplicity, I've excluded the encryption code from this listing.
}
catch (Exception ex)
{
HttpContext.Current.Response.Write("user: " + username + ", LDAPAccount: "+ ConfigurationManager.AppSettings["LDAPAccount"] + ".<br /> "+ ex.Message +"<br />");
if (HttpContext.Current.User.Identity != null)
{
HttpContext.Current.Response.Write("HttpContext.Current.User.Identity: " + HttpContext.Current.User.Identity.Name + ", " + HttpContext.Current.User.Identity.IsAuthenticated.ToString() + "<br />");
HttpContext.Current.Response.Write("Windows Identity: " + WindowsIdentity.GetCurrent().Name + ", " + HttpContext.Current.User.Identity.IsAuthenticated.ToString());
}
else
{
HttpContext.Current.Response.Write("User.Identity is null.");
}
HttpContext.Current.Response.End();
}
DirectoryEntry oDE = new DirectoryEntry(strPath, username, password, AuthenticationTypes.Secure);
return oDE;
}
public static string GetNetBIOSName(string DomainName)
{
string netBIOSName = "";
DirectoryEntry rootDSE =GetDirectoryObject(
"LDAP://"+DomainName+"/rootDSE");
string domain = (string)rootDSE.Properties[
"defaultNamingContext"][0];
// netBIOSName += "Naming Context: " + domain + "<br />";
if (!String.IsNullOrEmpty(domain))
{
//This code assumes you have a directory entry at the /CN=Partitions, CN=Configuration
//It will not work if you do not have this entry.
DirectoryEntry parts = GetDirectoryObject(
"LDAP://"+DomainName+"/CN=Partitions, CN=Configuration," + domain);
foreach (DirectoryEntry part in parts.Children)
{
if ((string)part.Properties[
"nCName"][0] == domain)
{
netBIOSName += (string)part.Properties[
"NetBIOSName"][0];
break;
}
}
}
return netBIOSName;
}
public static string GetDomainUsernameFromUPN(string strUPN)
{
string DomainName;
string UserName;
if (strUPN.Contains("@"))
{
string[] ud = strUPN.Split('@');
strUPN= ud[0];
DomainName = ud[1];
DomainName=LDAPToolKit.GetNetBIOSName(DomainName);
UserName= DomainName + "\" + strUPN;
}
else
{
UserName= strUPN;
}
return UserName;
}
回答by WWC
public static string GetDomainNameUserNameFromUPN(string strUPN)
{
try
{
WindowsIdentity wi = new WindowsIdentity(strUPN);
WindowsPrincipal wp = new WindowsPrincipal(wi);
return wp.Identity.Name;
}
catch (Exception ex)
{
}
return "";
}
回答by Nicholas DiPiazza
I'm extending a previous answer by @laktak to provide the details of what he meant.
我正在扩展@laktak 之前的回答,以提供他的意思的详细信息。
There is a partitions container in CN=Partitions,CN=Configuration
that contains all domains which gives you the cn
which is the Netbios domain name and the nCName
property that contains the distinguishedName
prefix a user will have if they are in this domain.
有一个分区容器,CN=Partitions,CN=Configuration
其中包含所有域,它为您提供cn
Netbios 域名和nCName
包含distinguishedName
用户在此域中将拥有的前缀的属性。
So start by searching ldap for (objectClass=*)
in CN=Partitions,CN=Configuration
and store the (cn
, nCName
) pairs of each result to a map.
因此,首先在 ldap(objectClass=*)
中搜索inCN=Partitions,CN=Configuration
并将每个结果的 ( cn
, nCName
) 对存储到映射中。
Next you query ldap using (sAMAccountName=USERIDHERE)
and get the distinguishedName
from the user. Now go through the (cn
, nCName
) pairs and find the nCName
that prefixes the distinguishedName
from the user, and the corresponding cn
is your desired Domain name.
接下来,您使用 ldap 查询(sAMAccountName=USERIDHERE)
并distinguishedName
从用户那里获取。现在遍历 ( cn
, nCName
) 对并找到来自用户的nCName
前缀distinguishedName
,对应的cn
是您想要的域名。
回答by Epervier 666
I wrote this pieces of code for my own usage (in VB.net, easy translation) :
我写了这段代码供我自己使用(在VB.net中,易于翻译):
<System.Runtime.CompilerServices.Extension()>
Public Function GetDomainFQDN(ByVal Entry As DirectoryServices.DirectoryEntry) As String
Try
While Entry.SchemaClassName <> "domainDNS"
Entry = Entry.Parent
End While
Dim DN As String = Entry.Properties("DistinguishedName").Value
Return DN.Replace("DC=", "").Replace(",", ".")
Catch ex As Exception
Debug.WriteLine(ex.ToString)
Return String.Empty
End Try
End Function
<System.Runtime.CompilerServices.Extension()>
Public Function GetDomainNetbiosName(ByVal Entry As DirectoryServices.DirectoryEntry) As String
Try
While Entry.SchemaClassName <> "domainDNS"
Entry = Entry.Parent
End While
Return Entry.Properties("Name").Value
Catch ex As Exception
Debug.WriteLine(ex.ToString)
Return String.Empty
End Try
End Function