org.apache.karaf.jaas.modules.ldap 无法为 LDAP 设置 SSL 支持

org.apache.karaf.jaas.modules.ldap Unable to setup SSL support for LDAP

我目前 运行 OpenLDAP 2.4.45 的一个实例作为我的 Talend ESB 容器的验证器。我正在使用 TLS 连接到 LDAP,我已经设法让我的 JMS 代理使用 org.apache.activemq.jaas.LDAPLoginModule 连接并成功使用 LDAP,但是,当使用 org.apache.karaf.jaas.modules.ldap.LDAPLoginModule 进行 Web 服务时,我得到以下堆栈跟踪:

2017-08-11 19:04:13,828 | WARN  | qtp272427408-140 | LDAPLoginModule                  | 126 - org.apache.karaf.jaas.modules - 4.0.8 | Can't connect to the LDAP server: Unable to setup SSL support for LDAP: null
javax.naming.NamingException: Unable to setup SSL support for LDAP: null
    at org.apache.karaf.jaas.modules.ldap.LDAPOptions.setupSsl(LDAPOptions.java:178)
    at org.apache.karaf.jaas.modules.ldap.LDAPOptions.getEnv(LDAPOptions.java:158)
    at org.apache.karaf.jaas.modules.ldap.LDAPCache.open(LDAPCache.java:113)
    at org.apache.karaf.jaas.modules.ldap.LDAPCache.doGetUserDnAndNamespace(LDAPCache.java:151)
    at org.apache.karaf.jaas.modules.ldap.LDAPCache.getUserDnAndNamespace(LDAPCache.java:142)
    at org.apache.karaf.jaas.modules.ldap.LDAPLoginModule.doLogin(LDAPLoginModule.java:115)
    at org.apache.karaf.jaas.modules.ldap.LDAPLoginModule.login(LDAPLoginModule.java:54)
    at org.apache.karaf.jaas.boot.ProxyLoginModule.login(ProxyLoginModule.java:83)[org.apache.karaf.jaas.boot-4.0.8.jar:]
    at sun.reflect.GeneratedMethodAccessor104.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)[:1.8.0_131]
    at java.lang.reflect.Method.invoke(Method.java:498)[:1.8.0_131]
    at javax.security.auth.login.LoginContext.invoke(LoginContext.java:755)[:1.8.0_131]
    at javax.security.auth.login.LoginContext.access[=11=]0(LoginContext.java:195)[:1.8.0_131]
    at javax.security.auth.login.LoginContext.run(LoginContext.java:682)[:1.8.0_131]
    at javax.security.auth.login.LoginContext.run(LoginContext.java:680)[:1.8.0_131]
    at java.security.AccessController.doPrivileged(Native Method)[:1.8.0_131]
    at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680)[:1.8.0_131]
    at javax.security.auth.login.LoginContext.login(LoginContext.java:587)[:1.8.0_131]
    at org.apache.cxf.interceptor.security.JAASLoginInterceptor.handleMessage(JAASLoginInterceptor.java:141)[67:org.apache.cxf.cxf-core:3.1.10]
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)[67:org.apache.cxf.cxf-core:3.1.10]
    at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)[67:org.apache.cxf.cxf-core:3.1.10]
    at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:262)[92:org.apache.cxf.cxf-rt-transports-http:3.1.10]
    at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234)[92:org.apache.cxf.cxf-rt-transports-http:3.1.10]
    at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208)[92:org.apache.cxf.cxf-rt-transports-http:3.1.10]
    at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160)[92:org.apache.cxf.cxf-rt-transports-http:3.1.10]
    at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:180)[92:org.apache.cxf.cxf-rt-transports-http:3.1.10]
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:299)[92:org.apache.cxf.cxf-rt-transports-http:3.1.10]
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:218)[92:org.apache.cxf.cxf-rt-transports-http:3.1.10]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)[19:javax.servlet-api:3.1.0]
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:274)[92:org.apache.cxf.cxf-rt-transports-http:3.1.10]
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:812)[200:org.eclipse.jetty.servlet:9.2.19.v20160908]
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:587)[200:org.eclipse.jetty.servlet:9.2.19.v20160908]
    at org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.doHandle(HttpServiceServletHandler.java:71)[223:org.ops4j.pax.web.pax-web-jetty:4.3.0]
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)[199:org.eclipse.jetty.server:9.2.19.v20160908]
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:577)[198:org.eclipse.jetty.security:9.2.19.v20160908]
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223)[199:org.eclipse.jetty.server:9.2.19.v20160908]
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127)[199:org.eclipse.jetty.server:9.2.19.v20160908]
    at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doHandle(HttpServiceContext.java:287)[223:org.ops4j.pax.web.pax-web-jetty:4.3.0]
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)[200:org.eclipse.jetty.servlet:9.2.19.v20160908]
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)[199:org.eclipse.jetty.server:9.2.19.v20160908]
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061)[199:org.eclipse.jetty.server:9.2.19.v20160908]
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)[199:org.eclipse.jetty.server:9.2.19.v20160908]
    at org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:80)[223:org.ops4j.pax.web.pax-web-jetty:4.3.0]
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)[199:org.eclipse.jetty.server:9.2.19.v20160908]
    at org.eclipse.jetty.server.Server.handle(Server.java:499)[199:org.eclipse.jetty.server:9.2.19.v20160908]
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311)[199:org.eclipse.jetty.server:9.2.19.v20160908]
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257)[199:org.eclipse.jetty.server:9.2.19.v20160908]
    at org.eclipse.jetty.io.AbstractConnection.run(AbstractConnection.java:544)[191:org.eclipse.jetty.io:9.2.19.v20160908]
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)[202:org.eclipse.jetty.util:9.2.19.v20160908]
    at org.eclipse.jetty.util.thread.QueuedThreadPool.run(QueuedThreadPool.java:555)[202:org.eclipse.jetty.util:9.2.19.v20160908]
    at java.lang.Thread.run(Thread.java:748)[:1.8.0_131]

