【问题标题】:how to make Unirest(java) ignore certificate error如何使 Unirest(java) 忽略证书错误
【发布时间】:2014-06-08 03:53:33
【问题描述】:

我正在使用 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();

MyHttpClientmakeClient方法是:

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

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

但这仍然不起作用。有什么建议吗?

【问题讨论】:

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


    【解决方案1】:

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

    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】:

    不幸的是,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);
    }
    

    【讨论】:

      【解决方案3】:
       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);
      

      这对我有用

      【讨论】:

      【解决方案4】:

      证书错误的解决方法是几个地方的组合

      和一个比较完整的例子。

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

      【讨论】:

        【解决方案5】:

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

        现在有一个配置

        Unirest.config().verifySsl(false);
        

        【讨论】:

          猜你喜欢
          • 2012-08-17
          • 1970-01-01
          • 2019-09-02
          • 1970-01-01
          • 2023-03-23
          • 2010-11-21
          • 1970-01-01
          • 2018-07-12
          相关资源
          最近更新 更多