Java settings for Fiddler examination of outgoing SOAP requests? - java

I am trying to debug my SOAP requests going to a third party web service. My client side code (the code running on my local machine) was generated using wsimport. I am trying to configure Fiddler to intercept my outgoing SOAP requests but have had no luck. Here is what I have done so far:
WinINET LAN settings pointed to localhost (127.0.0.1:8888) with Fiddler running and capturing traffic. I have HTTPS requests being decrypted by Fiddler since my web service is using HTTPS. At this point my requests to the 3rd party URL do not appear at all. I receive a stack trace error telling me the web service cannot process request due to an internal error (this is why I am debugging my request - since it is third party I do not have access to the web service logs).
I then added the following code to my method that calls the web service:
System.setProperty("http.proxyHost", "127.0.0.1");
System.setProperty("https.proxyHost", "127.0.0.1");
System.setProperty("http.proxyPort", "8888");
System.setProperty("https.proxyPort", "8888");
When I execute my code with this included, I receive the following errors:
org.apache.jasper.JasperException: javax.xml.ws.WebServiceException: Failed to access the WSDL at: <wsdl_url>. It failed with:
Got sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target while opening stream from <wsdl_url>.
BUT in Fiddler I get an entry for the request that seems to not complete (sorry - new to Fiddler). The host is listed as "Tunnel to" and it is greyed out. In the Fiddler log I get this error:
!SecureClientPipeDirect failed: System.Security.Authentication.AuthenticationException A call to SSPI failed, see inner exception. < An unknown error occurred while processing the certificate on pipe to (CN=<wsdl_base_url>, O=DO_NOT_TRUST, OU=Created by http://www.fiddler2.com).
To me, it seems that I have the configuration correct for Fiddler and my proxy, but I am missing something in Java. I can't help but feel that I am missing a critical step here, so any advice would be greatly appreciated. Thanks!
EDIT: Do I need to generate new Java code using wsimport with the -httpproxy option set?

You need to add Fiddler's root certificate to the Java Key Store. Java does not use the system's certificate store, so the fact that Fiddler puts itself there doesn't solve the problem for you.
Get Fiddler's certificate by clicking Export Root Certificate from inside Tools > Fiddler Options > HTTPS. Then import the cert: http://azure.microsoft.com/en-us/documentation/articles/java-add-certificate-ca-store/#to-add-a-certificate-to-the-cacerts-store

Related

Java application show PKIX path building failed when calling external api

My application is running for fetch data from a website with https:
let say
https://api.something.com
When I call with Apache HttpClient using HttpClients.createDefault();
It return the above error show PKIX path building failed.
Even I use Postman to call the api. I still need to disable SSL certification verification to make the call success.
My question is:
Is this is a one way ssl verification? because I don't post data to that domain. I only pull data from it. So server don't have to know who I am. But I can know that's exactly the server I call, and api response is from that domain as well (no middle man). Is my concept correct?
So to resolve this problem, can I just use a dummy sslContext?
thanks a lot
Yes it may be one way TLS but you should have the certificate of CA that issued the certificate of your server in your trust store in java (or other client) to have SSL connection.

`p12` file work in Firefox RestClient but not work in WebSphere

I have a java web application that runs in WebSphere that need to call to third party service (IBM) to get some response.
At first IBM give me a p12 file, which is contain client certificate, and I test it in Firefox RestClient, the call success and I am getting response code 200 in the RestClient. Else, I will get 403 forbidden. So this is proof that the p12 provided by third party is correct. Please correct me if my statement is wrong.
Thus, I happily import this p12 file into my CellDefaultKeyStore to test the connection on my application. Unfortunately, after I import this p12 file, the nodes status become "unknown", and I cant even "synchronize" them. And when I check server log, I keep seeing
com.ibm.jsse2.util.j: PKIX path building failed: java.security.cert.CertPathBuilderException: PKIXCertPathBuilderImpl could not build a valid CertPath.; internal cause is:
java.security.cert.CertPathValidatorException: The certificate issued by xxx is not trusted; internal cause is:
java.security.cert.CertPathValidatorException: Certificate chaining error
After that I remove it from CellDefaultKeyStore try to import it into NodeDefaultKeyStore, the node issue gone, the node can sync back and my app can call to the third party successfully. I think this is done of my job today, however, this solution is not stable, its only work some times, not every time. The node status will still become "unknown" after a moment, or, if I run ./stopManager.sh and ./startManager.sh, the node issue will immediately come back.
I have try run ./stopNode.sh and ./startNode.sh, there are no error in the log of this 2 shell script. But the WAS Console UI there still showing status is unknown, and I cant even stop start my server through WAS Console.
At first I am thinking its maybe display issue, but this issue will solve if I delete the p12 file from my NodeDefaultKeyStore.
I try google around but end up still cant find any clue. I am not sure is it my configuration or the p12 file having problem.
Which log should I refer to see why the node status will become unknown, or what else I can continue to debug/troubleshoot on this?
You received the certificate for an external service and you want code in Websphere to connect to that service right? The default cell store is not the place to put external connection`s certificates.
Put it in the Trusted keystore. This will tell WebSphere to trust that external connections certificate, enabling your code to connect to it.
You can do it via the console, or using iKeyman directly on the file.
That being said, do not mess with the default certificate in the default keystore. #dbreaux is right on that in the comments.

Google Cloud Storage Client API fails in Certificate validation if we pass javax ssl params

I have successfully builded and ran a code snippet to upload the document to google cloud storage using the Java API. While integration of Google Sql to our project we have introduced the keystore and truststore params. After the introduction of the store params the upload document API's are failing with Certification related errors.
Dec 26, 2017 4:00:46 PM com.google.api.client.http.HttpRequest execute
WARNING: exception thrown while executing request
javax.net.ssl.SSLHandshakeException:
sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to
find valid certification path to requested target
Caused by: com.google.cloud.storage.StorageException: Error getting
access token for service account:
If we remove the javax ssl params the code is working as expected, Is it because Cloud storage Api's are using the cloud sql ssl certificates to connect to the storage ? If it is the case is there a way to skip checking of certificates in cloud storage API ? Or What is the best way to solve this issue ?
Yes, we had a very similar complex problem and it turned out to be MacAfee Web gateway (MWG) proxy configuration causing this issue. We noticed a strange behavior of the SSL certificate validation where it works from one process and gives an error from another process. It worked from straight command line Java execution but gave an error when we ran the same code through a container. We imported all the certs from accounts.google.com and *.googleapsi.com. We were clue less on what to do.
It looks that MacAfee Web gateway (MWG) proxy white list configuration is based on the client process(exe or script) name. MWG has default configuration to white list all HTTPS URLs for Java.exe process but not for other process (exe) names such as container(odi.exe). Because of this setting in MacAfee Web gateway proxy the command line Java code worked successfully and the same code from container gave error. We also noticed that if there is a proxy issued SSL cert for the HTTPS URL then SSL cert validation worked.

HTTPS (SSL) connections issue in Codename One

I'm now stuck with a HTTPS/SSL issue. I'm developing on Windows 10 / Java 8 v121 on Codename One.
When I tried to call a HTTP (without SSL) connection, I get rejected with a reference to [https://www.codenameone.com/blog/ios-http-urls.html]. I don't think the call even hit the server. I tried to include the "build hint" in my codenameone_settings.properties file but to no avail.
Next, I tried to use self-signed certificate and it generated a "Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target" exception. So, I thought the error was caused because my certificate was self-signed, but it wasn't...
Then I got a free certificate from [https://www.sslforfree.com/] and it is still causing the SAME exception message. However, this cerficate works fine with my Firefox browser. I'm also using Simple DNS Plus (for Windows) for the signed certificate domain name tested to work correctly in my Firefox browser (ie. correctly hit the server with no Insecure Connection message).
I'd like to understand how to:-
Get the "build hint" to work for iOS (in the Codename One simulator) so it calls http (without ssl) connections.
How to resolve the Java exception.
Thanks!
Just use http URL during the development stage and when you are ready to publish, buy a genuine SSL certificate and change the http to https. It's for your own good, as unencrypted Webservice call will make your app vulnerable to a man-in-middle attack.
To make your http work on iOS during dev stage, add this build hint:
ios.plistInject=<key>NSAppTransportSecurity</key><dict><key>NSAllowsArbitraryLoads</key><true/></dict><key>CFBundleURLTypes</key><array><dict><key>CFBundleURLName</key><string>com.mycompany.myapp</string></dict><dict><key>CFBundleURLSchemes</key><array><string>MyApp</string></array></dict></array>
There was a similar question previously which I answered here.

Trouble with securing a Tomcat/Axis2 web service via SSL

I have successfully built a working web service, client, and .jsp-driven UI. I did this with Eclipse, Axis2, Tomcat 7, and Java 7.
The basic flow is that the user visits the .jsp and submits a form with input data. The JSP forwards the "request" object to the Java client. The Java client consumes the web service and submits the user input. The service connects to a SQL Server database via JDBC to retrieve information, which is displayed back to the user.
This all works perfectly over HTTP, but now I want to secure the process, and this is where I'm running into problems. I'm able to create a cert and get Tomcat to use it. I can connect to the web UI via HTTPS and submit the form and get data back just fine. The problem is that this is only securing the front-end. The web service client code is still connecting to the service via HTTP in the background.
According to this page, all I really need to do to enable my service for connections via SSL is to update the axis2.xml file and include a new "transportReceiver" node for HTTPS. I did that and regenerated my client code to use the secure endpoint. It doesn't work.
I have configured Tomcat to listen on ports 8081 for http and 8443 for https. But after changing axis2.xml to match, and starting up Tomcat, I get the following:
[INFO] Listening on port 8443 [ERROR] Terminating connection
listener
org.apache.axis2.transport.http.server.DefaultConnectionListener#16d60567
after 10retries in 0 seconds. java.net.BindException: Address already
in use: JVM_Bind at java.net.DualStackPlainSocketImpl.bind0(Native
Method) at java.net.DualStackPlainSocketImpl.socketBind(Unknown
Source) at java.net.AbstractPlainSocketImpl.bind(Unknown Source) at
java.net.PlainSocketImpl.bind(Unknown Source) at
java.net.ServerSocket.bind(Unknown Source) at
java.net.ServerSocket.(Unknown Source) at
java.net.ServerSocket.(Unknown Source) at
org.apache.axis2.transport.http.server.DefaultConnectionListener.run(DefaultConnectionListener.java:80)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
I have tried changing the port number in axis2.xml (for example, to 8445), and that sort of works. The server is able to start cleanly, but eventually, the same errors start showing up. For example, when I retrieve the WSDL, I see the error via the console (though the WSDL does show up). Also, if I try to actually use the service when on port 8445, I get the following error:
org.apache.axis2.AxisFault: Connection has been shutdown:
javax.net.ssl.SSLException: Unrecognized SSL message, plaintext
connection?
I can only assume this is because Tomcat is configured to handle HTTPS on 8443, not 8445, but I honestly don't know.
If I leave the port as 8443 and ignore the errors at startup, I get the following message when I connect to the service:
org.apache.axis2.AxisFault: Connection has been shutdown:
javax.net.ssl.SSLHandshakeException:
sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to
find valid certification path to requested target
I followed these steps to try to get it to recognize my certificate, but when importing it into my JRE7 keystore, I get the following:
keytool error: java.lang.Exception: Certificate reply and certificate
in keystore are identical
Basically, that cert is already there. Which makes sense, because it's the one that Tomcat is already using successfully.
So, I'm pretty clueless at this point. I'm really not sure what I'm supposed to be doing. Any general guidance, or a link to a step-by-step how-to would be really helpful.
But for a specific question... What, exactly, am I doing when I set the transportReceiver nodes in axis2.xml? Am I telling it what ports Tomcat is running on and that it should use, or does Axis2 have its own servers that will start on those ports? It seems to be the latter, but that doesn't make a whole lot of sense to me.
The correct way to configure the servlet transport is described in the Axis2 documentation. The symptoms you are describing suggest that you have a transportReceiver that refers to org.apache.axis2.transport.http.SimpleHTTPServer. Please also make sure that you use a recent version of Axis2 (1.5.6 or 1.6.1).
See Andreas's response for the port issue. As for the certificate issue, it was a misunderstanding on my part over the distinction between a keystore and truststore. The JVM defaults to using JAVA_HOME\lib\security\cacerts as its trust store, rather than the USER_HOME\.keystore file. Once I imported my certificate there, the errors went away.
I was also able to resolve the certificate problems by explicity setting the trust store to be the key store file, via code. I did this before importing the certificate into the cacerts store. It goes in the client code, right before invoking the service:
System.setProperty("javax.net.ssl.trustStore","C:\\path\\to\\.keystore");
System.setProperty("javax.net.ssl.trustStorePassword","password");
One of the way to connect to HTTPS is using jax-ws
E:\WSDL>wsimport -keep -p com.mypack.webservice https://domain:port/ws/MyService?wsdl
This will generate package structure under the wsdl folder. Use it.
Now all you have to do is put trust store in run.bat or use System class to set property.
It will work fine.

Categories

Resources