簡體   English   中英

如何將 Java 客戶端連接到 Windows 10 上的 Azure Cosmos db 模擬器,找不到證書

[英]How to connect a Java client to Azure Cosmos db emulator on Windows 10, can't find cert

問題:我的演示代碼客戶端無法連接到 Windows 10 上的 Azure Cosmos 模擬器。

步驟

  1. 我在 Windows 上安裝了 Cosmosdb 模擬器 - 看起來不錯

  2. 根據文檔,我啟動了 Windows cert 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 certificates\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 模擬器?

根據你的描述,我也寫了一段代碼,使用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盤中,如官方教程提供的。 看來你做了同樣的事情。

在此處輸入圖片說明

然后,我嘗試將 cosmosdb 的證書導入到 JVM 信任證書列表中。 你也可以參考我下面做的步驟:

Step1:打開CMD命令窗口,進入%JAVA_HOME%/jre/lib/security目錄。 注意需要用administrator privileges打開命令窗口

對我來說,目錄看起來像C:\\Program Files\\Java\\jdk1.8.0_131\\jre\\lib\\security

Step2:在打開的命令窗口中,輸入以下命令:

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

輸入默認密碼: changeit並針對Trust this certificate? [no]:輸入Y 或 y Trust this certificate? [no]: Trust this certificate? [no]:

Step 3:如果證書導入成功,可以看到Certificate was added to keystore

整個過程可以參考下面的截圖:

在此處輸入圖片說明

最后,我的代碼有效!

在此處輸入圖片說明

你也可以參考下面的SO線程:

1. 無法找到請求目標的有效證書路徑 - 即使在導入證書后也會出錯

2. “PKIX路徑構建失敗”和“無法找到到請求目標的有效認證路徑”

希望對你有幫助。

我在 Mac 上,但可以調整下面的腳本以在 Windows 10 上工作。

不要使用keytool -cacerts選項。 你會管自己。 如果你這樣做了,而且你不小心,你可能會不小心將證書導入到系統上錯誤的 JDK。

我在 docker-compose.yml 中定義了docker-compose.yml模擬器。 然后我這樣開始:

#!/usr/bin/env bash
## starts Mongo locally and imports certificates into your JDK

export EXTERNAL_IP=$(ifconfig | grep "inet " | grep -Fv 127.0.0.1 | awk '{print $2}' | head -n 1)
exec docker-compose up -d

sleep 20s

curl -k https://localhost:8081/_explorer/emulator.pem > emulatorcert.crt

if [ ! -f $JAVA_HOME/lib/security/jssecacerts ]
then
    sudo cp $JAVA_HOME/lib/security/cacerts $JAVA_HOME/lib/security/jssecacerts
else
    echo "jssecacerts file exists"
fi

sudo keytool -delete -alias "cosmosdb" -keystore $JAVA_HOME/lib/security/jssecacerts -storepass changeit -noprompt
sudo keytool -importcert -file ./emulatorcert.crt -keystore $JAVA_HOME/lib/security/jssecacerts -alias "cosmosdb" --storepass changeit -noprompt
sudo keytool -list -keystore $JAVA_HOME/lib/security/jssecacerts -alias "cosmosdb" --storepass changeit

這是我的docker-compose.yml

version: '2.4'

services:

  cosmosdb:
    container_name: cosmosdb
    hostname: cosmosdb
    image: mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator
    platform: linux
    tty: true
    restart: always
    mem_limit: 3GB
    ports:
        - '8081:8081'
        - '8900:8900'
        - '8901:8901'
        - '8902:8902'
        - '10250:10250'
        - '10251:10251'
        - '10252:10252'
        - '10253:10253'
        - '10254:10254'
        - '10255:10255'
        - '10256:10256'
        - '10350:10350'
    environment:
      AZURE_COSMOS_EMULATOR_PARTITION_COUNT: 2
      AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE: true
      AZURE_COSMOS_EMULATOR_IP_ADDRESS_OVERRIDE: ${EXTERNAL_IP}
    volumes:
      -  vol_cosmos:/Volumes/docked/cosmosdb  # volume must allow write permissions

volumes:
  vol_cosmos:

最后,將證書導入您的鑰匙串訪問應用程序(又名系統證書商店),然后將證書標記為受信任。

然后,最后您可以通過訪問 https://localhost:8081/_explorer/index.html 來管理您的 CosmosDB。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM