springboot配置ldaps连接方式

 更新时间:2024年05月17日 16:17:28   作者:天道有情战天下  
这篇文章主要介绍了springboot配置ldaps连接方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

springboot配置ldaps连接

spring boot配置ldap 连接时,通过ldap://xxxxx:389 连接,一般来说都能成功,但是如果配置ldap ssl 连接,ldaps://xxxx:636 那么很大概率会出现

javax.naming.CommunicationException: simple bind failed: xxxxxtest.com.local:636

这种异常 。

百度,谷歌搜索 大部分解决方案是需要从ldap 服务器上导出证书,然后再通过Java的keytool 工具导入证书,比较繁琐,我也没试过好不好使,反正从服务器上导出证书那一步就很烦了。

说一下如何代码配置ldap跳过ssl

直接上代码。

package com.github.wxiaoqi.security.common.config;
 
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.core.support.LdapContextSource;
 
import java.util.Hashtable;
import java.util.Objects;
 
/**
 * @author margo
 * @date 2021/11/4
 */
@Slf4j
// @ConditionalOnExpression("${ldap.enabled:false}")
public class LdapConfiguration {
 
    private LdapTemplate ldapTemplate;
 
    @Value("${ldap.url}")
    private String ldapUrl;
 
    @Value("${ldap.basedc}")
    private String ldapBaseDc;
 
    @Value("${ldap.username}")
    private String ldapUsername;
 
    @Value("${ldap.passwd}")
    private String ldapPasswd;
 
 
    /**
     * 继承LdapContextSource重写getAnonymousEnv方法来加载,
     * 使连接ldap时用SSL连接(由于修改AD密码时必须使用SSL连接)
     */
    public class SsldapContextSource extends LdapContextSource {
        @Override
        public Hashtable<String, Object> getAnonymousEnv(){
            Hashtable<String, Object> anonymousEnv = super.getAnonymousEnv();
            anonymousEnv.put("java.naming.security.protocol", "ssl");
            anonymousEnv.put("java.naming.ldap.factory.socket", CustomSslSocketFactory.class.getName());
            return anonymousEnv;
        }
    }
 
 
    @Bean
    public LdapContextSource contextSource() {
 
        SsldapContextSource ldapContextSource = new SsldapContextSource();
        ldapContextSource.setBase(ldapBaseDc);
        ldapContextSource.setUrl(ldapUrl);
        ldapContextSource.setUserDn(ldapUsername);
        ldapContextSource.setPassword(ldapPasswd);
        ldapContextSource.setPooled(false);
        ldapContextSource.setReferral("follow");
        ldapContextSource.afterPropertiesSet();
        return ldapContextSource;
    }
 
    @Bean
    public LdapTemplate ldapTemplate(LdapContextSource contextSource) {
        if (Objects.isNull(contextSource)) {
            throw new RuntimeException("ldap contextSource error");
        }
        if (null == ldapTemplate) {
            ldapTemplate = new LdapTemplate(contextSource);
        }
        return ldapTemplate;
    }
 
}
package com.github.wxiaoqi.security.common.config;
 
import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
 
/**
 * 自定义的SSL工厂里面加载自己实现X509TrustManager,信任自签证书
 * @author cb
 */
public class CustomSslSocketFactory extends SSLSocketFactory {
    private SSLSocketFactory socketFactory;
 
    public CustomSslSocketFactory() {
        try {
            SSLContext ctx = SSLContext.getInstance("TLS");
            ctx.init(null, new TrustManager[]{new DummyTrustmanager()}, new SecureRandom());
            socketFactory = ctx.getSocketFactory();
        } catch (Exception ex) {
            ex.printStackTrace(System.err);
        }
    }
 
    public static SocketFactory getDefault() {
        return new CustomSslSocketFactory();
    }
 
    @Override
    public String[] getDefaultCipherSuites() {
        return socketFactory.getDefaultCipherSuites();
    }
 
    @Override
    public String[] getSupportedCipherSuites() {
        return socketFactory.getSupportedCipherSuites();
    }
 
    @Override
    public Socket createSocket(Socket socket, String string, int num, boolean bool) throws IOException {
        return socketFactory.createSocket(socket, string, num, bool);
    }
 
    @Override
    public Socket createSocket(String string, int num) throws IOException, UnknownHostException {
        return socketFactory.createSocket(string, num);
    }
 