我的验证器配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
  xmlns:jaas="http://karaf.apache.org/xmlns/jaas/v1.0.0"
  xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0">

 <jaas:config name="KarafLdapConfiguration" rank="1">
    <jaas:module className="org.apache.karaf.jaas.modules.ldap.LDAPLoginModule" flags="required">
        connection.url=ldaps://ldap:4444
        connection.username=uid=user,ou=users,dc=base
        connection.password=password
        authentication=simple
        user.base.dn=ou=users,dc=base
        user.filter=(uid=%u)
        user.search.subtree=true
        role.base.dn=ou=groups,dc=base
        role.filter=(uniquemember=%fqdn)
        role.name.attribute=uid
        role.search.subtree=true
        ssl=true
        ssl.protocol=TLS
        ssl.algorithm=PKIX
        ssl.keystore=store
        ssl.keyalias=myalias
        ssl.truststore=trust
    </jaas:module>
  </jaas:config>

  <jaas:keystore name="store"
   path="file:///some/path/keystore.jks
   keystorePassword="secret"
   keyPasswords="secret" />

   <jaas:keystore name="trust"
   path="file:///some/path/truststore.jks
   keystorePassword="secret" />
</blueprint>

我怀疑我在这个配置文件中缺少 ssl.provider 选项。尽管源似乎在寻找某种 URI,但文档并不清楚这是什么期望。我花了很多时间进行搜索,但找不到任何关于提供 CA 服务的公司之外的 SSL 提供商的信息。我不知道这可能在寻找什么 URI。我没有进行撤销检查,所以不是那样。想知道这里可能出了什么问题吗?

几天前我终于解决了这个问题,我想我会记录下解决方案,以防将来对任何人有帮助。

问题确实是配置文件中缺少 ssl.provider 字段。需要弄清楚的部分是所需的实际 URI。在我之前的实验中,我缺少 LDAP 的基本 DN。最终,该字段应该看起来像

ssl.provider=ldaps://<somehostname>:<port>/<baseDN>

所以我最终得到的是

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
  xmlns:jaas="http://karaf.apache.org/xmlns/jaas/v1.0.0"
  xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0">

 <jaas:config name="KarafLdapConfiguration" rank="1">
    <jaas:module className="org.apache.karaf.jaas.modules.ldap.LDAPLoginModule" flags="required">
        connection.url=ldaps://ldap:4444
        connection.username=uid=user,ou=users,dc=base
        connection.password=password
        authentication=simple
        user.base.dn=ou=users,dc=base
        user.filter=(uid=%u)
        user.search.subtree=true
        role.base.dn=ou=groups,dc=base
        role.filter=(uniquemember=%fqdn)
        role.name.attribute=uid
        role.search.subtree=true
        ssl=true
        ssl.protocol=TLS
        ssl.algorithm=PKIX
        ssl.provider=ldaps://ldap:4444/dc=baseDN
        ssl.keystore=store
        ssl.keyalias=myalias
        ssl.truststore=trust
    </jaas:module>
  </jaas:config>

  <jaas:keystore name="store"
   path="file:///some/path/keystore.jks
   keystorePassword="secret"
   keyPasswords="secret" />

   <jaas:keystore name="trust"
   path="file:///some/path/truststore.jks
   keystorePassword="secret" />
</blueprint>