I am trying to connect to an HTTPs URL with Apache HttpClient 4.1....
HttpGet httpget = new HttpGet("https://federation/galaxy-class/enterprise/getSheildFrequencies");
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(httpget);
During the connection process, I get the below exception...
Caught: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
When I turn on debugging, I see the below..
main, WRITE: TLSv1 Handshake, length = 81
main, WRITE: SSLv2 client hello message, length = 110
main, handling exception: java.net.SocketException: Connection reset
So it seems like my client did the handshake in TLSv1 but then sent a client hello in SSLv2 which the server didn't like (it dropped the connection because it doesn't support SSLv2 backwards compatibility mode).
Is there any way to tell Apache HttpClient not to do that? Or is this something configured at the underlying JRE (I am using 1.6)?
UPDATE
As bmargulies suggested, I tried to make my own socket factory and configure it to only allow the protocols I want....
def supportedProtocols = new String[2]
supportedProtocols[0] = 'SSLv3'
supportedProtocols[1] = 'TLSv1'
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
SSLContext.getDefault(),supportedProtocols,
null,
SSLConnectionSocketFactory.getDefaultHostnameVerifier());
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", socketFactory)
.build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
CloseableHttpClient client = HttpClients.custom().setConnectionManager(cm).build();
HttpResponse response = client.execute(httpget);
But this gives another exception...
javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair
Use the current version of the http components
Use the HttpClientBuilder
Make your own socket factory and configure it to only allow the protocols you want.
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainSocketFactory.INSTANCE)
.register("https", new SSLSocketFactory(sslcontext, hostnameVerifier))
.build();
Remove SSLv2ClientHello from the SSLContext's enabled protocols.
Related
I'm trying to connect to a website through a proxy, but I'm getting an error
Error Code: 407 Proxy Authentication Required. Forefront TMG requires authorization to fulfill the request. Access to the Web Proxy filter is denied. (12209)
My code is very close to the example that apache provides, https://hc.apache.org/httpcomponents-client-ga/examples.html (see the proxy authentication example). I'm definitely doing something wrong with authentication, but...what?
HttpHost proxy = new HttpHost("http-proxy", 80);
HttpHost target = new HttpHost(url, 80);
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(user,password));
try (CloseableHttpClient client = HttpClientBuilder.create().setDefaultCredentialsProvider(new SystemDefaultCredentialsProvider()).build()) {
RequestConfig config = RequestConfig.custom().setProxy(proxy).build();
HttpGet httpget = new HttpGet("/basic-auth/user/passwd");
httpget.setConfig(config);
HttpResponse response = client.execute(target, httpget);
}
The problem seems to be that you are setting new SystemDefaultCredentialsProvider() when you are building the HTTP client. I guess you intention was to set credsProvider, to which you have just added proxy user and password.
I need to call third party web service via proxy.
I only have information below:
- Third party https IP & Port
- Proxy http IP & Port
May I know I need credential : username & Password for the Proxy?
Part of my code below:-
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpHost proxy = new HttpHost(proxyHost, proxyPort);
DefaultProxyRoutePlanner routePlanner = new
DefaultProxyRoutePlanner(proxy);
CloseableHttpClient httpclient = HttpClients.custom()
.setRoutePlanner(routePlanner)
.build();
RequestConfig config =RequestConfig.custom().setProxy(proxy).build();
HttpPost httppost = new HttpPost(queryUrl);
httppost.setConfig(config);
CloseableHttpResponse httpResponse = httpclient.execute(httppost);
Unfortunately, Proxy server reponse me "Access denied. Authentication is required."
Any idea for this problem?
When I create a cxf client to call a SOAP web service it returns connection refused or Unexpected end of file from server. The thing is though, it just happens on the first request, afterwards it's like the client is "warmed up" and actually starts working.
Any idea why this is happening?
...
if(port == null) {
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.getInInterceptors().add(new LoggingInInterceptor());
factory.getOutInterceptors().add(new LoggingOutInterceptor());
factory.setAddress("http://localhost:9000/helloWorld");
port = factory.create(HelloWorld.class);
...
Client client= ClientProxy.getClient(port);
HTTPConduit http = (HTTPConduit) client.getConduit();
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setAllowChunking(false);
http.setClient(httpClientPolicy);
}
port.someMethod(); // fails on first run, but succeeds on all following runs
...
Removing the if-statement would cause the client to fail on every call not just the first. I'm really stuck and would appreciate any help.
It seems that the issue was caused through TLS 1.2. In Java8 the default TLS version changed from TLSv1 to TLSv1.2. TLS 1.2 didn't seem to work even with the latest version of CXF (3.1.7). So the Solution was to set the TLS version to be used for CXF:
...
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setAllowChunking(false);
httpClientPolicy.setAutoRedirect(true);
httpClientPolicy.setConnection(ConnectionType.KEEP_ALIVE);
String proxyUrl = "http://proxy.com";
String proxyPortString = "8080";
HTTPConduit http = (HTTPConduit)client.getConduit();
SSLContext sslContext = SSLContext.getInstance("TLSv1");
sslContext.init(null, null, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
TLSClientParameters tlsClientParameters = new TLSClientParameters();
tlsClientParameters.setUseHttpsURLConnectionDefaultSslSocketFactory(true);
http.setTlsClientParameters(tlsClientParameters);
http.setClient(httpClientPolicy);
I have an http2 server at https://ec2-52-57-54-142.eu-central-1.compute.amazonaws.com/ with a self-signed cert. And I have a jetty http2 client that simply posts things to it. For some reason, I'm not getting ignoring self-signed cert to work. Here's a snippet of relevant code
SslContextFactory factory = new SslContextFactory(true);
factory.setTrustAll(true);
factory.setValidateCerts(false);
factory.setValidatePeerCerts(false);
factory.setEndpointIdentificationAlgorithm(null);
SSLContext sslContext = factory.getSslContext();
if(null == sslContext) {
sslContext = SSLContext.getInstance("TLS");
}
TrustManager[] verifiers = new TrustManager[] {...// some dummy trust manager that always passes};
sslContext.init(null, verifiers, null);
factory.setSslContext(sslContext);
HttpClientTransportOverHTTP2 httpClientTransportOverHTTP2
= new HttpClientTransportOverHTTP2(new HTTP2Client());
HttpClient httpClient = new HttpClient(httpClientTransportOverHTTP2, factory);
Request request = httpClient.POST(destination);
ContentProvider contentProvider = new InputStreamContentProvider(new StringInputStream(payload));
request.content(contentProvider);
ContentResponse response = request.send();
And I get these stacktrace
Caused by: java.util.concurrent.ExecutionException: java.nio.channels.ClosedChannelException
at org.eclipse.jetty.client.util.FutureResponseListener.getResult(FutureResponseListener.java:118)
at org.eclipse.jetty.client.util.FutureResponseListener.get(FutureResponseListener.java:101)
at org.eclipse.jetty.client.HttpRequest.send(HttpRequest.java:652)
at my code
... 34 more
Caused by: java.nio.channels.ClosedChannelException
at org.eclipse.jetty.io.WriteFlusher.onClose(WriteFlusher.java:498)
at org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.onIncompleteFlush(SslConnection.java:409)
at org.eclipse.jetty.io.AbstractEndPoint$2.onIncompleteFlush(AbstractEndPoint.java:54)
at org.eclipse.jetty.io.WriteFlusher.write(WriteFlusher.java:322)
at org.eclipse.jetty.io.AbstractEndPoint.write(AbstractEndPoint.java:140)
at org.eclipse.jetty.http2.HTTP2Flusher.process(HTTP2Flusher.java:243)
at org.eclipse.jetty.util.IteratingCallback.processing(IteratingCallback.java:241)
at org.eclipse.jetty.util.IteratingCallback.succeeded(IteratingCallback.java:365)
at org.eclipse.jetty.http2.HTTP2Flusher.succeeded(HTTP2Flusher.java:258)
at org.eclipse.jetty.io.WriteFlusher$PendingState.complete(WriteFlusher.java:269)
at org.eclipse.jetty.io.WriteFlusher.completeWrite(WriteFlusher.java:394)
at org.eclipse.jetty.io.ssl.SslConnection$1.run(SslConnection.java:101)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589)
... 1 more
When I step through things with a debugger, I see something about NOT_HANDSHAKE in one of the connection objects.
I really don't care about verifying anything. I just want to connect over HTTP2/TLS. I searched for many different terms, but they all end up with more or less the same thing (setTrustAll, custom TrustManager, etc)
Any help? Thanks!
P.S. Jetty version 9.3.12
Your client code is correct, although redundant.
It is enough to do:
SslContextFactory sslContextFactory = new SslContextFactory(true);
HTTP2Client http2Client = new HTTP2Client();
HttpClient httpClient = new HttpClient(new HttpClientTransportOverHTTP2(http2Client), sslContextFactory);
httpClient.start();
ContentResponse response = httpClient.GET("https://ec2-52-57-54-142.eu-central-1.compute.amazonaws.com/");
If you enable DEBUG logging on the Jetty HTTP/2 client, you will see that the client receives:
2016-10-05 09:20:33.102:DBUG:oejhp.Parser:qtp1897115967-15: Parsed GO_AWAY frame header from java.nio.HeapByteBuffer[pos=9 lim=35 cap=16384]
2016-10-05 09:20:33.103:DBUG:oejh.HTTP2Session:qtp1897115967-15: Received GoAwayFrame#3bc447d3,0/INADEQUATE_SECURITY_ERROR/Unknown error code
So the problem is that the server thinks that the security is inadequate (the GOAWAY frame arrives with error code INADEQUATE_SECURITY_ERROR).
At this point, the problem is on the server. You have to figure out why the server thinks the security is inadequate. Probably just a matter of configuration on the server.
Try
transport.setUseALPN(false);
I'm currently trying to do multiple HttpGet requests at the same time with CloseableHttpClient.
I googled on how to do that and the answer was to use a PoolingHttpClientConnectionManager.
At this point I got this:
PoolingHttpClientConnectionManager cManager = new PoolingHttpClientConnectionManager();
CloseableHttpClient httpClient = HttpClients.custom()
.setConnectionManager(cManager)
.build();
Then I tried a HttpGet request to http://www.google.com and everything worked fine.
Then I created a truststore via cmd and imported the certificate of the targeted website, setup a SSLConnectionSocketFactory with my truststore and set the SSLSocketFactory of httpClient:
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
FileInputStream inputStream = new FileInputStream(new File("myTrustStore.truststore"));
trustStore.load(inputStream, "nopassword".toCharArray());
inputStream.close();
SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(trustStore).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext,
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
PoolingHttpClientConnectionManager cManager = new PoolingHttpClientConnectionManager();
CloseableHttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(sslsf)
.setConnectionManager(cManager)
.build();
If I try to execute a Https HttpGet then I get a PKIX path building failed exception.
If I do the same without .setConnectionManager(cManager) everything works fine.
Can anyone of you tell me how I can get this to work? (Don't worry, I don't create any ddos tool)
Thanks in advance!
P.S.: I'm using HttpComponents 4.3.1
Found the answer:
https://stackoverflow.com/a/19950935/1223253
Just had to add
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create().register("https", sslsf).build();
and pass socketFactoryRegistry as parameter to the constructor of PoolingHttpClientConnectionManager.
Now it works just fine :)