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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 03:50:38  来源:igfitidea点击:

How can I get DOMAIN\USER from an AD DirectoryEntry?

c#.netactive-directory

提问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 sAMAccountNamewhich typically is something like myuser(without the domain). You have the distinguishedNamewhich is something like LDAP://cn=joe myuser,cn=Users,dc=yourCompany,dc=com. You also have a userPrincipalNamebut 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\MyUserin 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 resultsis 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=Configurationthat contains all domains which gives you the cnwhich is the Netbios domain name and the nCNameproperty that contains the distinguishedNameprefix a user will have if they are in this domain.

有一个分区容器,CN=Partitions,CN=Configuration其中包含所有域,它为您提供cnNetbios 域名和nCName包含distinguishedName用户在此域中将拥有的前缀的属性。

So start by searching ldap for (objectClass=*)in CN=Partitions,CN=Configurationand 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 distinguishedNamefrom the user. Now go through the (cn, nCName) pairs and find the nCNamethat prefixes the distinguishedNamefrom the user, and the corresponding cnis 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