How to access https through http proxy in Java? - java

I have a http proxy ip 218.106.96.211 and it's possible to access a website through the proxy.
RequestConfig config = RequestConfig.custom().setProxy(new HttpHost("218.106.96.211", 80, "http")).build();
HttpGet request = new HttpGet("http://www.example.com/");
request.setConfig(config);
and it's possible to access a https website in java.
SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(new File("file.storage"), null, new TrustSelfSignedStrategy()).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null,SSLConnectionSocketFactory.getDefaultHostnameVerifier());
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
HttpGet httpget = new HttpGet("https://www.def.com");
but if I access the https through the proxy, server responsed HTTP/1.1 400 Bad Request, so what's the right way to access https through http proxy in java?

Related

REST webservice call for HTTPS link - 400 Bad Request error

Using SOAP UI, I am able to successfully invoke the REST GET call with basic authentication
GET https://app.test.com/testing/rest/authentication-point/authentication HTTP/1.1
Accept-Encoding: gzip,deflate
Authorization: Basic aPOjYVclOmIzABFhZjVpJES=
Host: app.test.com
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
I received response code as 200.
Similar request, When I tried to invoke via java client, it is giving 400 status code.
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("User", "Password"));
final HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(credsProvider);
HttpClient client = HttpClientBuilder.create().build();
HttpResponse response = null;
response = client.execute(
new HttpGet("https://app.test.com/testing/rest/authentication-point/authentication"),
context);
int statusCode = response.getStatusLine().getStatusCode();
This code worked properly when the host was HTTP. Recently a VIP is added and made as HTTPS, after which it is not working. Please suggest a fix for this.
You need to use ssl with http client:
TrustStrategy acceptingTrustStrategy = (cert, authType) -> true;
SSLSocketFactory sf = new SSLSocketFactory(
acceptingTrustStrategy, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("https", 8443, sf));
ClientConnectionManager ccm = new PoolingClientConnectionManager(registry);
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("User", "Password"));
final HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(credsProvider);
DefaultHttpClient httpClient = new DefaultHttpClient(ccm);
HttpGet getMethod = new HttpGet(new HttpGet("https://app.test.com/testing/rest/authentication-point/authentication"),context);
HttpResponse response = httpClient.execute(getMethod);
int statusCode = response.getStatusLine().getStatusCode();
After trying out so many options, below code worked for me.
HttpHost targetHost = new HttpHost("app.test.com", 443, "https");
AuthCache authCache = new BasicAuthCache();
authCache.put(targetHost, new BasicScheme());
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("User", "Password"));
final HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(credsProvider);
context.setAuthCache(authCache);
HttpClient client = HttpClientBuilder.create().build();
HttpResponse response = null;
response = client.execute(
new HttpGet("https://app.test.com/testing/rest/authentication-point/authentication"),
context);
After defining a HTTP host with scheme as https, and setting them to context using AuthCache, the call went through successfully.

Apache HttpClient - POST to https url secure?

i want to do a HTTP POST request, which is secured by ssl.
the client is my java program, which is posting to a https-url (https:// ...). the certificate of the website is verified, i am using Apache HttpClient 4.5.1
with a normal post-request and a custom httpclient.
HttpContext context = HttpClientContext.create();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setDefaultMaxPerRoute(MAX_CONNECTIONS_PER_ROUTE);
cm.setMaxTotal(MAX_TOTAL_CONNECTIONS);
CloseableHttpClient client = HttpClients.custom()
.setConnectionManager(cm)
.build();
HttpContext context = HttpClientContext.create();
HttpPost login = new HttpPost("https://example.org"); // example url
login.addHeader("Content-Type", "application/json; charset=UTF-8");
login.addHeader("Accept", "application/json; charset=UTF-
login.setEntity(new StringEntity(loginData, ContentType.create("application/json", "UTF-8")));
JSONResponseHandler<JSONObject> rh = new JSONResponseHandler<>();
JSONObject test = client.execute(login, rh, context);
is this sufficend to get a ssl-secured connection or do i have to work with KeyStore, SSLContext and SSLConnectionFactory?
if i have to use those, how would i do this in an efficent way. i only saw examples how to allow self-signed certificates.

Apache HttpClient throws Remote host closed connection during handshake exception when trying to download file

I have a url where a file is available for download via http. If I hit that url with a curl the file downloads without issues. But if I try in code with Apache HttpClient, it gives an exception. Here is the code...
HttpClient httpClient = new HttpClient()
HttpMethod method = new GetMethod("https://www2.mycompany.com/internet/cats/productfeed.nsf/xmlproductfeed?openview")
def responseCode = httpClient.executeMethod(method)
The exception is
javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:882)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1188)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:654)
at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:100)
at org.apache.commons.httpclient.HttpConnection.flushRequestOutputStream(HttpConnection.java:828)
at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2116)
at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096)
at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
Could it be the https or the www2 in the url?
You are calling the URL through HTTPS, this is a TLS connection. You need to set up your client to use SSL/TLS.
Here is an example, rewrite to HttpGet, but this should be easy:
// Trust own CA and all self-signed certs
SSLContext sslcontext = createEasySSLContext();
// Allow TLSv1 protocol only
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext,
new String[] { "TLSv1", "TLSv1.1", "TLSv1.2" }, null,
SSLConnectionSocketFactory.getDefaultHostnameVerifier());
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
String userCredentials = username + ":" + password;
String basicAuth = "Basic " + new String(new Base64().encode(userCredentials.getBytes()));
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
HttpClientContext localContext = HttpClientContext.create();
localContext.setCredentialsProvider(credentialsProvider);
HttpPost httpPost = new HttpPost(path);

HttpClient and Connection Timeout

I send http requests over Apache HttpClient and my code is here:
HttpHost proxy = new HttpHost("78.1.1.222", 80);
DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy);
httpClient = HttpClients.custom()
.setRoutePlanner(routePlanner)
.build();
HttpGet httpGet = new HttpGet(url);
httpGet.addHeader("Authorization","Basic " + encoding);
httpGet.addHeader("Cache-Control", "no-cache");
httpResponse = httpClient.execute(httpGet);
responseCode=httpResponse.getStatusLine().getStatusCode();
........
........(code continue..)
My question is that how can I add connection timeout time to this code?
Note that I must use proxy with that and I use HttpClient 4.4 .
http://www.baeldung.com/httpclient-timeout explains various ways to set the connection timeout.

401 unauthorized with SSL and HttpClient library

When i try to login app with ssl
SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy())
.build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new String[]{"TLSv1"},
null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
HttpPost httppost = new HttpPost("https://otherwebapp.my.com/login");
BasicCredentialsProvider provider = new BasicCredentialsProvider();
provider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("admin", "admin"));
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).setDefaultCredentialsProvider(provider).build();
CloseableHttpResponse response = httpclient.execute(httppost);
I get 401 Unauthorized
When i login by POST in Chrome Advanced Rest Client view
everything works well.
I was looking differences through Wireshark monitor traffic
and not found difference between sending of my code and of chrome Advanced Rest Client view
If someone has ideas, plz help me

Categories