【问题标题】:Java to Active Directory LDAP java.net.SocketException: Connection or outbound has closedJava 到 Active Directory LDAP java.net.SocketException:连接或出站已关闭
【发布时间】:2021-03-17 13:52:45
【问题描述】:

晚上好,

到现在我已经面临这个错误几天了,尽管在整个网络上寻找解决方案,我还是可以修复这个错误。

import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;

public class LDAPtest {
public static void main(String[] args) {
    
    try {
        
        String keystorePath = "C:/Program Files/Java/jdk-13.0.2/lib/security/cacerts";
        System.setProperty("javax.net.ssl.keyStore", keystorePath);
         
        System.setProperty("javax.net.ssl.keyStorePassword", "changeit");
        
        Hashtable<String, String> ldapEnv = new Hashtable<>(); 
        ldapEnv.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
        ldapEnv.put(Context.PROVIDER_URL, "ldaps://localhost:10636");
        ldapEnv.put(Context.SECURITY_AUTHENTICATION,"simple");
        ldapEnv.put(Context.SECURITY_PRINCIPAL,"uid=admin,ou=system");
        ldapEnv.put(Context.SECURITY_CREDENTIALS,"secret");
        
        DirContext connection = new InitialDirContext(ldapEnv);
        System.out.println("Benvenuto " + connection);
        NamingEnumeration enm = connection.list("");

        while (enm.hasMore()) {
            System.out.println(enm.next());
        }

        enm.close();
        connection.close();
        
        
    }catch(Exception e) {
        e.printStackTrace();
    }
    
}

}

此代码在未测试 SSL 时实际工作,替换了

ldapEnv.put(Context.PROVIDER_URL, "ldaps://localhost:10636");

ldapEnv.put(Context.PROVIDER_URL, "ldap://localhost:10389");

我使用 Apache Directory Studio 对 LDAP 服务器进行了设置,并在此处遵循本教程以使 LDAPS 正常工作: http://directory.apache.org/apacheds/basic-ug/3.3-enabling-ssl.html

所以我制作了证书,甚至安装了它并使用 keytool 将其导入到 cacerts 中。 我为所选端口 (10636) 启用了端口转发,但仍然出现此异常:

javax.naming.CommunicationException: simple bind failed: localhost:10636 [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.getLdapCtxFromUrl(LdapCtxFactory.java:225)
at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:189)
at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:243)
at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:154)
at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:84)
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:130)
at Prova3.main(Prova3.java:31)
Caused by: java.net.SocketException: Connection or outbound has closed
at java.base/sun.security.ssl.SSLSocketImpl$AppOutputStream.write(SSLSocketImpl.java:1246)
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)
... 13 more

提前谢谢你

【问题讨论】:

标签: java ldap


【解决方案1】:

对于 Google 员工:

simple bind failed 错误几乎总是与 SSL 连接有关。

使用nctelnet,检查客户端与远程主机和端口是否可以建立连接。

使用SSLPoke.java(一个检查SSL连接的简单Java类),检查证书是否正确导入和使用,同时检查正确的TLS版本。使用 java -Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2 -Djavax.net.debug=all SSLPoke google.com 443 &gt; log.txt 2&gt;&amp;1 之类的东西。

寻找:

  • Warning: no suitable certificate found - continuing without client authentication = 检查你是否设置了javax.net.ssl.trustStore
  • Fatal (HANDSHAKE_FAILURE): Couldn't kickstart handshaking = TLS 版本可能不匹配
  • 还要检查您的中间 CA 是否已过期

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-26
    • 1970-01-01
    • 2021-10-01
    • 2011-11-24
    • 1970-01-01
    • 1970-01-01
    • 2013-04-29
    • 2019-08-21
    相关资源
    最近更新 更多