Before starting, ensure that the CA root certificate is available.
Create a key store using the following command.
keytool -import -trustcacerts -file CA_root_certificate_file -keystore keystore_file_name
For testing purposes, let’s assume the keystone_file_name is “jssecacerts".
When the above command is executed, the prompt “Enter keystore password:" will appear.
For testing purposes, we set the password to “123456″.
Then the prompt “Re-enter new password:" will appear. Simply enter “123456″ and then press “enter". After that, the certificate details will be shown on the screen,
and the prompt “Trust this certificate? [no]:" will appear. Type “y" to complete the creation of the keystore.
To establish an SSL connection with the LDAP server, you need to create an SSL socket factory class., the sample code as below:
import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyStore;
import java.util.concurrent.atomic.AtomicReference;
import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
public class SSLSocketFactory extends SocketFactory{
private static final AtomicReference<MySSLSocketFactory> defaultFactory = new AtomicReference<>();
private SSLSocketFactory sf;
public MySSLSocketFactory() {
try {
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
/*
* Use the keytool command to import the hko CA root cert. to the keystore file ./jssecacerts
*/
FileInputStream fis = new FileInputStream("./jssecacerts");
keyStore.load(fis, "123456".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, tmf.getTrustManagers(), null);
sf = ctx.getSocketFactory();
} catch (Exception ff) {
ff.printStackTrace();
}
}
public static SocketFactory getDefault() {
final MySSLSocketFactory value = defaultFactory.get();
if (value == null) {
defaultFactory.compareAndSet(null, new MySSLSocketFactory());
return defaultFactory.get();
}
return value;
}
@Override
public Socket createSocket(String arg0, int arg1) throws IOException, UnknownHostException {
// TODO Auto-generated method stub
return sf.createSocket(arg0, arg1);
}
@Override
public Socket createSocket(InetAddress arg0, int arg1) throws IOException {
// TODO Auto-generated method stub
return sf.createSocket(arg0, arg1);
}
@Override
public Socket createSocket(String arg0, int arg1, InetAddress arg2, int arg3)
throws IOException, UnknownHostException {
// TODO Auto-generated method stub
return sf.createSocket(arg0, arg1,arg2,arg3);
}
@Override
public Socket createSocket(InetAddress arg0, int arg1, InetAddress arg2, int arg3) throws IOException {
// TODO Auto-generated method stub
return sf.createSocket(arg0, arg1,arg2,arg3);
}
}
A sample LDAP query is as below:
Hashtable<String, String> environment = new Hashtable<String, String>();
environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
environment.put(Context.SECURITY_AUTHENTICATION, "simple");
environment.put(Context.SECURITY_PRINCIPAL, user_name);
environment.put(Context.SECURITY_CREDENTIALS, password);
/*
To connect to the LDAP server via SSL channel add the following environmental variables
*/
environment.put(Context.SECURITY_PROTOCOL, "ssl");
environment.put("java.naming.ldap.factory.socket", "SSLSocketFactory");
environment.put(Context.PROVIDER_URL, "ldaps://server_url");
DirContext context = null;
try {
context = new InitialDirContext(environment);
String filter = "(CN=John)";
String[] attrIDs = { "*" };
String fieldName;
SearchControls searchControls = new SearchControls();
searchControls.setReturningAttributes(attrIDs);
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
NamingEnumeration<SearchResult> searchResults = context.search("DC=ad,DC=com", filter,
searchControls);
while (searchResults.hasMoreElements()) {
SearchResult result = searchResults.nextElement();
NamingEnumeration<? extends Attribute> attrs = result.getAttributes().getAll();
while (attrs.hasMore()) {
Attribute a = attrs.nextElement();
fieldName = a.getID();
System.out.print("attribute name=" + fieldName);
System.out.println(",value=" + result.getAttributes().get(fieldName).get());
}
System.out.println("=====================================================");
}
context.close();
} catch (javax.naming.AuthenticationException er) {
System.out.println("Invalid user name or password.");
} catch (NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Reference web page:
https://stackoverflow.com/questions/23144353/how-do-i-initialize-a-trustmanagerfactory-with-multiple-sources-of-trust
https://stackoverflow.com/questions/4615163/how-to-accept-self-signed-certificates-for-jndi-ldap-connections
#java
#Microsoft Active Directory
#LDAP

