使用Groovy脚本连接Cosmos DB遇SSL握手异常求助
Cosmos DB Groovy脚本连接时SSL握手异常解决求助
异常信息
java.lang.IllegalStateException: com.microsoft.azure.documentdb.DocumentClientException: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target error at line: 52
相关代码
import java.io.FileReader; import java.io.IOException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import com.microsoft.azure.cosmosdb.spark.* import com.microsoft.azure.* import com.microsoft.azure.cosmosdb.* import com.microsoft.azure.documentdb.ConnectionPolicy; import com.microsoft.azure.documentdb.ConsistencyLevel; import com.microsoft.azure.documentdb.DataType; import com.microsoft.azure.documentdb.Database; import com.microsoft.azure.documentdb.DocumentClient; import com.microsoft.azure.documentdb.DocumentClientException; import com.microsoft.azure.documentdb.DocumentCollection; import com.microsoft.azure.documentdb.Index; import com.microsoft.azure.documentdb.IndexingPolicy; import com.microsoft.azure.documentdb.RangeIndex; import com.microsoft.azure.documentdb.RequestOptions; import com.microsoft.azure.documentdb.* import com.eviware.soapui.model.testsuite.TestRunner.* DocumentClient client; // Get the database configuration urlDB = testRunner.testCase.testSuite.project.getPropertyValue( "envCosmoURL" ); keyDB = testRunner.testCase.testSuite.project.getPropertyValue( "envCosmoKey" ); // Making the connection with COSMos DB account client = new DocumentClient("${urlDB}", "${keyDB}", new ConnectionPolicy(), ConsistencyLevel.Session); //Defining the options for retrieving data. feedOptions = new FeedOptions(); feedOptions.setEmitVerboseTracesInQuery(false); // In this section we are accessing to the studydefinition table DB = client.queryDatabases( "SELECT * FROM root r WHERE r.id='StudyDefinition'", null) .getQueryIterable() .toList(); StudyDefDB = DB[0]
解决办法
这个异常核心是Java运行时信任库中缺少Cosmos DB SSL证书的信任条目,以下是几种可行的解决方式:
1. 导入Cosmos DB证书到Java信任库(生产环境推荐)
- 获取证书:打开浏览器访问你的Cosmos DB endpoint(即
envCosmoURL对应地址),点击地址栏锁形图标,导出证书为CRT格式文件。 - 导入证书:找到运行脚本的Java环境(若用SoapUI执行,需定位到SoapUI自带的JRE路径),执行以下命令:
注:默认信任库密码为keytool -importcert -alias cosmosdb -file /path/to/your/cosmos-cert.crt -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeitchangeit,若已修改请替换为实际密码。
2. 临时禁用SSL证书验证(仅测试环境使用)
测试场景下可临时绕过SSL验证,在脚本最开头添加以下代码:
// 禁用SSL证书验证(仅测试环境使用,生产环境禁止) import javax.net.ssl.* import java.security.cert.X509Certificate TrustManager[] trustAllCerts = [new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(X509Certificate[] certs, String authType) {} public void checkServerTrusted(X509Certificate[] certs, String authType) {} }] SSLContext sc = SSLContext.getInstance("SSL") sc.init(null, trustAllCerts, new java.security.SecureRandom()) HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()) HostnameVerifier allHostsValid = { hostname, session -> true } HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid)
3. 检查ConnectionPolicy的网络配置
若环境通过代理访问Cosmos DB,需在ConnectionPolicy中配置代理信息,并确保代理证书已被信任:
ConnectionPolicy policy = new ConnectionPolicy() policy.setProxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("your-proxy-host", 8080))) // 代理需认证时添加以下配置 policy.setProxyUsername("proxy-username") policy.setProxyPassword("proxy-password") // 初始化client时使用配置好的policy client = new DocumentClient("${urlDB}", "${keyDB}", policy, ConsistencyLevel.Session)
内容的提问来源于stack exchange,提问作者pridhvimallikharjun
相关产品推荐
相关产品推荐

