簡體   English   中英

CAS SunCertPathBuilderException: 無法找到請求目標的有效證書路徑

[英]CAS SunCertPathBuilderException:unable to find valid certification path to requested target

我在我的計算機中配置了 CAS 以在特定域(例如a.com )上工作,該域工作正常。 在那里我有一對 .crt 和 .key 文件以及代碼。 現在需要更改域,所以我所做的是相應地更改源代碼中的域(例如b.com )並導入我收到的 .crt 和 .key 文件。 現在,當我訪問 CAS 登錄頁面時,我可以訪問它。 但是當我提供登錄憑據並單擊登錄按鈕時,它失敗並出現以下異常。

sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
    sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
    java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
    sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382)
    sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
    sun.security.validator.Validator.validate(Validator.java:260)
    sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
    sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)
    sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
    sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1496)
    sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
    sun.security.ssl.Handshaker.processLoop(Handshaker.java:1026)
    sun.security.ssl.Handshaker.process_record(Handshaker.java:961)
    sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
    sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
    sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
    sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
    sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
    sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
    sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1546)
    sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1474)
    sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
    org.jasig.cas.client.util.CommonUtils.getResponseFromServer(CommonUtils.java:429)
    org.jasig.cas.client.validation.AbstractCasProtocolUrlBasedTicketValidator.retrieveResponseFromServer(AbstractCasProtocolUrlBasedTicketValidator.java:41)
    org.jasig.cas.client.validation.AbstractUrlBasedTicketValidator.validate(AbstractUrlBasedTicketValidator.java:193)
    org.springframework.security.cas.authentication.CasAuthenticationProvider.authenticateNow(CasAuthenticationProvider.java:158)
    org.springframework.security.cas.authentication.CasAuthenticationProvider.authenticate(CasAuthenticationProvider.java:143)
    org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174)
    org.springframework.security.cas.web.CasAuthenticationFilter.attemptAuthentication(CasAuthenticationFilter.java:270)
    org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    org.jasig.cas.client.session.SingleSignOutFilter.doFilter(SingleSignOutFilter.java:97)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:121)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:121)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
    org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
    org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
    org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)

有人可以告訴我這里到底發生了什么嗎? 我見過很多類似的問題,但似乎沒有一個能解決我的情況。

原來是我的Tomcat配置有問題。 即使我已將密鑰導入密鑰庫,但 tomcat 並未訪問密鑰庫,導致無法讀取證書。

似乎這適用於那些下載和提取 tomcat 發行版的二進制文件而不是使用諸如apt-get類的包管理器的人。

目前有兩種可能的選擇(可能還有更多)。

  1. 修改 catalina.sh 以添加屬性-Djavax.net.ssl.trustStore以包含所需的信任存儲文件。 基本上,屬性和值被附加到上述腳本中的JAVA_OPTS變量。 例如JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStore=$JAVA_HOME/jre/lib/security/cacerts"然而,這只是一個快速修復。 我認為這不是一個好的解決方案,因為信任存儲正在全球范圍內添加。
  2. 將密鑰庫位置添加到server.xml配置文件中的連接器屬性。 可以在此處找到示例。

我現在意識到這是一個非常簡單的基本問題。 但是為了支持學習者,我想留下問題和答案。 請進一步改進此答案。

來自CAS 文檔

PKIX 路徑構建錯誤是最常見的 SSL 錯誤。 這里的問題是 CAS 客戶端不信任 CAS 服務器提供的證書; 發生這種情況的最常見原因是在 CAS 服務器上使用了自簽名證書。 要解決此錯誤,請將 CAS 服務器證書導入到 CAS 客戶端的系統信任庫中。 如果證書是您自己的PKI頒發的,最好將您的PKI的根證書導入CAS客戶端信任庫。

默認情況下,Java 系統信任庫位於 $JAVA_HOME/jre/lib/security/cacerts。 要導入的證書必須是 DER 編碼的文件。

所以,如果你有密鑰庫文件,比如store.jks ,首先,導出服務器的證書:

keytool -exportcert -keystore store.jks -alias server -file server.crt

[請注意,您的密鑰庫中的別名可能不同]。 接下來,將證書移動到$JAVA_HOME/jre/lib/security/cacerts目錄中,並將其導入客戶端的信任庫(這里,客戶端是您的 JVM):

keytool -import -keystore cacerts -file server.crt -alias server -storepass changeit

【最后一條命令必須以管理員權限調用!】

請注意,如果您在 localhost 上運行它,則證書的 CN 必須是“localhost”。

就是這樣,現在啟動服務器並享受。

暫無
暫無

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

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