Аутентификация AD с одним LDAP не удалась, но прошла с другим LDAP - PullRequest
0 голосов
/ 07 июня 2019

На следующем веб-сайте я нашел коды для выполнения аутентификации java AD.

http://java2db.com/jndi-ldap-programming/solution-to-sslhandshakeexception

Ниже приведены коды:

MySSLSocketFactory.java

import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.SecureRandom;

import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;

public class MySSLSocketFactory extends SSLSocketFactory {
    private SSLSocketFactory socketFactory;
    public MySSLSocketFactory() {
        try {
            SSLContext ctx = SSLContext.getInstance("TLS");
            ctx.init(null, new TrustManager[]{new DummyTrustmanager()}, new SecureRandom());
            socketFactory = ctx.getSocketFactory();
        } catch (Exception ex) {
            ex.printStackTrace(System.err);
        }
    }
    public static SocketFactory getDefault() {
        return new MySSLSocketFactory();
    }
    @Override
    public String[] getDefaultCipherSuites() {
        return socketFactory.getDefaultCipherSuites();
    }
    @Override
    public String[] getSupportedCipherSuites() {
        return socketFactory.getSupportedCipherSuites();
    }
    @Override
    public Socket createSocket(Socket socket, String string, int num, boolean bool) throws IOException {
        return socketFactory.createSocket(socket, string, num, bool);
    }
    @Override
    public Socket createSocket(String string, int num) throws IOException, UnknownHostException {
        return socketFactory.createSocket(string, num);
    }
    @Override
    public Socket createSocket(String string, int num, InetAddress netAdd, int i)
            throws IOException, UnknownHostException {
        return socketFactory.createSocket(string, num, netAdd, i);
    }
    @Override
    public Socket createSocket(InetAddress netAdd, int num) throws IOException {
        return socketFactory.createSocket(netAdd, num);
    }
    @Override
    public Socket createSocket(InetAddress netAdd1, int num, InetAddress netAdd2, int i) throws IOException {
        return socketFactory.createSocket(netAdd1, num, netAdd2, i);
    }
}

DummyTrustmanager.java

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.X509TrustManager;

public class DummyTrustmanager implements X509TrustManager {
    public void checkClientTrusted(X509Certificate[] cert, String string) throws CertificateException
    {
    }
    public void checkServerTrusted(X509Certificate[] cert, String string) throws CertificateException
    {
    }
    public X509Certificate[] getAcceptedIssuers()
    {
    return new java.security.cert.X509Certificate[0];
    }

}

TestAD.java

import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;

public class TestAD {

    public static void main(String[] args) {
        try {
            //String url = "ldaps://abc.company.com:636";
            String url = "ldaps://xyz.group.com:636";
            String conntype = "simple";
            // String id = "abc@abc.company.com";
            String id = "xyz.group.com";
            //String password = "abcpassword";
            String password = "xyzpassword";
            Hashtable<String, String> environment = new Hashtable<String, String>();
            environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
            environment.put(Context.PROVIDER_URL, url);
            environment.put("java.naming.ldap.factory.socket", "MySSLSocketFactory");
            environment.put(Context.SECURITY_AUTHENTICATION, conntype);
            environment.put(Context.SECURITY_PRINCIPAL, id);
            environment.put(Context.SECURITY_CREDENTIALS, password);
            DirContext ldapContext = new InitialDirContext(environment);
            System.out.println("Bind successful");
        } catch (Exception exception) {
            exception.printStackTrace();
        }

    }
}

У моей компании есть несколько дочерних компаний, и у них есть свои собственные LDAP.Когда я запускаю TestAD против LDAP моей компании, он работает нормально.Но когда я запустил его для LDAP дочерней компании XYZ, я получил следующее исключение:

javax.naming.CommunicationException: simple bind failed: xyz.group.com:636
[Root exception is javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative DNS name matching xyz.group.com found.]
        at com.sun.jndi.ldap.LdapClient.authenticate(LdapClient.java:219)
        at com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2791)
        at com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:319)
        at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:192)
        at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:210)
        at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:153)
        at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:83)
        at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684)
        at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
        at javax.naming.InitialContext.init(InitialContext.java:244)
        at javax.naming.InitialContext.<init>(InitialContext.java:216)
        at javax.naming.directory.InitialDirContext.<init>(InitialDirContext.java:101)
        at TestAD.main(TestAD.java:26)
Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative DNS name matching xyz.group.com found.
        at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
        at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1946)
        at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:316)
        at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:310)
        at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1639)
        at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:223)
        at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1037)
        at sun.security.ssl.Handshaker.process_record(Handshaker.java:965)
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1064)
        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367)
        at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:931)
        at sun.security.ssl.AppInputStream.read(AppInputStream.java:105)
        at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
        at java.io.BufferedInputStream.read1(BufferedInputStream.java:286)
        at java.io.BufferedInputStream.read(BufferedInputStream.java:345)
        at com.sun.jndi.ldap.Connection.run(Connection.java:877)
        at java.lang.Thread.run(Thread.java:748)
Caused by: java.security.cert.CertificateException: No subject alternative DNS name matching xyz.group.com found.
        at sun.security.util.HostnameChecker.matchDNS(HostnameChecker.java:214)
        at sun.security.util.HostnameChecker.match(HostnameChecker.java:96)
        at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:459)
        at sun.security.ssl.AbstractTrustManagerWrapper.checkAdditionalTrust(SSLContextImpl.java:1125)
        at sun.security.ssl.AbstractTrustManagerWrapper.checkServerTrusted(SSLContextImpl.java:1092)
        at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1621)
        ... 12 more

В чем может быть причина сбоя?Я не импортировал сертификаты ABC или XYZ в мой трастовый магазин.Почему это хорошо работает для ABC, но не для XYZ?Может ли быть так, что XYZ ожидает мой сертификат?

1 Ответ

0 голосов
/ 07 июня 2019

Это вызвано алгоритмами идентификации конечной точки , он проверяет, совпадает ли имя хоста в вашей конфигурации с именем хоста в сертификате удаленного сервера LDAPS TLS, и что эти имена хостов действительны.

Учитывая эту ошибку No subject alternative DNS name matching xyz.group.com found, должно быть, что "xyz.group.com" не соответствует вашему сертификату сервера ldap, а "abc.company.com" - соответствует.

Java 8u181 внесла некоторые изменения в core-libs / javax.naming и обновила порядок обработки защищенных соединений LDAP (см. примечание к выпуску ):

Идентификация конечной точки была включена в соединениях LDAPS.

Чтобы повысить надежность соединений LDAPS (безопасный LDAP через TLS), алгоритмы идентификации конечной точки были включены по умолчанию.

Примечаниечто могут быть ситуации, когда некоторые приложения, которые ранее могли успешно подключаться к серверу LDAPS, могут больше не делать этого.Такие приложения могут, если сочтут это целесообразным, отключить идентификацию конечной точки с помощью нового системного свойства: com.sun.jndi.ldap.object.disableEndpointIdentification.

Определить это системное свойство (или установить его в значение true), чтобы отключить алгоритмы идентификации конечной точки.

Отключение алгоритмов идентификации конечной точки - это обходной путь, долгосрочное решение состоит в том, чтобы исправить сертификат сервера так, чтобы он совпадал с именем хоста "xyz.group.com".

...