尝试使用spring LdapTemplate连接到ldap服务器时,我需要提供truststore和keystore。 我无法使用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.
答案 0 :(得分:0)
我无法使其与AuthenticationStrategy类一起使用。
我们通过以下方法解决了该问题:
实现初始化bean:
public class SystemPropertyInitializer implements InitializingBean {
@Value("${truststore.path}")
private String truststorePath;
@Value("${truststore.pass}")
private String truststorePass;
@Override
public void afterPropertiesSet() throws Exception {
System.setProperty(Utils.SOCKET_FACTORY_TSPATH, truststorePath);
System.setProperty(Utils.SOCKET_FACTORY_TSPASS, truststorePass);
}
设置ldap模板时:
LdapContextSource contextSource = new LdapContextSource();
contextSource.setUrl(getUrl());
contextSource.setBase(getBase());
contextSource.setUserDn(getUser());
contextSource.setPassword(getLdapPass());
Map<String, Object> baseEnvironmentProperties = new HashMap<String, Object>();
baseEnvironmentProperties.put("java.naming.ldap.factory.socket", "com.custom.LdapSocketFactory");
contextSource.setBaseEnvironmentProperties(baseEnvironmentProperties );
contextSource.afterPropertiesSet();
我找不到通过插座工厂的另一种方法...即通过Autowired ...所以 套接字工厂的实现从env变量中加载了信任信息。
SSL异常发生在初始化初始上下文时。从我看到的是 在加载初始上下文之前,authenticationStrategy.setupEnvironment(env,主体,凭据) 叫做。在类AbstractTlsDirContextAuthenticationStrategy中,此方法不执行任何操作。所以工厂呢 没有在那里设置...无论如何,我认为这更多是在ldap服务器上的身份验证,即一旦握手 发生。我的意思是,它确实在类名中说了很多:-)
另请参阅:how to accept self-signed certificates for JNDI/LDAP connections?