HttpGet working in SE application but not in Container - java

My test application works when running it from a SE application but when using the same code in a web based application it refuses to work.
example code:
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build());
HttpHost target = new HttpHost("test.test.com", 443, "https");
HttpHost proxy = new HttpHost("41.41.41.41", 3128, "http");
final RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(5000)
.setConnectionRequestTimeout(5000)
.setSocketTimeout(5000).setProxy(proxy)
.build();
CloseableHttpClient httpclient = HttpClients.custom()
.setSSLSocketFactory(sslsf)
.setDefaultRequestConfig(requestConfig)
.build();
HttpGet httpGet = new HttpGet(validateUrl);
httpGet.setHeader("Authorization", "Basic " + authenticationStringEncrypted);
CloseableHttpResponse response = httpclient.execute(target, httpGet);
In the web application it gets to this part:
CloseableHttpClient httpclient = HttpClients.custom()
.setSSLSocketFactory(sslsf)
.setDefaultRequestConfig(requestConfig)
.build();
Then it stops, no exceptions are thrown and this block is surrounded with a try-catch, using multicatch to catch all exceptions.
} catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException | IOException ex) {
ex.printStackTrace();
}
The web based application is deployed to glassfish 4.1.

Related

CloseableHttpClient session not closed

I create a CloseableHttpClient with intent to connect to our Tomcat to execute some services.
After the request i call close on the client but I still see that there a active Session in Tomcat.
Should not close invalidate the session?
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(1000 * 60 * 2)
.setConnectTimeout(4000)
.build();
HttpClientBuilder cl = HttpClients.custom();
cl.setDefaultRequestConfig(requestConfig);
cl.setSSLSocketFactory(makeSSLConnectionSocketFactory());
HttpGet postMethod = new HttpGet(url);
try (CloseableHttpClient client = cl.build();
CloseableHttpResponse httpResponse = client.execute(postMethod);) {
} catch (IOException e) {
//e.printStackTrace();
}

Apache HttpClient 5.0 HTTPS proxy: "No tunnel unless connected"

I am using the latest version of JDK8
My CloseableHttpAsyncClient is created by doing the following
try{
sslContext = SSLContexts.custom()
.setProvider(Conscrypt.newProvider())
.build();
}catch (Exception e){
e.printStackTrace();
}
final PoolingAsyncClientConnectionManager cm = PoolingAsyncClientConnectionManagerBuilder.create()
.setTlsStrategy(new ConscryptClientTlsStrategy(sslContext))
.build();
BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
if (proxy.isAuth()) {
credentialsProvider.setCredentials(
new AuthScope(proxy.getIp(), Integer.parseInt(proxy.getPort())),
new UsernamePasswordCredentials(proxy.getUsername(), proxy.getPassword().toCharArray()));
}
HttpHost p = new HttpHost(proxy.getIp(), Integer.parseInt(proxy.getPort()), "http");
asyncClient = HttpAsyncClients.custom()
.setVersionPolicy(HttpVersionPolicy.FORCE_HTTP_1)
.setConnectionManager(cm)
.setUserAgent(Utils.USER_AGENT)
.setDefaultCookieStore(cookieStore)
.setDefaultCredentialsProvider(credentialsProvider)
.setProxy(p)
.build();
asyncClient.start();
I am then trying to do a post request which works without a proxy. The request with the proxy also works with the url using http and not https. I receive the following error java.lang.IllegalStateException: No tunnel unless connected when using https and a proxy.

Java socket is closed - When posting SOAP request

first time posting a question on this site. I've been working on a project where I have to generate a signed(Header x509) SOAP request and submit it to an https URL where the webservice resides. Thus far I've been able to generate the Signed SOAP request, but I'm getting a socket is closed exception when I post the request. Can anyone help me figure out what is my code missing that could be causing this error. Thank you in advance!
Below is my code for how I'm posting the request, and the error:
SSLContext sslcontext = SSLContexts.custom()
.loadTrustMaterial(new File("my keystore"), "mypassword".toCharArray(),
new TrustSelfSignedStrategy())
.build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslcontext,
new String[] { "TLSv1" },
null,
SSLConnectionSocketFactory.getDefaultHostnameVerifier());
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(300 * 1000)
.setConnectTimeout(300 * 1000)
.setConnectionRequestTimeout(300 * 1000)
.build();
HttpClient httpclient = HttpClients.custom() //CloseableHttpClient
.setDefaultRequestConfig(requestConfig)
.setSSLSocketFactory(sslsf)
.build();
HttpPost httpPost;
httpPost = new HttpPost("https://my webservice");
httpPost.setHeader("Content-type", "test/xml");
File input = new File(esbXmlFile);
InputStream inputStream = new FileInputStream(input);
InputStreamEntity inputStreamEntity = new InputStreamEntity(inputStream);
httpPost.setEntity(inputStreamEntity);
String content = null;
int statusCode = 1; //statusCode is response code form WS.
try
{
HttpResponse response = httpclient.execute(httpPost);
statusCode = response.getStatusLine().getStatusCode();
System.out.println("statusCode : " + statusCode);
HttpEntity entity = response.getEntity();
content = EntityUtils.toString(entity);
}
catch (SocketException e) {
e.getStackTrace();
}
catch (IOException e) {
e.getStackTrace();
}
I get this error:
DEBUG (main) [org.apache.http.conn.ssl.SSLConnectionSocketFactory] - Starting handshake
2016-11-28 16:24:04,019 DEBUG (main) [org.apache.http.impl.conn.DefaultManagedHttpClientConnection] - http-outgoing-1: Shutdown connection
2016-11-28 16:24:04,019 DEBUG (main) [org.apache.http.impl.execchain.MainClientExec] - Socket is closed
java.net.SocketException: Socket is closed
at java.net.Socket.setSoLinger(Socket.java:986)
at org.apache.http.impl.BHttpConnectionBase.shutdown(BHttpConnectionBase.java:305)
at org.apache.http.impl.conn.DefaultManagedHttpClientConnection.shutdown(DefaultManagedHttpClientConnection.java:97)
at org.apache.http.impl.conn.LoggingManagedHttpClientConnection.shutdown(LoggingManagedHttpClientConnection.java:89)
at org.apache.http.impl.conn.CPoolEntry.shutdownConnection(CPoolEntry.java:74)
at org.apache.http.impl.conn.CPoolProxy.shutdown(CPoolProxy.java:96)
at org.apache.http.impl.execchain.ConnectionHolder.abortConnection(ConnectionHolder.java:127)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:352)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:55)
Maybe you have to set:
httpPost.setHeader("Content-type", "test/xml");
into
httpPost.setHeader("Content-type", "text/xml");
difference is test/xml into text/xml

