如何使Unirest(java)忽略证书错误

时间:2014-04-23 10:55:51

标签: java apache-httpclient-4.x unirest

我正在使用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的{​​{1}}方法是:

MyHttpClient

主要思想来自Ignoring SSL certificate in Apache HttpClient 4.3

但这仍然没有用。有什么建议吗?

5 个答案:

答案 0 :(得分:9)

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

这对我有用

答案 1 :(得分:5)

这就是我最终解决问题的方法:

public static HttpClient makeClient(){
    SchemeRegistry schemeRegistry = new SchemeRegistry();
    schemeRegistry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));
    try {
        schemeRegistry.register(new Scheme("https", 443, new MockSSLSocketFactory()));
    } catch (KeyManagementException e) {
        e.printStackTrace();
    } catch (UnrecoverableKeyException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (KeyStoreException e) {
        e.printStackTrace();
    }
    ClientConnectionManager cm = new SingleClientConnManager(schemeRegistry);
    DefaultHttpClient httpclient = new DefaultHttpClient(cm);
    return httpclient;
}

我一整天都在抓挠,我希望这可以帮助别人。

答案 2 :(得分:2)

我正在使用“ com.konghq:unirest-java:2.3.14”

现在有一个配置

Unirest.config().verifySsl(false);

答案 3 :(得分:1)

证书错误解决方案是来自几个地方的组合

和一个相对完整的例子。

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

答案 4 :(得分:0)

不幸的是,Unirest没有本地方式来配置SSL,因此提供自定义HttpClient实例看起来是唯一的选择。 这是一个解决方案,它不使用已弃用的类(如&#39; DefaultHttpClient&#39;)并使用自签名证书:

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