使用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
serverproperty('servername') 和 @@servername 返回的值Server name 不同