【发布时间】:2018-01-23 13:09:26
【问题描述】:
尝试使用 spring LdapTemplate 连接到 ldap 服务器时,我需要提供信任库和密钥库。 我无法使用 keytool 导入证书或由系统属性 javax.net.ssl.trustStore 设置
现在我按照以下方式进行配置:
<bean id="authenticationStrategy" class="org.springframework.ldap.core.support.DefaultTlsDirContextAuthenticationStrategy">
<property name="sslSocketFactory">
<bean class="com.sc.cops.common.auth.ssl.SslSocketFactoryBuilder">
<property name="trustStoreLocation" value="${oud.ldap.keyTrustLocation}" />
<property name="trustStorePassword" value="Password1" />
<!-- <property name="trustStorePassword">
<enc:decrypt key="${common.encryption.key}" cipher-text="${common.ssl.mq.keystore.password}" />
</property> -->
<property name="keyStoreLocation" value="${oud.ldap.keyTrustLocation}" />
<property name="keyStorePassword" value="Password1" />
</bean>
</property>
</bean>
<bean id="ldapContextSource"
class="org.springframework.ldap.core.support.LdapContextSource">
<property name="url" value="ldaps://${ldap.server}:${ldap.port}/" />
<property name="userDn" value="${ldap.oud.userDn}" />
<property name="password" value="${ldap.oud.password}" />
<property name="authenticationStrategy" ref="authenticationStrategy"/>
</bean>
<bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate">
<property name="contextSource" ref="ldapContextSource" />
</bean>
在 com.sc.cops.common.auth.ssl.SslSocketFactoryBuilder 中,我们创建 SSLSocketFactory:
@Override
public SSLSocketFactory getObject() throws IOException, GeneralSecurityException {
TrustManagerFactory trustMgrFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore trustStore = loadKeyStore(getTrustStoreLocation(), getTrustStoreType(), getTrustStorePassword());
trustMgrFactory.init(trustStore);
KeyManagerFactory keyMgrFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
KeyStore keyStore = loadKeyStore(getKeyStoreLocation(), getKeyStoreType(), getKeyStorePassword());
keyMgrFactory.init(keyStore, toCharArray(getKeyStorePassword()));
SSLContext sslContext = SSLContext.getInstance(SSL_VERSION);
sslContext.init(keyMgrFactory.getKeyManagers(), trustMgrFactory.getTrustManagers(), null);
return sslContext.getSocketFactory();
}
我调试代码,我可以看到密钥库和信任库已正确加载。而且我提供的jks文件是正确的。 但是当我尝试进行身份验证时,我得到了错误
Root exception is javax.net.ssl.SSLHandshakeException:
sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to find
valid certification path to requested target.
【问题讨论】:
-
有几种方法可以设置系统属性。你加载一个属性文件吗?
-
我说不能通过系统属性设置,因为在我们的系统中,我们已经使用这种方式设置了另一个 jks 文件。而且我不想将这个新认证添加到现有的 jks 文件中。
-
这里几乎每天都会被问到这个问题。要么您没有加载正确的密钥库,要么它不包含您相信的可信证书。添加 -Djavax.net.debug=all 并检查密钥库加载及其证书。将证书与服务器的证书进行比较(比较序列号)
-
@EugèneAdell 这绝对不是每天都在问的问题,而且要实现 OP 想要的也并不简单。
-
@Lezard 我询问了用户没有发布的调试日志。