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

#版本一:認證只做帳號、密碼設置

CredentialsProvider credentialsPovider = new BasicCredentialsProvider();

Credentials credentials = new UsernamePasswordCredentials("acc", "pwd");
credentialsPovider.setCredentials(AuthScope.ANY, credentials);
          
HttpClientBuilder clientbuilder = HttpClients.custom();

CloseableHttpClient httpclient = clientbuilder.build();

HttpHost targetHost = new HttpHost("xxx.xxx.xxx", 443, "https");
	      
AuthCache authCache = new BasicAuthCache();
authCache.put(targetHost, new BasicScheme());
HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(credentialsPovider);
context.setAuthCache(authCache);

HttpGet httpget = new HttpGet("https://xxx.xxx.xxx/xxx/xxx");
httpget.addHeader("Content-Type", "application/json");

HttpResponse response = httpclient.execute(httpget, context);
if(response != null){
    HttpEntity resEntity = response.getEntity();
    if(resEntity != null){
       //byte[] data = EntityUtils.toByteArray(resEntity);
       System.out.println(EntityUtils.toString(resEntity, "utf-8"));
    }
}
httpclient.close();

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

#版本二:包含SSL配置

CredentialsProvider credentialsPovider = new BasicCredentialsProvider();

Credentials credentials = new UsernamePasswordCredentials("acc", "pwd");
credentialsPovider.setCredentials(AuthScope.ANY, credentials);
          
HttpClientBuilder clientbuilder = HttpClients.custom();

SSLContext sslContext=SSLContext.getInstance("SSL");
TrustManager[] tm={new MyX509TrustManager()};
sslContext.init(null, tm, new java.security.SecureRandom());

clientbuilder = clientbuilder.setDefaultCredentialsProvider(credentialsPovider);
clientbuilder.setSSLContext(sslContext);

CloseableHttpClient httpclient = clientbuilder.build();

HttpHost targetHost = new HttpHost("xxx.xxx.xxx", 443, "https");
	      
AuthCache authCache = new BasicAuthCache();
authCache.put(targetHost, new BasicScheme());
HttpClientContext context = HttpClientContext.create();
//context.setCredentialsProvider(credentialsPovider);
context.setAuthCache(authCache);

HttpGet httpget = new HttpGet("https://xxx.xxx.xxx/xxx/xxx");
httpget.addHeader("Content-Type", "application/json");

HttpResponse response = httpclient.execute(httpget, context);
if(response != null){
    HttpEntity resEntity = response.getEntity();
    if(resEntity != null){
       //byte[] data = EntityUtils.toByteArray(resEntity);
       System.out.println(EntityUtils.toString(resEntity, "utf-8"));
    }
}
httpclient.close();

class MyX509TrustManager implements X509TrustManager{

	@Override
	public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public X509Certificate[] getAcceptedIssuers() {
		// TODO Auto-generated method stub
		return null;
	}
	
}

改由HttpClientBuilder設置setDefaultCredentialsProvider、setSSLContext

執行結果如下:

留言