使用LDAP WITHOUT servername从Java(Linux)到Active Directory进行身份验证

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用LDAP WITHOUT servername从Java(Linux)到Active Directory进行身份验证相关的知识,希望对你有一定的参考价值。

我们的开发人员在Linux上使用Java来处理各种事情(比如检查组的成员身份等)。它的工作原理 - 没问题!

问题是他们在代码中硬编码了域控制器(LDAP服务器)的服务器名称。所以现在当我们需要用更新的DC替换它们时,他们需要更改代码。

Active Directory本质上是多余的。域名(例如:domain.local)是我们AD可用的所有DC的循环。

有没有办法让开发人员不指定域控制器服务器名称,而只是指定Active Directory域名,然后他们的Linux服务器会找到DC:s并使用哪个启动并运行?

示例/链接表示赞赏。谢谢!

答案

显然,服务器名称至少应该是可配置的,而不是硬编码到应用程序中。

但是,您应该能够通过查找特殊DNS记录(即_ldap._tcp.DOMAINNAME的SRV记录)来查找服务器。必须将linux服务器配置为使用与AD更新相同的DNS服务器。

要确定这是否可行,请在Linux服务器上运行命令host -t srv _ldap._tcp.DOMAINNAME

另请参阅Querying the DNS service records to find the hostname and TCP/IP提供了有关如何在java中查找SRV记录的一些信息,以及https://community.oracle.com/blogs/kohsuke/2008/06/12/more-active-directory-integration-java

另一答案

我们使用适用于大量系统的以下代码:

/**
 * 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");
}

以上是关于使用LDAP WITHOUT servername从Java(Linux)到Active Directory进行身份验证的主要内容,如果未能解决你的问题,请参考以下文章

OpenSUSE Apache - Windows LDAP - 组用户认证 - Mercurial

如何枚举 Active Directory 架构属性?

serverproperty('servername') 和 @@servername 返回的值Server name 不同

将“-servername”参数与 openssl s_client 一起使用

Apache2不断重定向到默认页面

使用 PHP 和 MySql 的 Docker - $servername 错误 [重复]