You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LDAPConnectionPool重复获取连接触发强认证异常的解决方法

问题:LDAPConnectionPool 创建新连接时未执行StartTLS导致强认证错误

我原本用以下代码创建LDAP连接:

return LDAPConnection(opts, host, port).apply {
    connectionName = "foo-$userDn-$host-$port"
    processExtendedOperation(StartTLSExtendedRequest(SSLUtil(TrustAllTrustManager()).createSSLContext()))
    bind(userDn, password)
}      

现在想切换为使用LDAPConnectionPool,尝试了如下实现:

val simpleBindRequest = SimpleBindRequest(userDn, password)
val exampleConnection = LDAPConnection(opts, host, port).apply {
    connectionName = "foo-$userDn-$host-$port"
    processExtendedOperation(StartTLSExtendedRequest(SSLUtil(TrustAllTrustManager()).createSSLContext()))
    bind(simpleBindRequest )
}      
val ldapConnectionPool = LDAPConnectionPool(exampleConnection , 1, 10)
ldapConnectionPool.setBindRequest(simpleBindRequest)           

首次调用connectionPool.getConnection()能正常工作,因为返回的是初始传入的exampleConnection;但第二次调用时触发了LDAPException:

LDAPException(resultCode=8 (strong auth required), diagnosticMessage='BindSimple: Transport encryption required.
', ldapSDKVersion=6.0.11, revision=8b21d0a4c6eb8b5c3e60a96fc3e9e13b9c2f650f)
at com.unboundid.ldap.sdk.LDAPConnectionPool.createConnection(LDAPConnectionPool.java:1388)
at com.unboundid.ldap.sdk.LDAPConnectionPool.createConnection(LDAPConnectionPool.java:1269)
at com.unboundid.ldap.sdk.LDAPConnectionPool.getConnection(LDAPConnectionPool.java:1866)

推测原因是新创建的连接未执行processExtendedOperation(StartTLSExtendedRequest(SSLUtil(TrustAllTrustManager()).createSSLContext()))操作,请问有什么解决办法?


解决办法

问题根源在于:连接池在创建新连接时,不会复用初始连接的StartTLS配置,而是直接用基础参数创建连接,导致新连接未加密就尝试绑定,触发强认证错误。

正确的做法是自定义连接工厂,让连接池每次创建新连接时自动执行StartTLS和绑定流程:

  1. 实现自定义LDAPConnectionFactory
    继承DefaultLDAPConnectionFactory,重写createConnection方法,在创建连接后自动执行StartTLS和绑定:
class TLSLDAPConnectionFactory(
    private val opts: LDAPConnectionOptions,
    private val host: String,
    private val port: Int,
    private val userDn: String,
    private val password: String
) : DefaultLDAPConnectionFactory(opts, host, port) {

    override fun createConnection(): LDAPConnection {
        return super.createConnection().apply {
            connectionName = "foo-$userDn-$host-$port"
            // 执行StartTLS加密
            processExtendedOperation(StartTLSExtendedRequest(SSLUtil(TrustAllTrustManager()).createSSLContext()))
            // 绑定用户
            bind(userDn, password)
        }
    }
}
  1. 使用自定义工厂初始化连接池
    直接基于自定义工厂创建连接池,无需传入初始连接:
val connectionFactory = TLSLDAPConnectionFactory(opts, host, port, userDn, password)
val ldapConnectionPool = LDAPConnectionPool(connectionFactory, 1, 10)

这样,连接池每次创建新连接时,都会自动完成StartTLS加密和用户绑定,避免出现强认证要求的错误。

注意:TrustAllTrustManager仅适合测试环境,生产环境必须使用验证合法证书的TrustManager,防止安全风险。


内容的提问来源于stack exchange,提问作者gstackoverflow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 11:12:26