解决PKIX path building failed的问题-验证可以解决问题

时间:2022-11-04 14:19:49
在一次调试中,出现了这个错误: 
Java代码  解决PKIX path building failed的问题-验证可以解决问题
  1. [ERROR] http-8080-Processor25 2010-01-20 15:29:28,640 org.jasig.cas.client.validation.Cas20ServiceTicketValidator     - 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  
  2. 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  
  3.     at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)  
  4.     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(Unknown Source)  
  5.     at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)  
  6.     at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)  
  7.     at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unknown Source)  
  8.     at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)  
  9.     at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)  
  10.     at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Unknown Source)  
  11.     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)  
  12.     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)  
  13.     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)  
  14.     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)  
  15.     at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)  
  16.     at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)  
  17.     at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)  
  18.     at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown Source)  
  19.     at org.jasig.cas.client.validation.AbstractCasProtocolUrlBasedTicketValidator.retrieveResponseFromServer(AbstractCasProtocolUrlBasedTicketValidator.java:58)  
  20.     at org.jasig.cas.client.validation.AbstractUrlBasedTicketValidator.validate(AbstractUrlBasedTicketValidator.java:167)  
  21.     at org.jasig.cas.client.validation.AbstractTicketValidationFilter.doFilter(AbstractTicketValidationFilter.java:141)  
  22.     at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:137)  
  23.     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)  
  24.     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)  
  25.     at org.jasig.cas.client.authentication.AuthenticationFilter.doFilter(AuthenticationFilter.java:149)  
  26.     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)  
  27.     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)  
  28.     at org.jasig.cas.client.session.SingleSignOutFilter.doFilter(SingleSignOutFilter.java:78)  
  29.     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)  
  30.     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)  
  31.     at com.web114.web.filter.UTF8EncoderFilter.doFilter(UTF8EncoderFilter.java:57)  
  32.     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)  
  33.     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)  
  34.     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)  
  35.     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:174)  
  36.     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)  
  37.     at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)  
  38.     at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)  
  39.     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174)  
  40.     at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:874)  
  41.     at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)  
  42.     at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)  
  43.     at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)  
  44.     at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)  
  45.     at java.lang.Thread.run(Unknown Source)  

这个错误最终定位在这个方法: 
Java代码  解决PKIX path building failed的问题-验证可以解决问题
  1. protected final String retrieveResponseFromServer(final URL validationUrl,  
  2.             final String ticket) {  
  3.         HttpURLConnection connection = null;  
  4.         try {  
  5.             connection = (HttpURLConnection) validationUrl.openConnection();  
  6.             final BufferedReader in = new BufferedReader(new InputStreamReader(  
  7.                     connection.getInputStream()));  
  8.   
  9.             String line;  
  10.             final StringBuffer stringBuffer = new StringBuffer(255);  
  11.   
  12.             synchronized (stringBuffer) {  
  13.                 while ((line = in.readLine()) != null) {  
  14.                     stringBuffer.append(line);  
  15.                     stringBuffer.append("\n");  
  16.                 }  
  17.                 return stringBuffer.toString();  
  18.             }  
  19.   
  20.         } catch (final IOException e) {  
  21.             log.error(e, e);  
  22.             return null;  
  23.         } catch (final Exception e1){  
  24.             log.error(e1, e1);  
  25.             return null;  
  26.         }finally {  
  27.             if (connection != null) {  
  28.                 connection.disconnect();  
  29.             }  
  30.         }  
  31.     }  

后来上网查了很久,说是证书出问题了,服务器不信任我们自己创建的证书,所以在代码中必须要忽略证书信任问题。只要在创建connection之前调用两个方法: 
Java代码  解决PKIX path building failed的问题-验证可以解决问题
  1. trustAllHttpsCertificates();  
  2. HttpsURLConnection.setDefaultHostnameVerifier(hv);  

具体的实现是: 
Java代码  解决PKIX path building failed的问题-验证可以解决问题
  1. HostnameVerifier hv = new HostnameVerifier() {  
  2.         public boolean verify(String urlHostName, SSLSession session) {  
  3.             System.out.println("Warning: URL Host: " + urlHostName + " vs. "  
  4.                                + session.getPeerHost());  
  5.             return true;  
  6.         }  
  7.     };  
  8.       
  9.     private static void trustAllHttpsCertificates() throws Exception {  
  10.         javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];  
  11.         javax.net.ssl.TrustManager tm = new miTM();  
  12.         trustAllCerts[0] = tm;  
  13.         javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext  
  14.                 .getInstance("SSL");  
  15.         sc.init(null, trustAllCerts, null);  
  16.         javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc  
  17.                 .getSocketFactory());  
  18.     }  
  19.   
  20.     static class miTM implements javax.net.ssl.TrustManager,  
  21.             javax.net.ssl.X509TrustManager {  
  22.         public java.security.cert.X509Certificate[] getAcceptedIssuers() {  
  23.             return null;  
  24.         }  
  25.   
  26.         public boolean isServerTrusted(  
  27.                 java.security.cert.X509Certificate[] certs) {  
  28.             return true;  
  29.         }  
  30.   
  31.         public boolean isClientTrusted(  
  32.                 java.security.cert.X509Certificate[] certs) {  
  33.             return true;  
  34.         }  
  35.   
  36.         public void checkServerTrusted(  
  37.                 java.security.cert.X509Certificate[] certs, String authType)  
  38.                 throws java.security.cert.CertificateException {  
  39.             return;  
  40.         }  
  41.   
  42.         public void checkClientTrusted(  
  43.                 java.security.cert.X509Certificate[] certs, String authType)  
  44.                 throws java.security.cert.CertificateException {  
  45.             return;  
  46.         }  
  47.     }  


转:http://mengyang.iteye.com/blog/575671