【问题标题】:How to connect a Java client to Azure Cosmos db emulator on Windows 10, can't find cert如何在 Windows 10 上将 Java 客户端连接到 Azure Cosmos db 模拟器,找不到证书
【发布时间】:2018-02-08 18:25:40
【问题描述】:

问题:我的演示代码客户端无法连接到 Windows 10 上的 Azure Cosmos 模拟器。

步骤

  1. 我在 Windows 上安装了 Cosmosdb 模拟器 - 看起来不错

  2. 根据文档,我启动了 Windows 证书 manage.msc。我选择了具有友好名称“DocumentDBEmulatorCertificate”的私有证书作为 base64 编码的 x.509.cer 文件到本地磁盘

  3. 我以管理员身份在 Windows 中启动了 cmd 控制台,并 cd 到本地 JAVA_HOME/lib/security 目录(我使用的是 Java 8.0.131)

  4. 我用这个运行了keytool

    keytool -import -trustcacerts -keystore cacerts -storepass changeit -noprompt -alias azureCosmossDBEmulator -file "D:\exported certificate\cosmossDB-emulator-cert.cer"

  5. 我列出了修改后的密钥库到dump.txt 文件。我可以在转储中看到我的条目

    azurecosmossdbemulator,2017 年 8 月 30 日,trustedCertEntry, 证书指纹(SHA1):5B:F4:14:BE:9F:2B:7F:6A:2B:C0:87:A4:3E:4D:9A:52:45:FA:2F:EA

    这与 x.509 证书中的指纹值匹配。

  6. 我在构建时重新启动了 Intellij,并检查了 Java 8.0.1.3.1 是项目中唯一的 jdk。

  7. 我在调试中启动了 Groovy 测试脚本并逐步执行代码。我可以创建 DocumentClient 了。

  8. 这只是一个粗略的脚本来测试连接代码看起来像这样

     final String key = "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="
    
     DocumentClient client = new DocumentClient("https://localhost:8081", key
                 , new ConnectionPolicy(), ConsistencyLevel.Session)
    
     String dbname = "familyDB"
         String dblink = "/dbs/$dbname"
    
     //create db if not exists
     try {
         client.readDatabase(dblink,null)
         println "found db $dbname"
     } catch (DocumentClientException de) {
         if (de.getStatusCode() == 404) {
             Database db = new Database()
             db.id = dbname
             client.createDatabase(db, null)
             println "created new DB $dbname"
     } else {
         throw de
     }
     }
    

当我到达 client.readDatabase 行时,出现如下异常:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Caught: java.lang.IllegalStateException: Http client execution failed.
java.lang.IllegalStateException: Http client execution failed.
    at com.microsoft.azure.documentdb.internal.GatewayProxy.performGetRequest(GatewayProxy.java:234)
    at com.microsoft.azure.documentdb.internal.GatewayProxy.doRead(GatewayProxy.java:89)
    at com.microsoft.azure.documentdb.internal.GatewayProxy.processMessage(GatewayProxy.java:336)
    at com.microsoft.azure.documentdb.DocumentClient$8.apply(DocumentClient.java:2985)
    at com.microsoft.azure.documentdb.internal.RetryUtility.executeDocumentClientRequest(RetryUtility.java:58)
    at com.microsoft.azure.documentdb.DocumentClient.doRead(DocumentClient.java:2991)
    at com.microsoft.azure.documentdb.DocumentClient.readDatabase(DocumentClient.java:491)
    at com.microsoft.azure.documentdb.DocumentClient$readDatabase.call(Unknown Source)
    at com.softwood.azure.client.cosmossDBClientScript.run(cosmossDBClientScript.groovy:29)
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:394)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:353)
    at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:141)
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:353)
    at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:380)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:55)
    at com.microsoft.azure.documentdb.internal.GatewayProxy.performGetRequest(GatewayProxy.java:231)
    ... 8 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    ... 20 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    ... 20 more

这基本上表明它找不到我的 cacert 条目并拒绝连接。

出了什么问题? (我还没有重新启动 Windows)。证书看起来不错,导入似乎可以通过 keytool 导入到 cacerts,我使用的是单个 jdk ref,但代码无法连接。

