Proxy setting for HttpClient 4 not working - java

I am using Apache HttpClient library to connect to url. The network in which i am doing has a secure proxy to it. when i am using the java.net package to connect to the url i just have to add the
System.setProperty("http.proxyHost", proxy);
System.setProperty("http.proxyPort", proxyPort);
no proxy userid and password is needed to be passed but when i am trying to connect through httpclient i am getting 407 proxy authentication error.My code is:
HttpHost proxy = new HttpHost("xyz.abc.com",8080,"http");
HttpClient httpclient = new DefaultHttpClient();
httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY,proxy);
Proxy is using NTML authentication.I don't want to pass userid and password.

I have upgraded to httpclient 4.2 and this version has out of box NTML support. Just need to add following lines to the code
HttpClient httpclient = new DefaultHttpClient();
NTCredentials creds = new NTCredentials("user", "pwd", "myworkstation", "microsoft.com");
httpclient.getCredentialsProvider().setCredentials(AuthScope.ANY, creds);
For further reading Httpclent authentication scheme u can refer http://hc.apache.org/httpcomponents-client-ga/tutorial/html/authentication.html#d5e947
But my question is still open, why HttpClent is not picking the system proxy as simple java program does.

In order for the system properties to be picked up, you could use SystemDefaultHttpClient instead of DefaultHttpClient.
As of HttpClient 4.3, this class has been deprecated in favor of HttpClientBuilder:
HttpClient hc = new HttpClientBuilder().useSystemProperties().build();

Related

How do I configure SSL via rest?

A dynamic SSL configuration has been created on IBM WebSphere that embeds a certificate in outgoing requests, you do not need to specify the paths to jks in the code. How can I configure sending a rest request so that HttpClient does not search for certificates in IBM jdk if the request comes via https?
CloseableHttpClient httpClient = null;
HttpClientBuilder builder = HttpClientBuilder
.create()
.useSystemProperties();
httpClient = builder.build();
HttpPost request = new HttpPost("https://test.org:8081/add");
// add request headers
request.addHeader("custom-key", "rev");
request.addHeader(HttpHeaders.USER_AGENT, "lebot");
CloseableHttpResponse response = httpClient.execute(request);

Unable to connect to TLS 1.2 using HTTPclient 3.1

I have a running code that i am already using to connect to a server using SSL. The API i am using is commons-httpclient-3.1.jar and i cant not upgrade the jar.
The servers have upgraded to only use TSL 1.2.
Now my existing code is not working.
My current code is
HttpClient httpClient = new HttpClient();
PostMethod post = new PostMethod("https://XYZserver");
post.getParams().setParameter("http.protocol.version", HttpVersion.HTTP_1_1);
File f = new File("C://sampleXml.xml");
RequestEntity entity = new FileRequestEntity(f, "Application/xml");
post.setRequestEntity(entity);
int statusCode = httpClient.executeMethod(post);
If i modify my code as per link How to force Commons HTTPClient 3.1 to use TLS 1.2 only for HTTPS? then my code is working fine.
I have few questions (As i was unable to find their answers?)
Why do we require a separate class CustomHttpsSocketFactory. Is it possible to modify existing code to use TLS
Is there any other way to do?

How can HttpClientBuilder retrieve credentials for proxy authentication?

I have developed a Java Applet that works properly in a standard environment (no proxies). On the contrary if the applet is running on a client located behind a proxy, it correctly downloads files and accedes resources with simple http GET methods (java.net) but http POST method using Apache httpclient doesn't work.
I'm using:
HttpClientBuilder clientBuilder = HttpClientBuilder.create();
clientBuilder.useSystemProperties();
CloseableHttpClient httpclient = clientBuilder.build();
to retrieve credentials for proxy authentication (these credentials have been already used by JVM, because I can accede external resources using java.net).
The execution of the POST method results in a 407 error (Proxy authentication required). Why useSystemProperties() can't retrieve the credentials for authentication? How can I retrieve username and passoword for the proxy?

Java HTTP post using HTTPS Confusion - javax.net.ssl.SSLException: hostname in certificate didn't match

I'm sending an https POST on some url using Apache HttpClient.
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse response = httpClient.execute(httpPost);
And I get:
javax.net.ssl.SSLException: hostname in certificate didn't match: <*.*.*.*> != <*.url
Now after searching, I found the solution on stackoverflow:
HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
SchemeRegistry registry = new SchemeRegistry();
SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory();
socketFactory.setHostnameVerifier((X509HostnameVerifier) hostnameVerifier);
registry.register(new Scheme("https", socketFactory, 443));
SingleClientConnManager mgr = new SingleClientConnManager(client.getParams(), registry);
HttpClient httpClient = new DefaultHttpClient(mgr, client.getParams());
HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
And the POST is succesfully done.
But I don't understand what's happening here! Is my connection still secure?
Is this the right solution? If not, what's the best solution?
If you're not verifying the host name, you're simply not checking that you're talking to the entity you intended to talk to: it could be a MITM instead. It's the same issue as disabling VERIFYHOST with Curl, for example. You may also be interested in this question on Security.SE.
Regarding your initial problem, the host name (or IP address) in the certificate needs to match the host name you intended to contact, that is, the one in the URL.
If you're using an IP address, that IP address needs to be in the Subject Alternative Name of the certificate. (See this question.)
In general, it's easier to use names rather than IP addresses, even on a LAN.
EDIT: Considering you're using Apache Http Client 4.0.2, the release notes for 4.0.3 say:
This is an emergency release fixing a critical regression in the SSL
connection management code. HttpClient 4.0.2 release included an
improved support for multihome hosts, which unfortunately had a bug
causing the default SSL hostname verification logic to fail. An
attempt to establish an SSL connection with HttpClient 4.0.2 can
result in javax.net.ssl.SSLException: "hostname in certificate didn't
match ..." error.
Important - if you are allowing all hosts (that is, disabling host name verification), then it is certainly NOT safe. You shouldn't be doing this in production.
I think you are probably using self-signed certificates which may be the root cause of this exception. If yes, create a certificate with host as localhost (or your IP) and then try. On production, just enable host name verification and your code would run fine.

How can I configure HTTPClient to authenticate against a SOCKS proxy?

I need to set up proxy authentication against a SOCKS proxy.
I found out this post giving instructions that appear to work with common HTTP proxies.
httpclient.getHostConfiguration().setProxy("proxyserver.example.com", 8080);
HttpState state = new HttpState();
state.setProxyCredentials(new AuthScope("proxyserver.example.com", 8080),
new UsernamePasswordCredentials("username", "password"));
httpclient.setState(state);
Would that work with SOCKS proxies as well or do I have to do something different?
Java supports Socks proxy configuration via preferences:
socksProxyHost for the host name of the SOCKS proxy server
socksProxyPort for the port number, the default value being 1080
e.g.
java -DsocksProxyHost=socks.mydomain.com
(edit) For your example, if the socks proxy was configured in the way outlined before:
httpclient.getHostConfiguration().setProxy("proxyserver.example.com", 8080);
Credentials cred = new UsernamePasswordCredentials("username","password");
httpclient.getState().setProxyCredentials(AuthScope.ANY, cred);
You can also use this variant (without httpclient):
SocketAddress addr = new
InetSocketAddress("webcache.mydomain.com", 8080);
Proxy proxy = new Proxy(Proxy.Type.SOCKS, addr); // Type.HTTP for HTTP
So completing the previous example, we can now add:
URL url = new URL("http://java.sun.com/");
URConnection conn = url.openConnection(proxy);
HTH
The Features page of Apache HTTPClient says:
Transparent connections through SOCKS proxies (version 4 & 5) using native Java socket support.
With "transparent", I guess they mean that it works without you needing to do anything special. Do you have a SOCKS proxy available somewhere? Can't you just try it out to see if it works?
SOCKS is not supported by HttpClient 3 natively. You can try the SOCKS support in JDK as suggested by others. The side effect is that your whole JVM will go through the same SOCKS proxy.
Java 5 supports Username/Password authentication in SOCKS (type 2). All you have to do is to setup the authenticator like this,
Authenticator.setDefault(new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password.toCharArray());
}
});
Again, this may not work for you because it affects all authentication in your JVM (HTTP auth, Proxy Auth).
You can provide a custom socket factory which implements the SOCKS protocol, and register it as your default HTTP protocol handler. This solution has a limitation similar to tuergeist's answer above has - it applies globally, to any HTTP connection you'll establish through HttpClient.
If you find this a problem, take a look at this correspondence, where Oleg suggests using HttpClient 4.0, but also refers to a possible patch in HostConfiguration class for HttpClient 3.x.
Another possible solution, which is my personal favorite, is to write a wrapper HTTP proxy to the socks proxy.
I tried
System.setProperty("socksProxyHost", "socks.xyz.com");
System.setProperty("socksProxyPort", "1000");
and it's working fine.

Categories

Resources