Java LDAP服务器关闭时,与LDAP的连接挂起
我在LDAP服务器中存储了证书,我们使用此证书对将发送到其他系统的请求进行签名 我使用java.security.cert.CertStore类从LDAP检索证书 但是,当我的LDAP服务器关闭时,例如,我已从运行我的应用程序的服务器向LDAP服务器发出防火墙阻止,然后是CertStore.getInstanceLDAP、ldapCertStoreParams;不会超时,永远挂起 我还使用了一个将来的任务,以便在连接过程中超时,以防时间过长。即使将来的任务超时,但尝试连接LDAP的底层线程仍然没有超时,并且无限期挂起 经过一些研究,我发现有一个JNDI属性com.sun.JNDI.ldap.read.timeout可以用于ldap操作,比如在JNDI上下文中设置这个环境变量 env.putcom.sun.jndi.ldap.read.timeout,5000 如果服务器在5秒内没有响应,则导致LDAP服务提供程序中止读取尝试 但是,由于我使用的是SUN的CertStore提供程序,所以它没有任何工具来设置上述属性,以便在LDAP服务器在指定的时间段内没有响应时线程可以超时。我被困在如何使用CertStore对象的这个属性上 当LDAP服务器不可访问时,有人知道如何超时CertStore.getInstanceLDAP,ldapCertStoreParams方法吗 或者是否有其他LDAP提供程序api可以正确处理死连接,用于从LDAP检索证书Java LDAP服务器关闭时,与LDAP的连接挂起,java,ldap,Java,Ldap,我在LDAP服务器中存储了证书,我们使用此证书对将发送到其他系统的请求进行签名 我使用java.security.cert.CertStore类从LDAP检索证书 但是,当我的LDAP服务器关闭时,例如,我已从运行我的应用程序的服务器向LDAP服务器发出防火墙阻止,然后是CertStore.getInstanceLDAP、ldapCertStoreParams;不会超时,永远挂起 我还使用了一个将来的任务,以便在连接过程中超时,以防时间过长。即使将来的任务超时,但尝试连接LDAP的底层线程仍然没
protected CertStore getLdapCertStore(final CertStoreParameters ldapCertStoreParams) throws InterruptedException, ExecutionException, TimeoutException {
final Callable<CertStore> connectionTask = new Callable<CertStore>() {
public CertStore call() throws InvalidAlgorithmParameterException, NoSuchAlgorithmException {
return CertStore.getInstance("LDAP", ldapCertStoreParams);
}
};
final Future<CertStore> futureConnection = getCertStoreConnectionExecutor().submit(connectionTask);
return futureConnection.get(connectionTimeoutInSeconds, TimeUnit.SECONDS);
}
private synchronized ExecutorService getCertStoreConnectionExecutor() {
if (certStoreConnectionExecutor == null) {
// We want one thread per connection-setting, as any connection attempt can hang indefinitely if the port is blocked (e.g.: by a firewall)
// NOTE: Cancelling a Future task does NOT guarantee that the associated thread will be freed and returned to the pool, as threads are not forcefully stopped (only *requested* to stop)!
certStoreConnectionExecutor = Executors.newFixedThreadPool(Math.max(1, getLdapHostAndPortList().size()));
}
return certStoreConnectionExecutor;
}
非常感谢您的帮助
下面是从LDAP检索证书的代码段
protected CertStore getLdapCertStore(final CertStoreParameters ldapCertStoreParams) throws InterruptedException, ExecutionException, TimeoutException {
final Callable<CertStore> connectionTask = new Callable<CertStore>() {
public CertStore call() throws InvalidAlgorithmParameterException, NoSuchAlgorithmException {
return CertStore.getInstance("LDAP", ldapCertStoreParams);
}
};
final Future<CertStore> futureConnection = getCertStoreConnectionExecutor().submit(connectionTask);
return futureConnection.get(connectionTimeoutInSeconds, TimeUnit.SECONDS);
}
private synchronized ExecutorService getCertStoreConnectionExecutor() {
if (certStoreConnectionExecutor == null) {
// We want one thread per connection-setting, as any connection attempt can hang indefinitely if the port is blocked (e.g.: by a firewall)
// NOTE: Cancelling a Future task does NOT guarantee that the associated thread will be freed and returned to the pool, as threads are not forcefully stopped (only *requested* to stop)!
certStoreConnectionExecutor = Executors.newFixedThreadPool(Math.max(1, getLdapHostAndPortList().size()));
}
return certStoreConnectionExecutor;
}
您仍然可以通过创建jndi.properties文件来设置LDAP jndi属性,您可以在其中设置连接和读取超时。尽管如此,我仍然发现LDAP证书存储存在问题,即当它进入此状态时,第一次读取尝试和证书检查将失败,然后当它重新连接时,下一次检查将成功。使用jndi池也没有帮助。更糟糕的是,如果它进入这种状态,enginegetcrls方法是同步的,因此,如果存在过时的连接,则尝试从证书存储读取的任何其他内容都将挂起。我意识到这已经是6年前的事了,但同样的问题最近也让我头疼。当你甚至无法创建连接时,设置读取超时也不会有任何效果。您需要的是连接超时。NB connect不会永远阻塞:只阻塞一分钟左右。是的,这是一个很好的建议,但是,当我使用CertStore类时,我看不到任何方法或方法来设置JNDI属性com.sun.JNDI.ldap.connect.timeout,因为它的sun库在内部管理到ldap服务器的连接,并且不提供任何方法来设置JNDI属性。有什么想法吗?