SpringLDAP连接LDAPS证书报错解决办法(二)

devtools/2024/10/21 17:32:59/

一、前言

​ 阅读此笔记之前需先了解之前的文章《SpringLDAP连接LDAPS证书报错解决办法》,之前文章中所阐述的不再一一重述。

二、现象描述

​ 按照之前文章设置,在我所在的软件环境中有可能还会再出现SSL握手失败的异常,报错提示java.security.cert.CertificateException: No subject alternative names matching IP address 10.10.10.106 found,且出现后无法自动恢复,需要重启软件模块,重启后可恢复正常。
在这里插入图片描述
以上现象出现的在博主所在的环境中据反馈并没有什么特定的复现步骤,有时候可以,有时候不行,一旦不行之后就一直不行。

三、原因分析

​ 刚开始分析这个报错的时候,我并没有很好的头绪,明明已经按照之前的文章设置了SSL校验跳过,并且连jdk8以后的禁用端点校验都设置了成true,代码回顾如下:

(1)在构建LdapContextSource上下文之前禁用端点校验;

在这里插入图片描述

(2)SSLContext设置自定义校验器,跳过SSL校验。
在这里插入图片描述
在这里插入图片描述

​正常情况下,直接使用LDAPS协议连接ldap/ad进行数据交互能够绕过ssl校验,在设置后的验证过程中也确实没有啥问题,那为何还会偶发性的出现ssl握手失败的问题呢?

只能再分析分析异常信息了:

SSLHandshakeException: No subject alternative names matching IP address <ip> found这个异常表示在尝试建立SSL/TLS连接时,客户端的证书中没有包含与目标服务器IP地址匹配的主机名(Subject Alternative Name, SAN)。

SAN是一个X.509证书扩展,它允许在证书中包含多个主机名,除了主域名(CN)之外,还包括其他域名、IP地址、电子邮件地址等。如果服务器证书中没有包含客户端尝试连接的IP地址,或者包含的IP地址与实际连接的IP地址不匹配,就会抛出这个异常。
这个异常可能是由于以下原因导致的:
(1)服务器证书中的SAN列表不完整,没有包含所有可能的服务器IP地址。
(2)服务器证书的SAN列表包含错误的IP地址,或者客户端尝试连接的IP地址不在其中。
(3)客户端的SSL配置或策略要求证书中的SAN必须与连接的IP地址匹配。
​ 从以上信息来看,之前所设置的绕过代码就是解决这个问题,既然仍存在问题,那么只可能这段代码在特定的情况下绕过机制没生效或有别的代码还有校验。

​ 经过对偶发性报错的堆栈信息进行分析后发现,报错时其使用的ssl校验实现为默认的X509TrustManagerImpl,而非自定义的DummytTrustmanager实现,说明配置或上下文Context可能存在问题
在这里插入图片描述
经堆栈信息追查,LDAP连接的建立最终实现在com.sun.jndi.ldap.Connection这个类上,其连接LDAPS之前的ssl握手代码如下:
在这里插入图片描述
在这里插入图片描述

Java官方在JDK1.8以后启用了LDAPS方式上的端点识别,该特性由系统参数com.sun.jndi.ldap.object.disableEndpointIdentification控制,默认为false启用端点校验,即要求建立LDAPS过程中使用的证书中的域名/IP要与建立连接所使用的域名/IP一致。

我们在建立LDAPS过程时,使用了自定义的SSLLdapContextSource的实现,其实现中已通过System.setProperty方式将com.sun.jndi.ldap.object.disableEndpointIdentification设置为true,禁用了端点识别,因此在常规使用过程中不存在问题,可以进行正常的ldaps交互。偶发性ssl握手失败问题出现时,其依然进行了端点识别校验,因此怀疑该配置项加载存在问题。

于是对com.sun.jndi.ldap.Connection源码进行重新分析,发现其端点识别配置项的变量为静态变量,回顾Java的类加载过程,一个类在虚拟机中只会加载一次,静态变量归属于类本身,在类加载的过程中加载,与类的实例无关如果Connection类首次加载时,使用的是普通LDAP协议(敲重点),则SSLLdapContextSource中的禁用端点识别的代码不会被执行(如下图)
在这里插入图片描述
在这里插入图片描述

com.sun.jndi.ldap.Connection的静态变量IS_HOSTNAME_VERIFICATION_DISABLED会加载为false,即开启端点校验,这个时候我们再切换为协议时(LDAP切换到LDAPS),由于IS_HOSTNAME_VERIFICATION_DISABLED已经被加载成false,仍然会进行ssl证书校验,所以当连接地址非ldap/ad域证书中的域名/IP时,则无法通过校验,报错sslHandshakeException,并且后续的LDAPS都会因为端点校验问题无法正常连接,除非重启软件模块,销毁JVM环境,重启后直接进行LDAPS连接,SSLLdapContextSource禁用端点校验,恢复正常下发,至此问题根源得以复现。

