15

Unirest (Java バージョン) を使用して GET および POST 要求を作成していますが、プログラムが企業ネットワークの背後にあり、ネットワーク管理者がファイアウォール マッピングをセットアップしているため、SSL 暗号化サイトにアクセスすると問題が発生します。たとえば、foobar.comにマップされ56.1.89.12:4444ます。しかし、そのアドレスにリクエストを送信すると、次の ssl 証明書エラーが表示されます。

com.mashape.unirest.http.exceptions.UnirestException: javax.net.ssl.SSLException: hostname in certificate didn't match: <56.1.89.12> != <www.foobar.com>
    at com.mashape.unirest.http.HttpClientHelper.request(HttpClientHelper.java:131)
    at com.mashape.unirest.request.BaseRequest.asString(BaseRequest.java:52)

Unirestカスタムを使用するための事前設定があるようですhttpclient。だから私は使用します

Unirest.setHttpClient(MyHttpClient.makeClient());
HttpResponse<String> res = null;
try {
    res = Unirest.get(urlstr).asString();
} catch (UnirestException e) {
    e.printStackTrace();
}
String jsonstr = res.getBody();

makeClient方法MyHttpClientは次のとおりです。

public static HttpClient makeClient(){
 SSLContextBuilder builder = new SSLContextBuilder();
 CloseableHttpClient httpclient = null;
    try {
        // builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
        builder.loadTrustMaterial(null, new TrustStrategy(){
            public boolean isTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
                return true;
            }
        });
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                builder.build());
        httpclient = HttpClients.custom().setSSLSocketFactory(
                sslsf).build();
        System.out.println("custom httpclient called");
        System.out.println(httpclient);

    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (KeyStoreException e) {
        e.printStackTrace();
    } catch (KeyManagementException e) {
        e.printStackTrace();
    }

return httpclient;
}

主なアイデアは、Apache HttpClient 4.3 での SSL 証明書の無視から取られています。

しかし、それでもうまくいきませんでした。何か提案はありますか?

4

5 に答える 5

13
 SSLContext sslcontext = SSLContexts.custom()
            .loadTrustMaterial(null, new TrustSelfSignedStrategy())
            .build();

    SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext,SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
    CloseableHttpClient httpclient = HttpClients.custom()
            .setSSLSocketFactory(sslsf)
            .build();
    Unirest.setHttpClient(httpclient);

これは私のために働いた

于 2016-02-18T15:08:47.277 に答える
2

証明書エラーの解決策は、いくつかの場所からの組み合わせです

そして比較的完全な例。

import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;

import javax.net.ssl.SSLContext;
import javax.security.cert.CertificateException;
import javax.security.cert.X509Certificate;

import org.apache.http.client.HttpClient;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;

import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.JsonNode;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;

public class XXX {

    private static HttpClient unsafeHttpClient;

    static {
        try {
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustSelfSignedStrategy() {
                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    return true;
                }
            }).build();

            unsafeHttpClient = HttpClients.custom().setSSLContext(sslContext)
                    .setSSLHostnameVerifier(new NoopHostnameVerifier()).build();

        } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
            e.printStackTrace();
        }
    }

    public static HttpClient getClient() {
        return unsafeHttpClient;
    }

    public static void main(String[] args) {

        try {
            HttpClient creepyClient = RestUnirestClient.getClient();
            Unirest.setHttpClient(creepyClient);

            HttpResponse<JsonNode> response = Unirest.get("https://httpbin.org/get?show_env=1").asJson();
            System.out.println(response.getBody().toString());

        } catch (UnirestException e) {
            e.printStackTrace();
        }
    }
}
于 2016-05-06T04:34:36.520 に答える
0

残念ながら、Unirest には SSL を構成するためのネイティブな方法がないため、カスタム HttpClient インスタンスを提供することが唯一のオプションのように見えます。非推奨のクラス (「DefaultHttpClient」など) を使用せず、自己署名証明書で動作するソリューションを次に示します。

protected void prepareHttpsClient() {
    HttpClientBuilder clientBuilder = HttpClientBuilder.create();
    try {
        String certificateStorage = <<yourCertStorageFileName>>;
        String certificatePassword = <<yourCertStoragePassword>>;
        SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(
            new File(certificateStorage), certificatePassword.toCharArray(),
            new TrustSelfSignedStrategy()).build();
        SSLConnectionSocketFactory sslFactory = new SSLConnectionSocketFactory(sslContext,
            new String[]{"TLSv1"}, null,
            SSLConnectionSocketFactory.getDefaultHostnameVerifier());
        clientBuilder.setSSLSocketFactory(sslFactory);
    }
    catch (Exception e) {
        throw new IllegalArgumentException("Error configuring server certificates.", e);
    }
    HttpClient httpClient = clientBuilder.build();
    Unirest.setHttpClient(httpClient);
}
于 2016-02-06T15:44:00.393 に答える