Active directory 在Active Directory中查找域名

Active directory 在Active Directory中查找域名,active-directory,dns,Active Directory,Dns,我正在运行一个ASP.NET 4.0应用程序,它使用用户名,即HttpContext.Current.Request.LogonUserIdentity.name.ToString来管理对各种组件的访问 返回的用户名格式为abc\jsmith,其中abc是域名,jsmith是用户的登录名 此应用程序的部分安全模块访问用户所属的Active Directory组,例如Accounting、AccountsPayable、AdminDepartment。我可以使用DirectoryEntry.Pro

我正在运行一个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作为域内控制器,在这种情况下,我可以使用该属性的子字符串,或者是否有其他地方可以获取用户的当前域名?

dc代表域组件。对于使用Active Directory编程来说,一个看起来不错的例子是。这里有很多东西需要复制和粘贴,但我确实找到了可以帮助您的:

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

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


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

以下是找到它的WMI方法。我为您提供了PowerShell编写,但您可以轻松地将其转换为VBScript或C

PS C:\> (Get-WmiObject Win32_NTDomain).DomainName
请注意,“windows 2000之前版本域”的域部分可能与用户主体名称完全不同user@domain用于登录Active Directory。域是主域控制器名称或Netbios域名。域是在域创建期间创建的,默认情况下它是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"));
}

有一件事我不清楚,那就是关于在域控制器中检索给定directoryentry的域名的问题。我假设您有一个可以查看多个受信任域的服务器,并且用户可以从其中任何一个域登录到您的应用程序,这样您就不知道需要针对哪个域测试角色成员资格

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

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

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

HttpContext.Current.User.IsInRole(userDomainname + "\groupname")
有几点:

除非您已经建立了一个大型的AD代码库,否则我建议使用System.DirectoryServices.AccountManagement命名空间中的对象。 我强烈建议使用Sysinternals中的实用程序来获取域的更多LDAP视图,这通常有助于LDAP连接字符串和目录编程。 如果您对互操作感到满意,并且需要执行任何LDAP连接字符串解析,请查看以下内容。 System.DirectoryServices.AccountManagement.PrincipalContext.Container和System.DirectoryServices.DirectoryEntry.Path属性返回LDAP连接字符串,其中域位于字符串的末尾,即DC=mycompany,DC=com 不要忘记可靠的旧Environment.UserDomainName&Environment.UserName,它从当前执行的线程中获取WindowsPrincipal;请参阅表1:线程公开的CurrentPrincipal Object@以了解有关当前用户在asp.net运行时中所处位置的详细表。 **更新时间:2011年6月8日下午2:15**

如果我正确理解AD,用户的域是AD返回的用户对象的一个组成部分

因此,假设以下两个域之间存在信任关系:

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的DifferentizedName或userPrincipalName属性获取用户的域。注意:我手头没有双域设置,因此目前无法测试上述代码。这越来越近了吗?

事实上,在这个例子中,我发现dc是域名设计中心的一部分,而不是域组件。顺便说一下,在我的研究过程中,这是我第二次看到VB.Net方法GetObject,它在C中不起作用。有人用C方法
rks以类似的方式?使用DirectoryEntry.Properties[userPrincipalName].Value对此进行了研究。我仍然把abcdc作为域名。还在调查netBios的事情。再次感谢你的投入。我得到了DC=abcdc。我在访问UserPrincipalName时也遇到了一些问题。我尝试了[UserPrincipalName].Value、[User Prinicpal Name].Value,以及我能想到的所有其他方法,但一直都是空值。当然,它们来自DirectoryEntry.PropertyCollection。我走对了吗再次感谢,BadgerThe Environment.UserDomainName对于查找用户当前登录的计算机的域非常有用。但是,我需要让我的安全管理员能够添加和管理用户。我可以使用sAMAccountName从Active Directory获取用户登录名。但是我怎样才能得到域名呢?这才是真正的问题。顺便说一下,DC=myCompany不是我想要的。这就是给我abcdc的原因。我需要的是abc非常感谢你的意见。它给了我更多的路径去考虑。獾嗯。。。也许这是我当时错过的最基本的东西。因为我相信存储在域控制器中的用户只能来自该域。让我修改我的答案来说明我的意思;SA用户登录到应用程序,该应用程序搜索Active Directory并返回用户列表;SA然后可以选择用户,例如Bob Newaccountant,并向其授予适当功能(例如报告)的权限。我们想设置应用程序,使SA不仅可以看到我们广告中的所有用户,还可以看到他们所在的域。这是否更清楚?再次感谢您的投入。BadgerThis看起来更近了。有没有办法在不知道用户密码的情况下获取ctx数据?当我们处理Active Directory及其组时,我可以将其视为foreach循环,但我无法访问每个用户的密码。再次感谢。我认为我们走在正确的轨道上!!令人惊叹的是的,你不需要用户密码。我们有一个不使用模拟的情况,因此我们有一个特殊的服务帐户设置,用于连接到active directory,这就是用户名和密码的用途。有关不需要用户名和密码的内容,请参阅PrincipalContext的构造函数重载:。已尝试在命令窗口中运行ldifde。获取一个错误,“ldifde”未被识别为内部或外部命令、可操作程序或批处理文件。-幸运的是,我的网络上没有2000年以前的域名。-我将研究将您的PowerShell命令转换为C,以使其更易于集成到应用程序的其余部分中。-谢谢你的意见。BadgerLdifde出现在域控制器上。啊,但我需要能够让我的安全管理员访问此信息,以便管理用户对应用程序各个部分的访问。-谢谢,阿加尼编辑了答案。LDIFDE.EXE只是一个EXE文件,您可以从W2K或W2K3机器上复制。这在获取我所在系统的域名方面非常有效。它正确地显示了域名:abc。但是,我需要能够遍历Active Directory并检查每个名称和域名。或者,我会看看用户“NewHire”的域名是什么?有什么想法吗??谢谢你的帮助。我想我们已经接近我需要的了!!