javax.net.ssl.SSLPeerUnverifiedException: Host name does not match the certificate subject provided by the peer

I follow many links on stackoverflow and tried many solutions, but none of them worked for me. I'm using WSO2 API manager version 1.9.1. I am facing following error:
Exception in thread "main" javax.net.ssl.SSLPeerUnverifiedException: Host name 'XXXXXXXXX' does not match the certificate subject provided by the peer (CN=localhost, O=WSO2, L=Mountain View, ST=CA, C=US)
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.verifyHostname(SSLConnectionSocketFactory.java:465)
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:395)
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:353)
at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:134)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:353)
at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:380)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107)
at com.java.pushNotifications.WSO2DemoClient.main(WSO2DemoClient.java:49)
I developed the following Java code. Please help me what's going wrong here. I need to connect insecure way and allow connections to SSL sites without certs.
public static void main(String[] args) throws ClientProtocolException, IOException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build());
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", new PlainConnectionSocketFactory())
.register("https", sslsf)
.build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
cm.setMaxTotal(2000);//max connection
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf)
.setConnectionManager(cm).build();
HttpGet httpGet = new HttpGet("https://XXXXXXXXXX:8243/token");
CloseableHttpResponse response = httpclient.execute(httpGet);
String json =" {\"data\":\"grant_type=password&username=test&password=test123\"}";
try {
HttpPost httpost = new HttpPost(url);
httpost.setHeader("Content-Type", "application/x-www-form-urlencoded");
httpost.setHeader("Authorization", "Basic XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
httpost.setEntity(new StringEntity(json));
HttpResponse httpResponse = httpclient.execute(httpost);
System.out.println(httpResponse.getStatusLine());
}
finally {
response.close();
}
String responseString1 = new BasicResponseHandler().handleResponse(response);
System.out.println("Response : "+responseString1);
}
I have spent an hour trying to fix the same issue. This is what I come up with:
final SSLConnectionSocketFactory sslsf;
try {
sslsf = new SSLConnectionSocketFactory(SSLContext.getDefault(),
NoopHostnameVerifier.INSTANCE);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
final Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", new PlainConnectionSocketFactory())
.register("https", sslsf)
.build();
final PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
cm.setMaxTotal(100);
httpClient = HttpClients.custom()
.setSSLSocketFactory(sslsf)
.setConnectionManager(cm)
.build();
Hopefully, it works and does not use any deprecated code (httpclient 4.4.1).
Replace this
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf)
.setConnectionManager(cm).build();
with
CloseableHttpClient httpclient = HttpClients.custom()
.setSSLSocketFactory(sslsf)
.setConnectionManager(cm)
.setHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
.build();
If the certificate isn't signed (not even self-signed), then you can do
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
public class TrustAllStrategy implements TrustStrategy {
#Override
public boolean isTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
return true;
}
}
Then
builder.loadTrustMaterial(new TrustAllStrategy());
EDIT: this
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslcontext, //for you this is builder.build()
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER
);
Thanks to all the solutions. I have been trying all the solutions available online for 1.5 days now and finally it worked now. Here is the working code
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(builder.build(), NoopHostnameVerifier.INSTANCE);
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", new PlainConnectionSocketFactory())
.register("https", sslConnectionSocketFactory)
.build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
cm.setMaxTotal(100);
CloseableHttpClient httpclient = HttpClients.custom()
.setSSLSocketFactory(sslConnectionSocketFactory)
.setConnectionManager(cm)
.build();
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(postEntity);
httpPost.expectContinue();
CloseableHttpResponse response = httpclient.execute(httpPost);
This is what I came up with:
SSLContextBuilder sslcontext = new SSLContextBuilder();
sslcontext.loadTrustMaterial(null, new TrustSelfSignedStrategy());
httpclient = HttpAsyncClients.custom().setSSLContext(sslcontext.build()).setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.build();
After trying most of the solution suggested on this page and other related stackoverflow discussions, I found AJC's response above works with apache httpclient version 4.5.
Reason:
While creating SSLConnectionSocketFactory if the HostVerifier is not specified in the constructor, it does not get set and the DefaultHostVerifier is used. So line 3 of AJC's solutionmakes the difference.
(Atleast this is the behavior in apache httpclient 4.5.3 )

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