hc-httpclient-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Oleg Kalnichevski <ol...@apache.org>
Subject Re: Can't override default hostname verifier
Date Tue, 08 Oct 2013 10:42:01 GMT
On Tue, 2013-10-08 at 00:24 +0000, Pete Keyes wrote:
> 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
> 

Pete,

In your case a custom connection manager overrides a custom hostname
verifier. You cannot have them both. 

If you have a list of hosts you would like to handle differently prior
to constructing the connection manager you should create a custom
X509HostnameVerifier and supply to the connection manager at the
construction time. If you want to update the list dynamically your only
option is to create a custom LayeredConnectionSocketFactory and use
HttpContext to supply the list of special cases to the #connectSocket
method.

Hope this helps

Oleg





---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
For additional commands, e-mail: httpclient-users-help@hc.apache.org


Mime
View raw message