Аутентификация из Java (Linux) в Active Directory с использованием LDAP без имени сервера. - PullRequest
6 голосов
/ 22 июня 2010

Наши разработчики используют Java в Linux для различных целей (например, проверка членства в группах и т. Д.).Это работает - с этим проблем нет!

Проблема в том, что они жестко закодировали имена серверов наших контроллеров домена (LDAP-серверов) в своем коде.Поэтому теперь, когда нам нужно заменить их на новые контроллеры домена, им нужно изменить код.

Active Directory по своей природе является избыточным.Доменное имя (пример: domain.local) представляет собой циклический перебор всех DC: s, доступных для нашей AD.

Есть ли возможность для разработчика НЕ ​​указывать имена серверов контроллера домена, а просто активныеДоменное имя каталога, а затем его сервер Linux найдет DC: s и будет использовать тот, который запущен и работает?

Примеры / ссылки приветствуются.Спасибо!

Ответы [ 2 ]

8 голосов
/ 22 июня 2010

Очевидно, что имя сервера должно быть, по крайней мере, настраиваемым, а не жестко закодированным в приложении.

Однако вы сможете найти сервер, просмотрев специальную запись DNS, а именно запись SRV для_ldap._tcp.DOMAINNAME.Серверы Linux должны быть настроены на использование того же DNS-сервера, что и обновления AD.

Чтобы определить, возможно ли это, выполните команду host -t srv _ldap._tcp.DOMAINNAME на вашем linux-сервере

См. Также Запрос записей службы DNS для поиска имени хоста и TCP / IP предоставляет некоторую информацию о том, как искать записи SRV в Java, и https://community.oracle.com/blogs/kohsuke/2008/06/12/more-active-directory-integration-java

2 голосов
/ 24 октября 2012

Мы используем следующий код, который работает на большом количестве систем:

/**
 * Detect the default LDAP server
 * @return server:port or null
 */
String getDefaultLdapHost() {
    try {
        Hashtable<String, String> env = new Hashtable();
        env.put( "java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory" );
        DirContext dns = new InitialDirContext( env );

        InetAddress address = InetAddress.getLocalHost();
        String domain = address.getCanonicalHostName();

        if( domain.equals( address.getHostAddress() ) ) {
            //domain is a ip address
            domain = getDnsPtr( dns );
        }

        int idx = domain.indexOf( '.' );
        if( idx < 0 ) {
            //computer is not in a domain? We will look in the DNS self.
            domain = getDnsPtr( dns );
            idx = domain.indexOf( '.' );
            if( idx < 0 ) {
                //computer is not in a domain
                return null;
            }
        }
        domain = domain.substring( idx + 1 );

        Attributes attrs = dns.getAttributes( "_ldap._tcp." + domain, new String[] { "SRV" } );

        Attribute attr = attrs.getAll().nextElement();
        String srv = attr.get().toString();

        String[] parts = srv.split( " " );
        return parts[3] + ":" + parts[2];
    } catch( Exception ex ) {
        ex.printStackTrace();
        return null;
    }
}

/**
 * Look for a reverse PTR record on any available ip address
 * @param dns DNS context
 * @return the PTR value
 * @throws Exception if the PTR entry was not found
 */
private String getDnsPtr( DirContext dns ) throws Exception {
    Exception exception = null;
    Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
    while(interfaces.hasMoreElements()) {
        NetworkInterface nif = interfaces.nextElement();
        if( nif.isLoopback() ) {
            continue;
        }
        Enumeration<InetAddress> adresses = nif.getInetAddresses();
        while(adresses.hasMoreElements()) {
            InetAddress address = adresses.nextElement();
            if( address.isLoopbackAddress() || address instanceof Inet6Address) {
                continue;
            }
            String domain = address.getCanonicalHostName();
            if( !domain.equals( address.getHostAddress() ) && (domain.indexOf( '.' ) > 0) ) {
                return domain;
            }

            String ip = address.getHostAddress();
            String[] digits = ip.split( "\\." );
            StringBuilder builder = new StringBuilder();
            builder.append( digits[3] ).append( '.' );
            builder.append( digits[2] ).append( '.' );
            builder.append( digits[1] ).append( '.' );
            builder.append( digits[0] ).append( ".in-addr.arpa." );
            try {
                Attributes attrs = dns.getAttributes( builder.toString(), new String[] { "PTR" } );
                return attrs.get( "PTR" ).get().toString();
            } catch( Exception ex ) {
                exception = ex;
            }
        }
    }
    if( exception != null ) {
        throw exception;
    }
    throw new IllegalStateException("No network");
}
...