Reputation: 557
My question is similar to: SSLSocketFactory in java
I need to set a custom SSLSocketFactory...except I do NOT have an https connection (it's LDAPS), so can't use:
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
...to set the SSLSocketFactory. I have an SSLContext object initialized but when I make the LDAP connection the default SSLContext is called automatically since my custom one is not set:
dirContext = new InitialDirContext(env); // <-- reverts to default ssl context
Is there a non-HTTPS equivalent method to line #3 below:
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(myKeyManagerFactory.getKeyManagers(), myTrustManagerArray, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
Upvotes: 1
Views: 3056
Reputation: 81
Note, if the issue is just a hostname mismatch (which is super common in clustered Active Directory Environments), you can just set the system property com.sun.jndi.ldap.object.disableEndpointIdentification to true, so as a command line arg -Dcom.sun.jndi.ldap.object.disableEndpointIdentification=true
Note this will only ignore a hostname mismatch on the certificate, you will still need to have a trust chain from ldap's cert to something in your truststore, but this seems to be the most common issue people have with SSL, LDAP and Active Directory, as the certificate's the domain generate for each domain controller don't include a subject alternate name for the domain itself, so if you follow the standard example of just pointing ldap to yourcomapanydomain.com
, when it resolves to domaincontroller1.yourcompanydomain.com
you get a failure. Note, if you are upgrading from an old java version, this behavior changed in https://www.oracle.com/java/technologies/javase/8u181-relnotes.html
Upvotes: 0
Reputation: 117569
Yes, there is.
env.put("java.naming.ldap.factory.socket", UnsecuredSSLSocketFactory.class.getName());
UnsecuredSSLSocketFactory.java:
public class UnsecuredSSLSocketFactory extends SSLSocketFactory
{
private SSLSocketFactory socketFactory;
public UnsecuredSSLSocketFactory()
{
try
{
var sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[]{new X509TrustManager()
{
@Override
public void checkClientTrusted(X509Certificate[] xcs, String string){}
@Override
public void checkServerTrusted(X509Certificate[] xcs, String string){}
@Override
public X509Certificate[] getAcceptedIssuers()
{
return null;
}
}}, new SecureRandom());
socketFactory = sslContext.getSocketFactory();
}
catch(Exception e)
{
throw new RuntimeException(e);
}
}
@SuppressWarnings("unused")
public static SocketFactory getDefault()
{
return new UnsecuredSSLSocketFactory();
}
@Override
public String[] getDefaultCipherSuites()
{
return socketFactory.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites()
{
return socketFactory.getSupportedCipherSuites();
}
@Override
public Socket createSocket(Socket socket, String string, int i, boolean bln) throws IOException
{
return socketFactory.createSocket(socket, string, i, bln);
}
@Override
public Socket createSocket(String string, int i) throws IOException
{
return socketFactory.createSocket(string, i);
}
@Override
public Socket createSocket(String string, int i, InetAddress ia, int i1) throws IOException
{
return socketFactory.createSocket(string, i, ia, i1);
}
@Override
public Socket createSocket(InetAddress ia, int i) throws IOException
{
return socketFactory.createSocket(ia, i);
}
@Override
public Socket createSocket(InetAddress ia, int i, InetAddress ia1, int i1) throws IOException
{
return socketFactory.createSocket(ia, i, ia1, i1);
}
@Override
public Socket createSocket() throws IOException
{
return socketFactory.createSocket();
}
}
Upvotes: 2