Apache Httpクライアント。あなたは関連するコードを見ることができます ここ :
String url = "https://path/to/url/service";
HttpClient client = new HttpClient();
PostMethod method = new PostMethod(url);
// Test whether to ignore cert errors
if (ignoreCertErrors){
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager(){
public X509Certificate[] getAcceptedIssuers(){ return null; }
public void checkClientTrusted(X509Certificate[] certs, String authType) {}
public void checkServerTrusted(X509Certificate[] certs, String authType) {}
}
};
try {
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
} catch (Exception e){
e.printStackTrace();
}
}
try {
// Execute the method (Post) and set the results to the responseBodyAsString()
int statusCode = client.executeMethod(method);
resultsBody = method.getResponseBodyAsString();
} catch (HttpException e){
e.printStackTrace();
} catch (IOException e){
e.printStackTrace();
} finally {
method.releaseConnection();
}
これは、SSL証明書エラーを無視するために誰もが使用する方法と言われています(ステージング用に設定するだけで、本番環境では使用されません)。しかし、私はまだ次の例外/スタックトレースを取得しています:
javax.net.ssl.SSLHandshakeException: Sun.security.validator.ValidatorException: PKIX path building unable to find valid certification path to requested target
どんなヒントも素晴らしいでしょう。 TrustManagerを間違って実行している場合、またはHTTP Postメソッドを別の方法で実行する必要がある場合。
ありがとう!
まず、証明書エラーを無視無視しません。代わりに対処してください。証明書エラーを無視すると、潜在的なMITM攻撃への接続が開かれます。それは時々それが音を立てるのであなたの煙警報器のブザーをオフにするようなものです...
確かに、それはテストコード専用であると言いたくてたまらなく、最終的には本番にはなりませんが、締め切りが近づくと何が起こるかは誰でも知っています。テスト中にコードにエラーが表示されない->出荷可能そのまま。必要に応じて、代わりにテストCAをセットアップする必要があります。作成するのはそれほど難しくなく、プロセス全体は、開発用のカスタムコードを導入して本番環境で削除するよりも難しくありません。
あなたは明らかにApache Http Clientを使用しています:
HttpClient client = new HttpClient();
int statusCode = client.executeMethod(method);
ただし、作成したSSLContext
を使用してjavax.net.ssl.HttpsURLConnection
を初期化しています。
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
これは、Apache Http Clientの設定から完全に独立しています。
代わりに、Apache Http Clientライブラリ用にSSLContext
を設定する必要があります this answer で説明されています。 Apache Http Client 3.xを使用している場合は、独自のSecureProtocolSocketFactory
を設定して、そのSSLContext
を使用する必要があります(例 こちら を参照)。ただし、SSLContext
を直接サポートしているApache Http Client 4.xにアップグレードする価値があります。
Pascalの回答 を使用して、証明書を正しくインポートすることもできます。繰り返しになりますが、その質問に対する(Kevinによる)承認済みの回答に従うと、実際にはエラーは無視されますが、これにより接続がMITM攻撃に対して脆弱になります。
HttpClient 4.3、それは簡単です、
HttpClientBuilder cb = HttpClientBuilder.create();
SSLContextBuilder sslcb = new SSLContextBuilder();
sslcb.loadTrustMaterial(KeyStore.getInstance(KeyStore.getDefaultType()), new TrustSelfSignedStrategy());
cb.setSslcontext(sslcb.build());
CloseableHttpClient httpclient = cb.build();
それはあなたの問題を解決するはずです
これが私にとってうまくいったすべてを本当に無視したい場合:
SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(new TrustStrategy() {
@Override
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
}).build();
HostnameVerifier hnv = new NoopHostnameVerifier();
SSLConnectionSocketFactory sslcf = new SSLConnectionSocketFactory(sslContext, hnv);
CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslcf).build()
証明書を無視すると、同じコードが実稼働環境に移動し、大混乱を引き起こす可能性があるため、それ自体に害があります。
以下の例はJersey Rest Clientの場合です
private static final com.Sun.jersey.api.client.Client client = com.Sun.jersey.api.client.Client.create(configureClient());
final com.Sun.jersey.api.client.WebResource webResource = client.resource("url");
try {
com.Sun.jersey.api.client.ClientResponse response = webResource.type(MediaType.APPLICATION_JSON_TYPE)
.accept(MediaType.APPLICATION_JSON_TYPE)
.get(com.Sun.jersey.api.client.ClientResponse.class);
}catch(com.Sun.jersey.api.client.ClientHandlerException che){
che.printStackTrace();
}
証明書を無視すると、次のようになります。
public static ClientConfig configureClient() {
TrustManager[ ] certs = new TrustManager[ ] {
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
}
};
SSLContext ctx = null;
try {
ctx = SSLContext.getInstance("SSL");
ctx.init(null, certs, new SecureRandom());
} catch (Java.security.GeneralSecurityException ex) {
}
HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
ClientConfig config = new DefaultClientConfig();
try {
config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, new HTTPSProperties(
new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
},
ctx
));
} catch(Exception e) {
}
return config;
}