我怎样才能解开我没有正确做的事情,现在必须做些什么才能让代码从 Java 连接到在我的 Windows 10 机器上本地运行的 Azure DB 模拟器?

【问题讨论】:

  • 几周前我遇到了类似的问题,但我正在处理一个 LDAP 服务器证书(这是给我的)。我从来没有使用过你处理的 Azure 东西,但听起来你在你的机器上运行某种本地服务器,对吗?如果是,请查看此页面。 github.com/escline/InstallCert/blob/master/InstallCert.java。复制/粘贴 java 代码并运行它,传递“host:port passphrase”。它应该为您生成一个证书(我相信与您运行的 java 类的位置相同)。将文件复制/粘贴到您提到的 jre 位置。

标签: java azure client keystore


【解决方案1】:

根据你的描述,我也写了一段sn-p代码,使用Document DB JavaSDK连接Cosmos DB模拟器,结果遇到了和你一样的问题。

package emulator;

import com.microsoft.azure.documentdb.ConnectionPolicy;
import com.microsoft.azure.documentdb.ConsistencyLevel;
import com.microsoft.azure.documentdb.Database;
import com.microsoft.azure.documentdb.DocumentClient;
import com.microsoft.azure.documentdb.DocumentClientException;

public class TestEmlulator {

    // Replace with your DocumentDB end point and master key.
    private static final String END_POINT = "https://localhost:8081/";
    private static final String MASTER_KEY = "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==";

    public static void main(String[] args) throws DocumentClientException {
        // Connect to the Azure Cosmos DB Emulator running locally
        DocumentClient client = new DocumentClient(END_POINT, MASTER_KEY, ConnectionPolicy.GetDefault(),
                ConsistencyLevel.Session);

        Database database = new Database();
        database.setId("testEmulator");
        database = client.createDatabase(database, null).getResource();

        System.out.println(database.toJson());
    }

}

于是我把cosmosDB的证书导出了,命名为documentdbemulatorcert.cer,存到我的D盘里,由official tutorial提供。看来你也做了同样的事情。

然后,我尝试将 cosmosdb 的证书导入到 JVM 信任证书列表中。你也可以参考我下面的步骤:

Step1:打开CMD命令窗口,进入%JAVA_HOME%/jre/lib/security目录。注意必须用administrator privileges

打开命令窗口

对我来说,目录看起来像 C:\Program Files\Java\jdk1.8.0_131\jre\lib\security

第二步:在打开的命令窗口中,输入以下命令:

keytool -import -alias cacerts -keystore cacerts -file d:\documentdbemulatorcert.cer

输入默认密码:changeit 并在 Trust this certificate? [no]: 上输入 Y 或 y

第三步:如果证书导入成功,你会看到Certificate was added to keystore

整个过程可以参考下面的截图:

终于,我的代码成功了!

你也可以参考下面的SO线程:

1.Unable to find valid certification path to requested target - error even after cert imported

2."PKIX path building failed" and "unable to find valid certification path to requested target"

希望对你有帮助。

【讨论】:

  • 杰伊,谢谢。我查看了起始文件夹,我认为我在错误的位置。我已将其导入“C:\Program Files\Java\jre1.8.0_131\lib\security” - JRE 副本。当我再次阅读您的内容时,您已导入 %java_home%/jre/security。不知道我是怎么搞定的——我觉得太累了。这次我按照您所做的进入正确的 JDK 目录并再次运行它。我们在玩宾果游戏。再次感谢您,否则 id 在 java 配置目录中又把我的头发扯了一天。非常感谢
  • @WILLIAMWOODMAN 很高兴能为您提供帮助,如果您不介意,您可以标记我的答案以供有相同问题的人参考。
  • Jay - 提高了我的问题编号 - 再次感谢
  • 遇到了同样的问题,按照答案中的步骤操作。工作。谢谢。
  • @PraveenKumarKS 干杯!你真好。
猜你喜欢
  • 2022-10-05
  • 2018-06-14
  • 2019-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-07
相关资源
最近更新 更多