Java - unable to find valid certification path to requested target

這是在實作HTTP GET請求時,遇到了認證上的問題導致的錯誤訊息,由於做請求需要以登入的身分才有權限,同時它又是HTTPS傳輸協定,因此還有SSL相關的設定。在這裡主要是利用Apache HttpClient來完成這個實作!

用到的相關Library如下:
org.apache.commons.httpclient_3.1.0.v201012070820.jar
org.apache.httpcomponents.httpclient_4.5.5.v20180409-1525.jar
org.apache.httpcomponents.httpcore_4.4.9.v20180409-1525.jar
commons-codec-1.15.jar
commons-logging-1.2.jar

#版本一:認證只做帳號、密碼設置
  1. CredentialsProvider credentialsPovider = new BasicCredentialsProvider();
  2. Credentials credentials = new UsernamePasswordCredentials("acc", "pwd");
  3. credentialsPovider.setCredentials(AuthScope.ANY, credentials);
  4. HttpClientBuilder clientbuilder = HttpClients.custom();
  5. CloseableHttpClient httpclient = clientbuilder.build();
  6. HttpHost targetHost = new HttpHost("xxx.xxx.xxx", 443, "https");
  7. AuthCache authCache = new BasicAuthCache();
  8. authCache.put(targetHost, new BasicScheme());
  9. HttpClientContext context = HttpClientContext.create();
  10. context.setCredentialsProvider(credentialsPovider);
  11. context.setAuthCache(authCache);
  12. HttpGet httpget = new HttpGet("https://xxx.xxx.xxx/xxx/xxx");
  13. httpget.addHeader("Content-Type", "application/json");
  14. HttpResponse response = httpclient.execute(httpget, context);
  15. if(response != null){
  16. HttpEntity resEntity = response.getEntity();
  17. if(resEntity != null){
  18. //byte[] data = EntityUtils.toByteArray(resEntity);
  19. System.out.println(EntityUtils.toString(resEntity, "utf-8"));
  20. }
  21. }
  22. httpclient.close();

在做HTTP GET請求的回應時,除了HttpUriRequest外,還需要一個HttpContext,這個部分就會設置setCredentialsProvider的部分,provider又可以包含帳號、密碼的設置!
只是執行之後會發生unable to find valid certification path to requested target exception

#版本二:包含SSL配置
  1. CredentialsProvider credentialsPovider = new BasicCredentialsProvider();
  2. Credentials credentials = new UsernamePasswordCredentials("acc", "pwd");
  3. credentialsPovider.setCredentials(AuthScope.ANY, credentials);
  4. HttpClientBuilder clientbuilder = HttpClients.custom();
  5. SSLContext sslContext=SSLContext.getInstance("SSL");
  6. TrustManager[] tm={new MyX509TrustManager()};
  7. sslContext.init(null, tm, new java.security.SecureRandom());
  8. clientbuilder = clientbuilder.setDefaultCredentialsProvider(credentialsPovider);
  9. clientbuilder.setSSLContext(sslContext);
  10. CloseableHttpClient httpclient = clientbuilder.build();
  11. HttpHost targetHost = new HttpHost("xxx.xxx.xxx", 443, "https");
  12. AuthCache authCache = new BasicAuthCache();
  13. authCache.put(targetHost, new BasicScheme());
  14. HttpClientContext context = HttpClientContext.create();
  15. //context.setCredentialsProvider(credentialsPovider);
  16. context.setAuthCache(authCache);
  17. HttpGet httpget = new HttpGet("https://xxx.xxx.xxx/xxx/xxx");
  18. httpget.addHeader("Content-Type", "application/json");
  19. HttpResponse response = httpclient.execute(httpget, context);
  20. if(response != null){
  21. HttpEntity resEntity = response.getEntity();
  22. if(resEntity != null){
  23. //byte[] data = EntityUtils.toByteArray(resEntity);
  24. System.out.println(EntityUtils.toString(resEntity, "utf-8"));
  25. }
  26. }
  27. httpclient.close();
  1. class MyX509TrustManager implements X509TrustManager{
  2. @Override
  3. public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
  4. // TODO Auto-generated method stub
  5. }
  6. @Override
  7. public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
  8. // TODO Auto-generated method stub
  9. }
  10. @Override
  11. public X509Certificate[] getAcceptedIssuers() {
  12. // TODO Auto-generated method stub
  13. return null;
  14. }
  15. }

改由HttpClientBuilder設置setDefaultCredentialsProvider、setSSLContext

執行結果如下:

留言