    @Override
    public Socket createSocket(String string, int num, InetAddress netAdd, int i) throws IOException, UnknownHostException {
        return socketFactory.createSocket(string, num, netAdd, i);
    }
 
    @Override
    public Socket createSocket(InetAddress netAdd, int num) throws IOException {
        return socketFactory.createSocket(netAdd, num);
    }
 
    @Override
    public Socket createSocket(InetAddress netAdd1, int num, InetAddress netAdd2, int i) throws IOException {
        return socketFactory.createSocket(netAdd1, num, netAdd2, i);
    }
 
 
    /**
     * 证书
     */
    public static class DummyTrustmanager implements X509TrustManager {
        @Override
        public void checkClientTrusted(X509Certificate[] cert, String string) throws CertificateException {
        }
 
        @Override
        public void checkServerTrusted(X509Certificate[] cert, String string) throws CertificateException {
        }
 
        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new java.security.cert.X509Certificate[0];
        }
 
    }
}

主要的配置是 CustomSslSocketFactory  这个类,其他的正常配置。

配置好后启动应用,又出现了另外一个错误,

javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException

在启动main方法中加上一行环境变量配置即可

@EnableEurekaClient
@SpringBootApplication
@EnableConfigurationProperties
@EnableTransactionManagement
@Import(value = {RedissonConfig.class, GatewayReqInterceptor.class, UserInfoInterceptor.class, InterceptorConfig.class, CoreConfig.class, AuthConfig.class, AuthServerRunner.class, LdapConfiguration.class})
@EnableScheduling
public class WxCpApplication {
 
    public static void main(String[] args) {
        System.setProperty("com.sun.jndi.ldap.object.disableEndpointIdentification", "true");  // important resolve javax.net.ssl.SSLHandshakeException
        SpringApplication.run(WxCpApplication.class, args);
    }
 
    
}
System.setProperty("com.sun.jndi.ldap.object.disableEndpointIdentification", "true");  这行

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 如何用idea数据库编写快递e站

    如何用idea数据库编写快递e站

    这篇文章主要介绍了如何用idea数据库编写快递e站,本文通过图文实例相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-01-01
  • Idea报错: A JNI error has occurred的问题

    Idea报错: A JNI error has occurred的问题

    这篇文章主要介绍了Idea报错: A JNI error has occurred的问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • 深入理解final变量的初始化

    深入理解final变量的初始化

    本篇文章是对final变量的初始化进行了详细的分析介绍,需要的朋友参考下
    2013-06-06
  • 详解Spring Boot 定时任务的实现方法

    详解Spring Boot 定时任务的实现方法

    最近在用SpringBoot写一个关于定时项目的时候遇到一个问题,下面小编把如何处理定时任务的解决思路分享给大家 ,需要的朋友参考下
    2017-05-05
  • 解决SpringBoot启动报错:Failed to load property source from location 'classpath:/application.yml'问题

    解决SpringBoot启动报错:Failed to load property source from l

    这篇文章主要介绍了解决SpringBoot启动报错:Failed to load property source from location 'classpath:/application.yml'问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-04-04
  • SpringMVC基于注解的Controller详解

    SpringMVC基于注解的Controller详解

    这篇文章主要介绍了SpringMVC基于注解的Controller详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-01-01
  • 使用JWT作为Spring Security OAuth2的token存储问题

    使用JWT作为Spring Security OAuth2的token存储问题

    这篇文章主要介绍了使用JWT作为Spring Security OAuth2的token存储,大家经常使用的方法有两种一种是使用JWT作为Token传递,一种是使用Redis存储Token,资源服务器本地访问Redis校验Token,需要的朋友可以参考下
    2021-12-12
  • JAVA获取rabbitmq消息总数过程详解

    JAVA获取rabbitmq消息总数过程详解

    这篇文章主要介绍了JAVA获取rabbitmq消息总数过程详解,公司使用的是rabbitMQ,需要做监控预警的job去监控rabbitMQ里面的堆积消息个数,如何使用rabbitMQ获取监控的队列里面的队列消息个数呢,需要的朋友可以参考下
    2019-07-07
  • Java实现图片与二进制的互相转换

    Java实现图片与二进制的互相转换

    这篇文章主要为大家详细介绍了Java实现图片与二进制的互相转换,将图片转二进制再将二进制转成图片,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • JAVA多线程线程安全性基础

    JAVA多线程线程安全性基础

    这篇文章主要介绍了如何测试Java类的线程安全性,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2021-08-08

最新评论