Spring Cloud Azure证书启动器4.x不支持mTLS,仅自动配置Key Vault证书客户端;Oracle ADW的mTLS依赖ojdbc8原生Wallet支持,需通过-Doracle.net.tns_admin指定解压后的Wallet路径,并使用tcps://协议与TNS别名连接。
spring-cloud-azure-starter-keyvault-certificates 4.x 不支持 mTLS,别白费力气配 Wallet + ssl_server_cert_dn 参数——它压根不读 Oracle Wallet 文件,也不处理 ojdbc8 要求的 TLS 握手流程。
Oracle ADW 的 mTLS 实际依赖 ojdbc8 + Wallet,不是 Spring Boot 自动配置
adw(autonomous database on wallet)强制要求客户端使用 wallet(.zip 包含 cwallet.sso、tnsnames.ora 等)完成双向 tls 认证。spring boot 的 spring.datasource.url 无法直接加载 wallet;必须靠 ojdbc8 原生支持,并通过 jvm 级参数或 datasource 初始化时显式挂载。
- Wallet 必须解压到本地路径(如
/opt/oracle/wallet),不能放在src/main/resources或 JAR 内 - 需在 JVM 启动参数中添加:
-Doracle.net.tns_admin=/opt/oracle/wallet -
ojdbc8版本必须 ≥ 21.9(推荐 23.7+),旧版对 ADW 的 TLS 1.2/1.3 兼容性差,会报ORA-28759: failure to open file - 连接 URL 必须用
tcps://协议 + ADW 提供的完整 TNS 名(不是传统@host:port:sid格式)
application.yml 中的 url 和 driver-class-name 怎么写才有效
ADW 控制台下载的 Wallet 里 tnsnames.ora 会给出类似 adb1234567890_high 的连接别名。你不能把它当普通字符串拼进 JDBC URL,而要让 ojdbc8 自动解析。
- 正确写法:
spring.datasource.url=jdbc:oracle:thin:@adb1234567890_high - 必须指定 driver:
spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver(不能省略,否则 HikariCP 可能 fallback 到错误驱动) - 禁用自动重试和连接池预检(ADW Wallet 连接耗时高):
spring.datasource.hikari.connection-test-query=SELECT 1 FROM DUAL,并设connection-timeout: 30000 - 不要加
?oracle.net.ssl_server_dn_match=true—— Wallet 已内置证书链校验,加了反而可能触发重复验证失败
Wallet 文件权限和 JVM 加载失败的典型现象
最常见的失败不是代码写错,而是文件不可见或权限不对。JVM 进程用户(比如 systemd 服务里跑的 spring-boot.jar)必须有读取 cwallet.sso 的权限,且 tnsnames.ora 里的路径不能含 Windows 风格反斜杠。
- 报错
java.sql.SQLException: IO Error: The Network Adapter could not establish the connection→ 检查tnsnames.ora是否被ojdbc8正确加载(加 JVM 参数-Doracle.jdbc.Trace=true看日志) - 报错
ORA-28759: failure to open file→cwallet.sso权限不对(应为600),或tns_admin指向目录下缺少sqlnet.ora(Wallet zip 解压后默认不含该文件,需手动创建,内容至少含WALLET_LOCATION = (SOURCE = (METHOD = file) (METHOD_DATA = (DIRECTORY=/opt/oracle/wallet)))) - Linux 上用
ls -l /opt/oracle/wallet/cwallet.sso确认属主和权限;若用 systemd 启动,确保User=设置的用户能访问该路径
为什么 spring-cloud-azure-keyvault-certificates 不管用
这个 starter 只负责从 Azure Key Vault 拉取 PEM 格式证书并注册为 Spring KeyStore Bean,但它不干预 JDBC 层。ADW Wallet 是 Oracle 私有格式(SSO + TNS + SQLNET 配置),ojdbc8 绕过 Java TrustManager 直接调用本地 SSL 库做 handshake,所以 Key Vault 的证书根本进不了这条链路。
- 如果你硬要用 Key Vault 存 Wallet 文件,得自己写逻辑:启动时下载
wallet.zip→ 解压到临时目录 → 设置tns_admin→ 清理临时文件(注意并发和重启问题) - 更稳妥的做法是把 Wallet 放在 ECS 或 VM 的持久化磁盘上,用 Ansible 或 cloud-init 初始化,避免每次部署都重拉
- 别试图用
KeyStore.getInstance("OracleWallet")—— 这个类型不存在,Oracle 没提供标准 JCA 接口
tns_admin 目录是否被 ojdbc8 看见、cwallet.sso 是否可读、以及 JVM 用户是否有权访问那个目录。











