在Active Directory中查找域名

时间:2011-06-07 17:55:10

标签: active-directory dns

我正在运行一个ASP.NET 4.0应用程序,它使用用户名(即HttpContext.Current.Request.LogonUserIdentity.Name.ToString())来管理对各种组件的访问。

返回的用户名格式为“abc \ jsmith”,其中“abc”是域名,“jsmith”是用户的登录名。

此应用的部分安全模块访问用户所属的Active Directory组(例如,“Accounting”,“AccountsPayable”,“AdminDepartment”)。我可以使用DirectoryEntry.Properties(即System.DirectoryServices.PropertyCollection“)”sAMAccountName“.Value。

从Active Directory中获取用户名。

到目前为止,一切都很好,但我希望能够跨多个域扩展应用程序,这意味着我需要能够在Active Directory中找到域名以及用户的登录名。我可以从PrincipalContext获取“域”值,但它返回“abcdc”,而不是“abc”。我是否可以假设此属性将始终在每个域的末尾返回“dc”(如在“域控制器”中)(在这种情况下,我可以使用属性的子字符串),或者在其他地方我可以获得用户的目前的域名?

4 个答案:

答案 0 :(得分:5)

我不清楚的一件事是你在域控制器中给出一个目录条件检索域名的问题。我假设您有一台可以看到多个受信任域的服务器,并且用户可以从任何一个域登录您的应用程序,这样您就不会知道测试角色成员资格所需的域名。

要通过ADGroup成员资格控制对功能的访问,您可以使用

HttpContext.Current.User.IsInRole("appdomain\groupname") 

其中User.Identity.Name ==“userdomain \ user”。我不熟悉域信任问题,但这假设您可以将受信任域中的用户添加到您控制的域组中,这样您就不必担心组域位置。

如果您不能,或者每个不同的域名中都有相同的组名,那么您可以这样做吗?

HttpContext.Current.User.IsInRole(userDomainname + "\groupname")

