9

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 メソッドを別の方法で実行する必要がある場合は、いずれにしても.

ありがとう!

4

4 に答える 4

14

まず、証明書エラーを無視しないでください。代わりにそれらに対処してください。証明書エラーを無視すると、潜在的なMITM攻撃への接続が開かれます。煙探知器のブザーを消すようなものです。時々音がするからです...

確かに、それはテストコード専用であり、本番環境では終了しないと言いたくなりますが、期限が近づくと何が起こるかは誰もが知っています:コードはテスト中にエラーを表示しません->出荷できますそのまま。必要に応じて、代わりにテストCAを設定する必要があります。作成するのはそれほど難しくありません。全体的なプロセスは、開発用のカスタムコードを導入し、本番環境で削除するよりも確かに難しくありません。

目に見えてApacheHttpクライアントを使用しています。

HttpClient client = new HttpClient();
int statusCode = client.executeMethod(method);

それでも、あなたはあなたが作成javax.net.ssl.HttpsURLConnectionしたもので初期化していSSLContextます:

HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());

これは、ApacheHttpクライアントの設定とは完全に独立しています。

代わりに、この回答SSLContextで説明されているように、ApacheHttpクライアントライブラリ用にを設定する必要があります。Apache Http Client 3.xを使用している場合は、それを使用するために独自に設定する必要があります(ここの例を参照)。ただし、を直接サポートしているApacheHttpクライアント4.xにアップグレードする価値があります。SecureProtocolSocketFactorySSLContextSSLContext

Pascalの回答を使用して、証明書を正しくインポートすることもできます。繰り返しになりますが、その質問に対する(Kevinによる)受け入れられた回答に従うと、実際にはエラーを無視しますが、これにより接続がMITM攻撃に対して脆弱になります。

于 2012-08-21T18:28:49.893 に答える
2

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();

それはあなたの問題を解決するはずです

于 2014-09-02T09:41:07.130 に答える