首页 > 解决方案 > HttpClient 是否同时配置了 SSL 和 Proxy 身份验证?

问题描述

我有两段使用 HttpClient 的代码,
第一部分是端点需要 SSL
第二部分是具有基本身份验证的代理连接
我的问题是如何使这段代码有条件,所以如果我有 SSL + 代理或 SSL时间弄清楚如何设置默认凭据,例如在我使用 SSL 部分中的客户端创建客户端之后

.setDefaultCredentialsProvider(credsProvider)

这部分是我在需要 SSL 时创建客户端的方式

CloseableHttpClient client = null;

    if(conf.isUseSslConfig()) {         
        SSLContext sslcontext = SSLContexts.custom()
                    .loadTrustMaterial(new File(conf.getTrustStoreLocation()), conf.getTrustStorePassword().toCharArray(), new TrustSelfSignedStrategy()).build();

            // Allow protocols
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext,conf.getTlsVersions(), null,
                    SSLConnectionSocketFactory.getDefaultHostnameVerifier());               
            client = HttpClients.custom().setSSLSocketFactory(sslsf).build();


        }else {
            client= HttpClients.createDefault();                
        }

这部分是我在需要代理身份验证时创建客户端的方式:

if(conf.isUseProxyConfig()){
    CredentialsProvider credsProvider = new BasicCredentialsProvider();        
    credsProvider.setCredentials(
            new AuthScope("fakeProxy.xerox.com", 80),
            new UsernamePasswordCredentials("xeroxUser","fakePassword123"));

HttpClients.custom()
            .setDefaultCredentialsProvider(credsProvider).build();
         }

所以底线是如何让这两个部分一起工作,以防万一

  1. 使用 SSL + 代理和身份验证调用
  2. 仅使用 SSL 调用
  3. 仅使用代理和身份验证进行调用

标签: apache-commons-httpclient

解决方案


您可以通过这种方式编写代码来解决多个条件:

CloseableHttpClient client = null;

    if(conf.isUseSslConfig() && conf.isUseProxyConfig()) {         

            setSSLSetting(client);
            setProxy()

        }else  if(conf.isUseSslConfig()) {

        setSSLSetting(client);
        }else {
            client= HttpClients.createDefault();                
        }


private void setProxy(){
    CredentialsProvider credsProvider = new BasicCredentialsProvider();        
    credsProvider.setCredentials(new AuthScope("fakeProxy.xerox.com", 80),new UsernamePasswordCredentials("xeroxUser","fakePassword123"));
}       


private void setSSLSetting(CloseableHttpClient client){
        SSLContext sslcontext = SSLContexts.custom()
                    .loadTrustMaterial(new File(conf.getTrustStoreLocation()), conf.getTrustStorePassword().toCharArray(), new TrustSelfSignedStrategy()).build();

            // Allow protocols
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext,conf.getTlsVersions(), null,
                    SSLConnectionSocketFactory.getDefaultHostnameVerifier());               
            client = HttpClients.custom().setSSLSocketFactory(sslsf).build();
}

或者您可以创建返回具有不同设置和配置的客户端的方法,如下所示:


    final Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create().register("http", new PlainConnectionSocketFactory()).register("https", sslsf).build();

    final PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);

    private CloseableHttpClient createHttpClient(String headerName, String value) throws NoSuchAlgorithmException, KeyManagementException,KeyStoreException {
        SSLContextBuilder builder = new SSLContextBuilder();
        builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
        Header header = new BasicHeader(headerName,value);
        List<Header> headers = new ArrayList<>();
        headers.add(header);
        RequestConfig reqConfig = RequestConfig.custom().setConnectionRequestTimeout(long milli seconds).build();

        CloseableHttpClient httpclient = HttpClients.custom().
                setDefaultHeaders(headers).
                setDefaultRequestConfig(reqConfig).
                setConnectionManager(cm).
                build();
        return httpclient;
    }

推荐阅读