有些观点:

  1. 除非您已经拥有大量已建立的AD代码库,否则我建议您使用System.DirectoryServices.AccountManagement命名空间中的对象。
  2. 我强烈推荐来自Sysinternals的ADExplorer实用程序来获取域的更多LDAP视图,这有助于LDAP连接字符串和目录编程。
  3. 如果您对interop感到满意,并且需要执行任何LDAP连接字符串解析,请查看此site
  4. System.DirectoryServices.AccountManagement。 PrincipalContext.Container 和System.DirectoryServices。 DirectoryEntry.Path 属性返回LDAP连接字符串w /域末尾string(即DC = mycompany,DC = com)
  5. 不要忘记可靠的旧环境.UserDomainName& Environment.UserName(从当前正在执行的线程中获取WindowsPrincipal;请参阅表1:线程公开的CurrentPrincipal对象 @ http://msdn.microsoft.com/en-us/library/Aa480475.aspx以获取有关当前用户在asp.net中的内容的精彩表格运行时。)
  6. **更新6/8/2011 2:15 PM **

    如果我正确理解AD,则用户的域是AD返回的用户对象的组成部分。扩展你的“Bob Newaccountant”的例子......

    因此,鉴于以下2个域之间存在信任:

    1. "abcdc.com"
        CN=Users
            CN="Bob NewAccountant"
    2. "abc.com"
        CN=Users
            CN="Local User1"
        OU=Applications
            OU=MyApplication
                CN=ReportReaders (Members: abcdc\BNewAccountant, abc\luser1)
    

    您应该根据以下查询获取用户的信息:

    //name parameter = domain
    //container parameter = distinguished name
    using(var ctx = new PrincipalContext(
                         ContextType.Domain,
                         name: "abc.com",
                         container: "OU=MyApplication,OU=Applications,DC=abc,DC=com",
                         "abc\serviceaccountname",
                         "Password1"))
    {
        var officeGroup = GroupPrincipal.FindByIdentity(ctx,
                                         IdentityType.SamAccountName,
                                         "ReportReaders");
    
        foreach(Principal prin in officeGroup.GetMembers(recursive: true))
        {
            Console.WriteLine("DistinguishedName: " + prin.DistinguishedName 
                + " UPN: " + prin.UserPrincipalName);
        }
        //Should result in
        //  DistinguishedName: CN=luser1,CN=Users,DC=abc,DC=com UPN: luser1@abc.com
        //  DistinguishedName: CN=BNewAccountant,CN=Users,DC=abcdc,DC=com UPN: BNewAccountant@abcdc.com
    }
    

    因此,您应该能够通过Active Directory的 distinguishedName userPrincipalName 属性获取用户的域。 (注意:我没有方便的双域设置,所以我目前无法测试上面的代码。)这是否越来越近了?

答案 1 :(得分:4)

以下是WMI查找方法。我给你PowerShell写作,但你可以轻松地将其转换为VBScript或C#

PS C:\> (Get-WmiObject Win32_NTDomain).DomainName

请注意,'pre windows 2000 domain'的Domain部分可以与用户Principal Name(user @ domain)用于登录Active Directory的完全不同。 DOMAIN是主域控制器名称或Netbios域名。 DOMAIN是在域创建期间创建的,默认情况下它是DNS名称的一部分,但在域创建期间可以完全更改。

您可以使用nETBIOSName属性找到它:

ldifde -f netbios.ldf -d "CN=Partitions,CN=Configuration,DC=your-DNS-Name" -r "(netbiosname=*)" 

被修改

这是CSharp代码

ManagementObjectSearcher domainInfos1 = new ManagementObjectSearcher("select * from WIN32_NTDomain");

foreach (ManagementObject domainInfo in domainInfos1.Get())
{
  Console.WriteLine("Name : {0}", domainInfo.GetPropertyValue("Name"));
  Console.WriteLine("Computer/domain : {0}", domainInfo.GetPropertyValue("Caption"));
  Console.WriteLine("Domain name : {0}", domainInfo.GetPropertyValue("DomainName"));
  Console.WriteLine("Status : {0}", domainInfo.GetPropertyValue("Status"));
}

答案 2 :(得分:1)

DC代表域组件。使用Active Directory进行编程的看似不错的概述是here。那里有一点很多可以在这里做一个像样的复制和粘贴,但我确实找到了可以帮助你的following

domainname=inputbox("Enter DNS Domain Name" & vbcrlf & "(Leave blank for current domain):")
username=inputbox("Enter username:")


IF domainname = "" THEN
    SET objRoot = GETOBJECT("LDAP://RootDSE")
    domainname = objRoot.GET("defaultNamingContext")
END IF

IF username <> "" THEN
    wscript.echo finduser(username,domainname)
END IF


FUNCTION FindUser(BYVAL UserName, BYVAL Domain) 
    ON ERROR RESUME NEXT

    SET cn = CREATEOBJECT("ADODB.Connection")
    SET cmd = CREATEOBJECT("ADODB.Command")
    SET rs = CREATEOBJECT("ADODB.Recordset")

    cn.open "Provider=ADsDSOObject;"

    cmd.activeconnection=cn
    cmd.commandtext="SELECT ADsPath FROM 'LDAP://" & Domain & _
             "' WHERE sAMAccountName = '" & UserName & "'"

    SET rs = cmd.EXECUTE

    IF err<>0 THEN
        FindUser="Error connecting to Active Directory Database:" & err.description
    ELSE
        IF NOT rs.BOF AND NOT rs.EOF THEN
                rs.MoveFirst
                FindUser = rs(0)
        ELSE
            FindUser = "Not Found"
        END IF
    END IF
    cn.close
END FUNCTION

答案 3 :(得分:0)

您可以获得用户“userprincipalname”。它看起来像一个电子邮件地址,但实际上是samaccountname + @ + domain.name。需要注意的一点是,Active Directory域看起来像是互联网域名,但netbios域名(示例中的“abc”)却没有。

如果您抓住UPN,我相信它将始终包含虚线域名。