[英]PKIX path building failed in OAuth Authentication in Java
我正在嘗試在 discogs 中進行身份驗證:
https://www.discogs.com/developers/#page:authentication,header:authentication-oauth-flow
關於第 2 點:向 DISCOGS 請求令牌 URL 發送 GET 請求,我明白了:
oauth_token=tnMYYwCBsvoecGyBsANXyVKQtICTdDnnzRPeGUfa
oauth_token_secret=xwHpnTRYNJIpdkkTJLMsfXECdHgXeQUrDjzmktPw
oauth_callback_confirmed=true
關於第 3 點:將您的用戶重定向到 DISCOGS 授權頁面,
我創建了這段代碼:
private static void redirectUserToAuthorizePage(String consumerKey) throws IOException {
String yourUrl = "https://discogs.com/oauth/authorize?oauth_token=" + consumerKey;
URL url = new URL(yourUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("GET");
int statusCode = conn.getResponseCode();
System.out.println("Status Code: " + statusCode);
conn.disconnect();
}
但我得到了這個錯誤:
但我收到此錯誤:
Exception in thread "main" 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 sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1509)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:914)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1513)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1441)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:338)
提供的錯誤表明您的應用程序無法與遠程服務器discogs.com
建立 SSL 安全通信,因為它無法在配置為信任的服務器中找到該服務器的有效證書。
在后台, HttpURLConnection
將使用Java 安全套接字擴展來建立安全的 SSL 通信。
為了解決這個問題,你有幾個選擇,主要是:
javax.net.ssl.trustStore
和javax.net.ssl.trustStorePassword
系統屬性運行您的應用程序。<java-home>/lib/security/jssecacerts
<java-home>/lib/security/cacerts
無論選擇何種機制,請確保所需的密鑰庫包含信任遠程服務器所需的所有證書,不僅是 SSL 證書本身,還包括證書鏈中的所有證書。
openssl
提供了一個有用的命令,允許您獲取 SSL 連接中使用的所有證書。 在這種情況下,它將提供以下信息,其中包括:
depth=0 O = Acme Co, CN = Kubernetes Ingress Controller Fake Certificate
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 O = Acme Co, CN = Kubernetes Ingress Controller Fake Certificate
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
0 s:/O=Acme Co/CN=Kubernetes Ingress Controller Fake Certificate
i:/O=Acme Co/CN=Kubernetes Ingress Controller Fake Certificate
-----BEGIN CERTIFICATE-----
MIIDcDCCAligAwIBAgIRALyiewLACTbxSO/mUgPt2z8wDQYJKoZIhvcNAQELBQAw
SzEQMA4GA1UEChMHQWNtZSBDbzE3MDUGA1UEAxMuS3ViZXJuZXRlcyBJbmdyZXNz
IENvbnRyb2xsZXIgRmFrZSBDZXJ0aWZpY2F0ZTAeFw0yMTAzMTYyMjQ5MDVaFw0y
MjAzMTYyMjQ5MDVaMEsxEDAOBgNVBAoTB0FjbWUgQ28xNzA1BgNVBAMTLkt1YmVy
bmV0ZXMgSW5ncmVzcyBDb250cm9sbGVyIEZha2UgQ2VydGlmaWNhdGUwggEiMA0G
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDxBj7SvSJpus5+2s4HLhheJhmKEmcV
MTFIVf3xRDfGpVFeYKAc/o8oB3/OXrqr16kuv2g+bE2d59qVri1uTXX/CRHM6G0E
St/gEdUsGiO1e3VueYGkdgr//s7idEMD0tBHp9ITiR0XUFK75YdWCT6H24fetNzp
bOSMImEeSQsRexKqwcCvM6l4rNshJQ1BVD7NOYPBO9BJuEKU0wCd8yDF20Ig6Qwh
D8B6kRIfNIR1jaQbXGwsvowx4ZHtE4ETd5ftPvKFLfjTMRNFOenJMOeA9te3f2vA
f4jm8furOytI7+sQhZqstxbwPV9OI96rilq4P+ZjP3CW9bfubdyE8ccHAgMBAAGj
TzBNMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMB
Af8EAjAAMBgGA1UdEQQRMA+CDWluZ3Jlc3MubG9jYWwwDQYJKoZIhvcNAQELBQAD
ggEBADFd9W49IsGKTm6WBSsSPLuKn1NFlQmfuRljcZyB01seN7N8fvX4OG/fD+/A
g1nogwDbTl3g1AAyiU6iCKerZevolS2akLdbKwxg/olFRjgwdTN5668Dbz4o3MVY
21AJJ9qO14Oxdu5x+3VhMnsuQdcOzdpwVPmNWIOGQMPD+sOZ8d1hqFp6+3gFQpIL
4kEs2RhjZqwySYoQmBnURx8kbyrs3s/sH06v+CzJwVomf7amOaywJ/VuxmkF9JPp
pxxmlHfbSzlWZGRC4K0ij1+91r6EALVUGgonQGY3FsN2+JTTfg8J9FGqvjb7F+BO
PMPqU/pmCW5h8ej8eyNflagzLFE=
-----END CERTIFICATE-----
---
Server certificate
subject=/O=Acme Co/CN=Kubernetes Ingress Controller Fake Certificate
issuer=/O=Acme Co/CN=Kubernetes Ingress Controller Fake Certificate
---
在這種情況下,服務器似乎正在使用自簽名證書來標識自己。 您新配置 Java 以信任該證書。
復制並粘貼命令中輸出的證書文本,包括—–BEGIN CERTIFICATE—–
和—–END CERTIFICATE—–
,並保存到一個新文件,例如discogs.pem
。
為了在 Java 密鑰庫中導入,應首先將其轉換為 DER 格式。 您也可以使用openssl
來做到這一點:
openssl x509 -outform der -in discogs.pem -out discogs.der
然后,將證書導入密鑰庫。 如圖所示,您可以將其導入默認的 JVM kystore 或新的。 讓我們考慮后一種情況並創建一個名為discogs
的新密鑰庫:
keytool -import -keystore discogs -file discogs.der
提供您方便的密碼,我們假設changeme
為例。
現在,使用上述系統屬性運行應用程序:
java -Djavax.net.ssl.trustStore=discogs \
-Djavax.net.ssl.trustStorePassword=changeme \
your.Application
如有必要,為了解決問題,您可以使用具有適當值的javax.net.debug
系統屬性all
或ssl
:
java -Djavax.net.debug=ssl \
-Djavax.net.ssl.trustStore=discogs \
-Djavax.net.ssl.trustStorePassword=password \
your.Application
請考慮查看這個相關的 SO question ,它可能會有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.