You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot连接SQL Server时SSL加密安全连接建立失败问题

问题场景

使用如下application.properties配置本地SQL Server连接:

spring.datasource.url=jdbc:sqlserver://somesqlservername;databaseName=somedbanme
spring.datasource.username=someusername
spring.datasource.password=somepass

通过以下JDBC代码访问数据库:

@RestController
public class UserController {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    
    @GetMapping(value="/User")
    public User getUser(@RequestParam BigInteger id) {
        String sql = "SOME SQL QUERY";
        User user = (User) jdbcTemplate.query(sql, BeanPropertyRowMapper.newInstance(User.class));
        return user;
    }
}

调用服务时抛出错误:

com.microsoft.sqlserver.jdbc.SQLServerException: 驱动程序无法使用安全套接字层(SSL)加密与SQL Server建立安全连接。错误: "PKIX路径构建失败: sun.security.provider.certpath.SunCertPathBuilderException: 无法找到请求目标的有效认证路径"。
ClientConnectionId:8f7627f2-78cf-4479-89fe-9eba6f7be4a5

解决方案

1. 本地开发临时跳过证书验证(不推荐生产环境)

修改数据源URL,添加参数关闭加密或信任服务器证书:

# 方式1:直接关闭SSL加密
spring.datasource.url=jdbc:sqlserver://somesqlservername;databaseName=somedbanme;encrypt=false
# 方式2:启用加密但信任服务器证书(不验证合法性)
spring.datasource.url=jdbc:sqlserver://somesqlservername;databaseName=somedbanme;trustServerCertificate=true

2. 将SQL Server证书导入JVM信任库

操作步骤:

  • 导出SQL Server的SSL证书:可通过SQL Server配置管理器导出,或使用openssl命令从服务器获取证书文件
  • 使用keytool命令将证书导入JVM默认信任库(默认密码为changeit):
keytool -importcert -file /path/to/sqlserver-cert.cer -keystore $JAVA_HOME/jre/lib/security/cacerts -alias sqlserver-local-cert

3. 指定自定义信任库(适合不修改系统默认信任库的场景)

在数据源URL中配置自定义信任库的路径和密码:

spring.datasource.url=jdbc:sqlserver://somesqlservername;databaseName=somedbanme;encrypt=true;trustStorePath=/path/to/your/truststore.jks;trustStorePassword=your-truststore-pwd

或在应用启动时添加JVM参数指定:

-Djavax.net.ssl.trustStore=/path/to/your/truststore.jks -Djavax.net.ssl.trustStorePassword=your-truststore-pwd
代码额外修复

原代码中jdbcTemplate.query()返回的是List<User>,直接强转为User会抛出类型转换异常,应使用queryForObject()并传入查询参数:

@GetMapping(value="/User")
public User getUser(@RequestParam BigInteger id) {
    String sql = "SELECT * FROM users WHERE id = ?";
    return jdbcTemplate.queryForObject(sql, BeanPropertyRowMapper.newInstance(User.class), id);
}

内容的提问来源于stack exchange,提问作者TSSK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 08:45:49