hc-httpclient-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Pete Keyes <PKe...@starbucks.com>
Subject Can't override default hostname verifier
Date Tue, 08 Oct 2013 00:24:21 GMT
We're using http-client 4.3 and have some situation where the EDI trading partner HTTP server
presents an SSL certificate with a CN doesn't match the service URL's hostname.  To support
this we're trying to use the following code to override the default http-client "BrowserCompatHostnameVerifier"
strategy on a case-by-case basis:
    private static final PoolingHttpClientConnectionManager connManager =
        new PoolingHttpClientConnectionManager()
    ;
    connManager.setDefaultMaxPerRoute(10);
    connManager.setMaxTotal(5000);

    final RequestConfig requestConfig = RequestConfig.custom()
        .setAuthenticationEnabled(bsc.getBasicAuthCfg().isEnabled())
        .setConnectTimeout(bsc.getConnTimeoutMs())
        .setExpectContinueEnabled(bsc.isExpectContinue())
        .setSocketTimeout(bsc.getSoTimeoutMs())
        .setStaleConnectionCheckEnabled(bsc.isStaleConnCheck())
        .build()
    ;

    final HttpHost httpHost = new HttpHost(
        bsc.getUrl().getHost(), bsc.getUrl().getPort()
    );
    final HttpRoute httpRoute = new HttpRoute(httpHost);
    AbstractHttpDeliverTDB.connManager.setMaxPerRoute(
        httpRoute, bsc.getMaxConns()
    );
    final HttpClientBuilder builder = HttpClients.custom()
        .setConnectionManager(AbstractHttpDeliverTDB.connManager)
        .setDefaultConnectionConfig(
            ConnectionConfig.custom().setCharset(charset).build()
        )
        .setDefaultRequestConfig(requestConfig)
    ;

    // disable hostname verification ... if option is disabled
    if(!bsc.isVerifySSLHostname()) {
        StringBuilder msg = new StringBuilder(100)
            .append("hostname verification disabled in http config:")
            .append(" env-id=").append(envId.name())
            .append("; tp=").append(partnerId)
            .append("; tx=").append(folderNm)
            .append("; cfg-nm=").append(cfgDocNm)
        ;
        log.warn(msg);
        final SSLContext sslContext = SSLContexts.createSystemDefault();
        final SSLConnectionSocketFactory sslSF = new SSLConnectionSocketFactory(
            sslContext
            , SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER
        );
        builder.setSSLSocketFactory(sslSF);
    }

    CloseableHttpClient httpClient = builder.build();

    final HttpClientContext httpContext = HttpClientContext.create();

    // add login form parameters
    UrlEncodedFormEntity urlEntity = new UrlEncodedFormEntity(
        formDataList
        , context.bscBase.getCharset()
    );

    // execute login service to get session token
   HttpPost request = new HttpPost(urlLogin);
    request.setEntity(urlEntity);
    HttpResponse response = httpClient.execute(request, httpContext);

The code above results in http-client using the browser compatible strategy rather than simply
ignoring the hostname verification as desired.
10-07 17:00:06.856|FATAL|us bams - 12|                         |SBaseDeliverTDB.login(BAMSBaseDeliverTDB.java:351)|bams
login failed: https://nonp-glbl-bam/m3oui/rest/login; err=javax.net.ssl.SSLException: hostname
in certificate didn't match: <nonp-glbl-bam> != <nonp-glbl-bam.starbucks.net>
javax.net.ssl.SSLException: hostname in certificate didn't match: <nonp-glbl-bam> !=
<nonp-glbl-bam.starbucks.net>
       at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:232) ~[apache-httpclient-4.3.jar:4.3]
       at org.apache.http.conn.ssl.BrowserCompatHostnameVerifier.verify(BrowserCompatHostnameVerifier.java:54)
~[apache-httpclient-4.3.jar:4.3]
       at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:152) ~[apache-httpclient-4.3.jar:4.3]
       at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:133) ~[apache-httpclient-4.3.jar:4.3]
       at org.apache.http.conn.ssl.SSLConnectionSocketFactory.verifyHostname(SSLConnectionSocketFactory.java:289)
~[apache-httpclient-4.3.jar:4.3]
       at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:263)
~[apache-httpclient-4.3.jar:4.3]
       at org.apache.http.impl.conn.HttpClientConnectionOperator.connect(HttpClientConnectionOperator.java:118)
~[apache-httpclient-4.3.jar:4.3]
       at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:314)
~[apache-httpclient-4.3.jar:4.3]
       at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:357)
~[apache-httpclient-4.3.jar:4.3]
       at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:218) ~[apache-httpclient-4.3.jar:4.3]
       at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:194) ~[apache-httpclient-4.3.jar:4.3]
       at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:85) ~[apache-httpclient-4.3.jar:4.3]
       at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108) ~[apache-httpclient-4.3.jar:4.3]
       at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:186)
~[apache-httpclient-4.3.jar:4.3]
       at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
~[apache-httpclient-4.3.jar:4.3]

I'm assuming we've missed something basic in the process of trying to override hostname verification
on a client-by-client basis.  Can anyone point out where we've messed up?

...Pete


Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message