四、解决方案

​ 经过以上分析,我们知道出现SSL握手失败的根本原因在于证书与所使用的域名/IP不匹配导致的,虽迫于现实问题默认采用了SSL绕过的方式进行LDAPS连接,但并不符合规范(可能存在中间人欺骗风险),一般不建议绕过,建议使用正规有效证书及配套域名/IP

​ 当然出了这个问题来找解决方案的同学肯定是用了自签证书/非正规证书,问题还是要解决的,所以大概率还是会采用ssl绕过的方式来处理,所以仍需要按照我之前的博文《SpringLDAP连接LDAPS证书报错解决办法》设置来绕过ssl校验,只不过针对本文的现象需要再次优化一下端点校验的设置方式,我们需要确保使用LDAPS的时候加载的端点校验一定是禁用的,因此要在更早的时机加载禁用端点的系统属性配置。

因此建议以下两种方案根据自身情况二选一

(1)在JVM启动时增加VM参数

-Dcom.sun.jndi.ldap.object.disableEndpointIdentification=true

(2)在模块启动时,如是SpringBoot项目可考虑在启动类的main方法中设置系统属性
在这里插入图片描述


http://www.ppmy.cn/devtools/127623.html

相关文章

java导出带图形的word

先看效果图&#xff1a;方法都是一样的&#xff0c;所以数据只做了前两组 第一步需要准备模版&#xff1a; 新建一个word插入图表&#xff0c;选择想要的图表。 编辑图表&#xff1a;营业额表示数字&#xff0c;季度表示文字。其他的样式编辑可根据自己的需求更改&#xff0c;…

vscode 远程linux服务器 连接git

vscode 远程linux服务器 连接git 1. git 下载2. git 配置1&#xff09;github 设置2&#xff09;与github建立连接linux端&#xff1a;创建密钥github端&#xff1a;创建ssh key 3. 使用1&#xff09;初始化repository2&#xff09;commit 输入本次提交信息&#xff0c;提交到本…

Ubuntu18上,解决AndroidStudio中Device Explorer无法使用,Logcat无法使用的问题

具体原因时&#xff0c;Ubuntu中&#xff0c;默认adb版本使用过低&#xff0c;sudo apt-get adb版本过低 错误原因是因为之前用 sudo apt-get install adb 安装过 adb 通过 update-alternatives 使用 android studio 里面 Tools -> sdk manager -> SDK Tools -> And…

0.36秒即可完成一次高分辨率全球海洋预报!国防科技大学推出「羲和」大模型,性能超越主流数值预报系统,预报时长可达30天

在近日举行的第 20 届 CCF HPC China 2024 大会上&#xff0c;第六届海洋数值预报与高性能计算论坛圆满落幕。在该论坛中&#xff0c;国防科技大学气象海洋学院汪祥课题组助理研究员韩毅以「羲和&#xff1a;数据驱动的全球涡可分辨海洋环境预报大模型」为主题带来了深度分享。…

常用Python数据分析开源库:Numpy、Pandas、Matplotlib、Seaborn、Sklearn介绍

文章目录 1. 常用Python数据分析开源库介绍1.1 Numpy1.2 Pandas1.3 Matplotlib1.4 Seaborn1.5 Sklearn 1. 常用Python数据分析开源库介绍 1.1 Numpy Numpy(Numerical Python)是Python数据分析必不可少的第三方库&#xff0c;Numpy的出现一定程度上解决了Python运算性能不佳的…

Linux LCD 驱动实验

LCD 是很常用的一个外设&#xff0c;在裸机篇中我们讲解了如何编写 LCD 裸机驱动&#xff0c;在 Linux 下LCD 的使用更加广泛&#xff0c;再搭配 QT 这样的 GUI 库下可以制作出非常精美的 UI 界面。本章我们就来学习一下如何在 Linux 下驱动 LCD 屏幕。 Framebuffer 设备 先来…

Gorm操作数据库,有和没有WithContext的区别

问题的提出 本人是Go服务器的新中新中新手&#xff0c;在使用数据库操作时&#xff0c;看到代码中有些查询语句会先调用WithContext再查询&#xff0c;如&#xff1a; //有WithContext dao.WinUser.WithContext(l.ctx).Where(...)//没有WithContext dao.WinUser.Where(...) …

第六章 元素应用CSS

6.1 使用CSS设置字体样式 6.1.1.字体类型 CSS 提供 font-family属性来控制文本的字体类型。 格式如下&#xff1a; font-family:字体名称; 参数&#xff1a;字体名称按优先顺序排列&#xff0c;以逗号隔开。如果字体名称包含空格&#xff0c;则应用引号括起。 说明&#xff…