Java 升级 8 到 11 导致 LDAPS 连接出现问题(连接或出站已关闭)

标签 java ldap

java升级后出现的这个问题:

  • 具有 DNS 别名的 LDAP 无法与 java 11.0.2 连接
    使用 java 8

  • 下面的 DNS 别名保持不变,这里没有变化,唯一的变化是 java 升级 8 到 11:

    $ nslookup ad1.XXXXX.zz
    Server:         10.222.249.209
    Address:        10.222.249.209#53
    
    Name:   ad1.XXXXX.zz
    Address: 10.222.249.205
    Name:   ad1.XXXXX.zz
    Address: 10.222.249.204
    Name:   ad1.XXXXX.zz
    Address: 10.222.249.210
    
  • LDAP 直接 IP 与 java 11.0.2 没有问题:

  • $ nslookup qdegsf.XXXXX.zz
    Server:         10.222.249.209
    Address:        10.222.249.209#53
    
    Name:   qdegsf.XXXXX.zz
    Address: 10.222.249.210
    

    工艺参数:

    /opt/3rdparty/jdk_installed/jdk-11.0.2/bin/java -Dsserver -Djdk.serialFilter=* -Dfile.encoding=UTF8 -Djavax.net.ssl.trustStore=/opt/3rdparty/tomcat/conf/svrtrust - Djavax.net.ssl.trustStorePassword=XXXX -Djavax.net.ssl.keyStore=/opt/3rdparty/tomcat/conf/svrkeystore.jks

    以下是建立 ldap 连接时的问题跟踪
    java.lang.RuntimeException: connection to ldap server failed;url;ldaps://ad1.XXXXX.zz:636;authDN;sa_XXX@XXXXX.zz
    javax.naming.CommunicationException: simple bind failed: ad1.XXXXX.zz:636 [Root exception is java.net.SocketException: Connection or outbound has closed]
    java.net.SocketException: Connection or outbound has closed
    Trace for the thrown exceptions:
    java.lang.RuntimeException: connection to ldap server failed;url;ldaps://ad1.XXXXX.zz:636;authDN;sa_XXX@XXXXX.zz
        at auth.ldap.LdapConnection.testConnection(LdapConnection.java:46)
    
    
    Caused by: javax.naming.CommunicationException: simple bind failed: ad1.XXXXX.zz:636 [Root exception is java.net.SocketException: Connection or outbound has closed]
        at java.naming/com.sun.jndi.ldap.LdapClient.authenticate(LdapClient.java:219)
        at java.naming/com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2795)
        at java.naming/com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:320)
        at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:192)
        at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:210)
        at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:153)
        at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:83)
        at java.naming/javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:730)
        at java.naming/javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:305)
        at java.naming/javax.naming.InitialContext.init(InitialContext.java:236)
        at java.naming/javax.naming.InitialContext.<init>(InitialContext.java:208)
        at java.naming/javax.naming.directory.InitialDirContext.<init>(InitialDirContext.java:101)
        at auth.ldap.LdapConnection.testConnection(LdapConnection.java:41)
        ... 3 more
    Caused by: java.net.SocketException: Connection or outbound has closed
        at java.base/sun.security.ssl.SSLSocketImpl$AppOutputStream.write(SSLSocketImpl.java:976)
        at java.base/java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:81)
        at java.base/java.io.BufferedOutputStream.flush(BufferedOutputStream.java:142)
        at java.naming/com.sun.jndi.ldap.Connection.writeRequest(Connection.java:398)
        at java.naming/com.sun.jndi.ldap.Connection.writeRequest(Connection.java:371)
        at java.naming/com.sun.jndi.ldap.LdapClient.ldapBind(LdapClient.java:359)
        at java.naming/com.sun.jndi.ldap.LdapClient.authenticate(LdapClient.java:214)
        ... 15 more
    javax.naming.CommunicationException: simple bind failed: ad1.XXXXX.zz:636 [Root exception is java.net.SocketException: Connection or outbound has closed]
        at java.naming/com.sun.jndi.ldap.LdapClient.authenticate(LdapClient.java:219)
        at java.naming/com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2795)
        at java.naming/com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:320)
        at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:192)
        at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:210)
        at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:153)
        at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:83)
        at java.naming/javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:730)
        at java.naming/javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:305)
        at java.naming/javax.naming.InitialContext.init(InitialContext.java:236)
        at java.naming/javax.naming.InitialContext.<init>(InitialContext.java:208)
        at java.naming/javax.naming.directory.InitialDirContext.<init>(InitialDirContext.java:101)
        at auth.ldap.LdapConnection.testConnection(LdapConnection.java:41)
    Caused by: java.net.SocketException: Connection or outbound has closed
        at java.base/sun.security.ssl.SSLSocketImpl$AppOutputStream.write(SSLSocketImpl.java:976)
        at java.base/java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:81)
        at java.base/java.io.BufferedOutputStream.flush(BufferedOutputStream.java:142)
        at java.naming/com.sun.jndi.ldap.Connection.writeRequest(Connection.java:398)
        at java.naming/com.sun.jndi.ldap.Connection.writeRequest(Connection.java:371)
        at java.naming/com.sun.jndi.ldap.LdapClient.ldapBind(LdapClient.java:359)
        at java.naming/com.sun.jndi.ldap.LdapClient.authenticate(LdapClient.java:214)
        ... 15 more
    java.net.SocketException: Connection or outbound has closed
        at java.base/sun.security.ssl.SSLSocketImpl$AppOutputStream.write(SSLSocketImpl.java:976)
        at java.base/java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:81)
        at java.base/java.io.BufferedOutputStream.flush(BufferedOutputStream.java:142)
        at java.naming/com.sun.jndi.ldap.Connection.writeRequest(Connection.java:398)
        at java.naming/com.sun.jndi.ldap.Connection.writeRequest(Connection.java:371)
        at java.naming/com.sun.jndi.ldap.LdapClient.ldapBind(LdapClient.java:359)
        at java.naming/com.sun.jndi.ldap.LdapClient.authenticate(LdapClient.java:214)
        at java.naming/com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2795)
        at java.naming/com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:320)
        at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:192)
        at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:210)
        at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:153)
        at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:83)
        at java.naming/javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:730)
        at java.naming/javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:305)
        at java.naming/javax.naming.InitialContext.init(InitialContext.java:236)
        at java.naming/javax.naming.InitialContext.<init>(InitialContext.java:208)
        at java.naming/javax.naming.directory.InitialDirContext.<init>(InitialDirContext.java:101)
        at nims.auth.ldap.LdapConnection.testConnection(LdapConnection.java:41)
        at auth.LdapAuthenticationService.doTestConnection(LdapAuthenticationService.java:50)
    

    > 更新出现以下错误:

    $ openssl s_client -connect ad1.XXXXX-ru.zz:636

    已连接(00000003)
    深度=0
    验证错误:num=20:无法获得本地颁发者证书
    验证返回:1
    深度=0
    验证错误:num=27:证书不受信任
    验证返回:1
    深度=0
    验证错误:num=21:无法验证第一个证书
    验证返回:1

    证书链
    0 秒:
    i:/DC=zz/DC=XXXXX-ru/CN=XXXXX-ru-ROOT-CA

    服务器证书
    -----开始证书-----
    MIIFfjCCBGagAwIBAgITLwAAAKgllUHEZUjzRwAAAAAAqDANBgkqhkiG9w0BA.......

    APPpwNrloBJjZo2bJ7pqe4gXN
    -----结束证书-----

    主题=
    发行人=/DC=zz/DC=XXXXX-ru/CN=XXXXX-ru-ROOT-CA

    未发送客户端证书 CA 名称
    服务器临时 key :ECDH,prime256v1,256 位

    SSL 握手已读取 1980 字节并写入 441 字节

    新的,TLSv1/SSLv3,密码是 ECDHE-RSA-AES256-SHA384
    服务器公钥为 2048 位
    支持安全重新协商
    压缩:无
    扩展:无
    SSL- session :
    协议(protocol):TLSv1.2
    密码:ECDHE-RSA-AES256-SHA384
    session ID:C51900006745E495E1C8CA132C0EDF901C3638DE9E5EEA506551E298E2374372
    session ID-ctx:
    万能 key :A8B4C4E2B01FE11822CE047D3B7D692EE1C001DA551DFE63FBC314737177BE7A285F79D6FF36B67D3E1AFF72C1402D2D
    键-Arg:无
    Krb5 主体:无
    PSK 身份:无
    PSK 身份提示:无
    开始时间:1574232095
    超时:300(秒)
    验证返回码:21(无法验证第一个证书)

    请提供建议。
    谢谢

    最佳答案

    根据您使用的 Java 8 版本,此错误可能有多种原因:

  • Java 11(和 Java 8 的最新版本)现在强制执行主机名
    建立 SSL 连接时的验证。所以服务器的
    证书与您尝试连接的主机名非常匹配。
  • Java 11 还具有更新的密码套件和 TLS 版本,并弃用了一些旧密码套件。您可能想要启用 SSL
    调试以查看 SSL 层上交换的内容。
  • 最后,TLS(1.3) 存在几个问题,Java 11 早期版本中的密码套件,因此您可能需要切换到
    最新更新 (11.0.5)
  • 关于Java 升级 8 到 11 导致 LDAPS 连接出现问题(连接或出站已关闭),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58911874/

    相关文章:

    amazon-web-services - 如何使用ldapsearch连接到AWS简单AD?

    active-directory - 查询列出某个组的所有用户

    java - 为什么我不能在内部类中声明和初始化静态变量?

    java - 是否有带有自定义比较器的 retainAll() 的实现?

    active-directory - 为什么我从我的 LDAP 属性中得到 'System.__ComObject'?

    java - 将 X509 值传递到 LDAP 服务器

    java - 如何解决 "Graphics Device initialization failed for : d3d, sw"问题

    java - 尝试创建一个二分搜索平方根计算器,每次都收到 0 结果

    java - 尝试进行其他 Activity 时,我简单的 “counter app”崩溃了……为什么?

    php - ldap_mod_replace 返回 true 但密码未更改