I have an application java on tomcat with ldap and I can authenticate without problem. Now, my company would to insert ssl layer on ldap, so I need to use ldaps. Any suggestion to ignore certificate and trust certificate from ldaps server?
This is my code that works for ldap
final String ldapAdServer = "ldap://my_ldap_url:3268";
final String ldapSearchBase = "Ldap_search_base";
//need a default user to be able to do query on AD
final String ldapUsername = "username_path_AD";
final String ldapPassword = "password_path_AD";
Hashtable<String, Object> env = new Hashtable<String, Object>();
env.put(Context.SECURITY_AUTHENTICATION, "simple");
if(ldapUsername != null) {
env.put(Context.SECURITY_PRINCIPAL, ldapUsername);
}
if(ldapPassword != null) {
env.put(Context.SECURITY_CREDENTIALS, ldapPassword);
}
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, ldapAdServer);
//ensures that objectSID attribute values
//will be returned as a byte[] instead of a String
env.put("java.naming.ldap.attributes.binary", "objectSID");
LdapContext ctx = new InitialLdapContext(env,null);
return ctx;
now, I tried to create this class to trust all certificates :
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
public class SSLFix {
public static void execute(){
TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {}
@Override
public void checkServerTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {}
}
};
SSLContext sc=null;
try {
sc = SSLContext.getInstance("SSL");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
try {
sc.init(null, trustAllCerts, new java.security.SecureRandom());
} catch (KeyManagementException e) {
e.printStackTrace();
}
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
// Create all-trusting host name verifier
HostnameVerifier validHosts = new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
};
// All hosts will be valid
HttpsURLConnection.setDefaultHostnameVerifier(validHosts);
}
}
and so I decided to change my previous ldap code with this:
public LdapContext getLDAPContext() throws NamingException
{
SSLFix.execute();
final String ldapAdServer = "ldaps://my_ldap_url:3269";
final String ldapSearchBase = "ldap_search_base";
//need a default user to be able to do query on AD
final String ldapUsername = "username_path_AD";
final String ldapPassword = "password_path_AD";
Hashtable<String, Object> env = new Hashtable<String, Object>();
env.put(Context.SECURITY_AUTHENTICATION, "simple");
if(ldapUsername != null) {
env.put(Context.SECURITY_PRINCIPAL, ldapUsername);
}
if(ldapPassword != null) {
env.put(Context.SECURITY_CREDENTIALS, ldapPassword);
}
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, ldapAdServer);
//ensures that objectSID attribute values
//will be returned as a byte[] instead of a String
env.put("java.naming.ldap.attributes.binary", "objectSID");
LdapContext ctx = new InitialLdapContext(env,null);
return ctx;
}
but when I execute the control for ldaps, I obtain this error:
javax.naming.CommunicationException: simple bind failed: [Root exception is javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target]