Найти доменное имя в Active Directory - PullRequest
8 голосов
/ 07 июня 2011

Я использую приложение ASP.NET 4.0, которое использует имя пользователя (то есть HttpContext.Current.Request.LogonUserIdentity.Name.ToString ()) для управления доступом к различным компонентам.

Возвращаемое имя пользователя имеет вид «abc \ jsmith», где «abc» - это имя домена, а «jsmith» - имя пользователя для входа.

Часть модуля безопасности для этого приложения обращается к группам Active Directory, к которым принадлежит пользователь (например, «Бухгалтерия», «Учетные счета», «AdminDepartment»). Я могу получить имя пользователя из Active Directory с помощью DirectoryEntry.Properties (т.е. System.DirectoryServices.PropertyCollection ")" sAMAccountName ".Value.

Пока все в порядке, но я хочу иметь возможность расширять приложение на несколько доменов, а это значит, что мне нужно найти доменное имя в Active Directory, а также имя пользователя для входа. Я могу получить значение «Domain» из PrincipalContext, но он возвращает «abcdc» вместо «abc». Могу ли я предположить, что это свойство всегда будет возвращать «dc» (как в «Контроллере домена») в конце каждого домена (в этом случае я могу использовать подстроку свойства), или же где-то еще я могу получить пользователя текущее доменное имя?

Ответы [ 4 ]

5 голосов
/ 08 июня 2011

Одна вещь, по которой мне неясно, это ваш вопрос о получении имени домена по заданному каталогу в контроллере домена. Я предполагаю, что у вас есть сервер, который может видеть несколько доверенных доменов, и что пользователь может войти в ваше приложение с любого из них, чтобы вы не знали, с каким доменом вам нужно проверить членство в роли.

Для управления доступом к функциям через членство в ADGroup, вы можете использовать

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

где User.Identity.Name == "userdomain \ user". Я не знаком с проблемами доверия к домену, но это предполагает, что вы можете добавлять пользователей из доверенного домена в группу домена, которой вы управляете, чтобы вам не пришлось беспокоиться о расположении домена группы.

Если вы не можете или если у вас есть одно и то же имя группы в каждом другом домене, то вы могли бы сделать что-то подобное?

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

Некоторые баллы:

  1. , если у вас уже нет большой установленной базы кодов AD, я бы рекомендовал использовать объекты из пространства имен System.DirectoryServices.AccountManagement.
  2. Я настоятельно рекомендую утилиту ADExplorer от Sysinternals, чтобы получить более детальное представление LDAP о ваших доменах, которое помогает при работе со строками подключения LDAP и программированием каталогов в целом.
  3. Если вы знакомы с взаимодействием и вам нужно выполнить любой анализ строки соединения LDAP, проверьте этот сайт .
  4. System.DirectoryServices.AccountManagement. PrincipalContext.Container и System.DirectoryServices. DirectoryEntry.Path свойства возвращают строку подключения LDAP с доменом в конце строки ( т.е. DC = моя компания, DC = com)
  5. Не забывайте о старом надежном Environment.UserDomainName & Environment.UserName (который извлекает WindowsPrincipal из текущего выполняющегося потока; см. Таблица 1: Поток Exposed CurrentPrincipal Object @ http://msdn.microsoft.com/en-us/library/Aa480475.aspx для отличная таблица того, что текущий пользователь находится в среде выполнения asp.net.)

** ОБНОВЛЕНИЕ 08.06.2011 14:15 **

Если я правильно понимаю AD, домен пользователя является неотъемлемой частью объекта пользователя, возвращаемого AD. Расширяя на вашем примере "Боб Ньюаккаунт" ...

Итак, учитывая следующие 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
}

Таким образом, вы сможете получить домен пользователя через различимое имя или userPrincipalName свойства активного каталога. (Примечание: у меня нет удобной настройки двух доменов, поэтому я не могу сейчас протестировать приведенный выше код.) Это становится ближе?

4 голосов
/ 08 июня 2011

Вот способ 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"));
}
1 голос
/ 07 июня 2011

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
0 голосов
/ 07 июня 2011

Вы можете получить пользователей "userprincipalname". Это похоже на адрес электронной почты, но на самом деле это имя samaccountname + @ + domain.name. Следует отметить, что домен Active Directory выглядит как доменное имя в Интернете, а имя домена netbios («abc» из вашего примера) - нет.

Если вы захватите UPN, я думаю, что оно всегда будет содержать доменное имя с точками.

...