In my application, I am providing support for Native AD and LDAP. When i am trying to authenticate user using NativeAD its working fine, But for LDAP (we need to install application on linux), I am getting javax.security.auth.login.FailedLoginException: Cannot bind to LDAP server.
Error stack:-
Caused by: javax.security.auth.login.FailedLoginException: Cannot bind to LDAP server
...
Caused by: javax.naming.CommunicationException: simple bind failed: mydomain.com:3269
com.sun.jndi.ldap.LdapClient.authenticate(Unknown Source)
com.sun.jndi.ldap.LdapCtx.connect(Unknown Source)
com.sun.jndi.ldap.LdapCtx.<init>(Unknown Source)
com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(Unknown Source)
com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(Unknown Source)
com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(Unknown Source)
com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(Unknown Source)
javax.naming.spi.NamingManager.getInitialContext(Unknown Source)
javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)
javax.naming.InitialContext.init(Unknown Source)
javax.naming.ldap.InitialLdapContext.<init>(Unknown Source)
...
Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative DNS name matching mydomain.com found.
sun.security.ssl.Alerts.getSSLException(Unknown Source)
sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
sun.security.ssl.Handshaker.fatalSE(Unknown Source)
sun.security.ssl.Handshaker.fatalSE(Unknown Source)
sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
sun.security.ssl.Handshaker.processLoop(Unknown Source)
sun.security.ssl.Handshaker.process_record(Unknown Source)
sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
sun.security.ssl.SSLSocketImpl.writeRecord(Unknown Source)
sun.security.ssl.AppOutputStream.write(Unknown Source)
java.io.BufferedOutputStream.flushBuffer(Unknown Source)
java.io.BufferedOutputStream.flush(Unknown Source)
com.sun.jndi.ldap.Connection.writeRequest(Unknown Source)
com.sun.jndi.ldap.Connection.writeRequest(Unknown Source)
com.sun.jndi.ldap.LdapClient.ldapBind(Unknown Source)
com.sun.jndi.ldap.LdapClient.authenticate(Unknown Source)
com.sun.jndi.ldap.LdapCtx.connect(Unknown Source)
com.sun.jndi.ldap.LdapCtx.<init>(Unknown Source)
com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(Unknown Source)
com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(Unknown Source)
com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(Unknown Source)
com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(Unknown Source)
javax.naming.spi.NamingManager.getInitialContext(Unknown Source)
javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)
javax.naming.InitialContext.init(Unknown Source)
javax.naming.ldap.InitialLdapContext.<init>(Unknown Source)
...
Caused by: java.security.cert.CertificateException: No subject alternative DNS name matching mydomain.com found.
sun.security.util.HostnameChecker.matchDNS(Unknown Source)
sun.security.util.HostnameChecker.match(Unknown Source)
sun.security.ssl.X509TrustManagerImpl.checkIdentity(Unknown Source)
sun.security.ssl.X509TrustManagerImpl.checkIdentity(Unknown Source)
sun.security.ssl.X509TrustManagerImpl.checkTrusted(Unknown Source)
sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
sun.security.ssl.Handshaker.processLoop(Unknown Source)
sun.security.ssl.Handshaker.process_record(Unknown Source)
sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
sun.security.ssl.SSLSocketImpl.writeRecord(Unknown Source)
sun.security.ssl.AppOutputStream.write(Unknown Source)
java.io.BufferedOutputStream.flushBuffer(Unknown Source)
java.io.BufferedOutputStream.flush(Unknown Source)
com.sun.jndi.ldap.Connection.writeRequest(Unknown Source)
com.sun.jndi.ldap.Connection.writeRequest(Unknown Source)
com.sun.jndi.ldap.LdapClient.ldapBind(Unknown Source)
com.sun.jndi.ldap.LdapClient.authenticate(Unknown Source)
com.sun.jndi.ldap.LdapCtx.connect(Unknown Source)
com.sun.jndi.ldap.LdapCtx.<init>(Unknown Source)
com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(Unknown Source)
com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(Unknown Source)
com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(Unknown Source)
com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(Unknown Source)
javax.naming.spi.NamingManager.getInitialContext(Unknown Source)
javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)
javax.naming.InitialContext.init(Unknown Source)
javax.naming.ldap.InitialLdapContext.<init>(Unknown Source)
Also I observed when, I am trying to run application using JRE 1.8.172 same code work fine. In windows JRE 1.8.192 also working. I also added mydomain.com in my DNS. and mydomain.com certificate in my code.
There has been a change in Java 8 update 181 and later with the default settings in JNDI when a client connects to a server using SSL. If the server's certificate hostname doesn't match the host that the client connected to, the connection is rejected with that exact message.
The issue and the workaround are described in the Java 8 update 181 release notes:
Disable endpoint identification using a new system property:
com.sun.jndi.ldap.object.disableEndpointIdentification
. Define this system property (or set it to true) to disable endpoint identification algorithms.