Link to home
Start Free TrialLog in
Avatar of prohacx
prohacx

asked on

Calling HTTPS webservices using Axis and Soap

Hi,

I'm pretty new in this webservice thing and I want to call a webservice deployed over HTTPS.

My current code is like so:

        System.setProperty("javax.net.ssl.trustStore", "CustomKeyStore");
        System.setProperty("javax.net.ssl.trustStorePassword", "littlesecret");
       
      String endpoint = "https://brsla-cadev-vm3/axis/services/USD_R11_WebService?wsdl";
       
      String user = "someuser";
      String pwd = "somepassword";

      try
      {
        
            // create a new web service stub instance
          USD_WebServiceLocator ws = new USD_WebServiceLocator();
          java.net.URL url = new java.net.URL(endpoint);
        
          USD_WebServiceSoap usd = ws.getUSD_WebServiceSoap(url);
           
           
            // login to server
            int sid = usd.login(user, pwd);


When deploying the service over HTTP I don't have any problems and can access all methods of the web service. However, over HTTPS, I keep on getting Java errors.

I already created a keystore and it looks like the code has no problems accessing that. However, now I run in errors like this:

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

All I'm looking for is a simple example of calling a method over HTTPS, but I seem to be unable to find that anywhere. Kind of stuck here....

Can anyone help me please?

Thanks in advance!
Avatar of Mayank S
Mayank S
Flag of India image

>> System.setProperty("javax.net.ssl.trustStore", "CustomKeyStore");

Where is CustomKeyStore located? Is it in the same directory as the main class running your application?
Avatar of prohacx
prohacx

ASKER

I'm using netbeans IDE and set a working directory for the project. The CustomKeyStore file is located there.
I'm pretty sure the code can find it now, because I used to have another problem before that was caused because the file could not be found.

My main problem is that I have no clue on how this Axis stuff works (in the docs they talk about factories and other stuff). An example code would be really great. I'm really confused because of the difference in a simple call over HTTP (which I got to work quite easily) and the trouble I'm having to make it work over HTTPS.
ASKER CERTIFIED SOLUTION
Avatar of Mayank S
Mayank S
Flag of India image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of prohacx

ASKER

Hi Manyankeagle:

the code finds the certificate all right, but I still get this error now:

java.net.SocketException: Default SSL context init failed: DerInputStream.getLength(): lengthTag=109, too big.

My code is now this:

        System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
        Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
        System.setProperty("javax.net.ssl.keyStoreType", "PKCS12"); // pkcs12 JKS
       
        System.setProperty("javax.net.ssl.keyStore", "vm3KeyStore");
        System.setProperty("javax.net.ssl.keyStorePassword", "littlesecret");

        com.sun.net.ssl.HostnameVerifier hv=new com.sun.net.ssl.HostnameVerifier() {
        public boolean verify(String urlHostname, String certHostname) {
            System.out.println("urlHostname >>" + urlHostname +"<<");
            System.out.println("certHostname >>" + certHostname +"<<");
            System.out.println("WARNING: Hostname is not matched for cert.");
            return true;
        }
        };
        com.sun.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(hv);

       
      // The endpoint for the R11 web service
      String endpoint = "https://brsla-cadev-vm3/axis/services/USD_R11_WebService?wsdl";
       
      //  Assume user and password are both "ServicePlus"
      String user = "someuser";
      String pwd = "somepassword";

      try
      {
        
            // create a new web service stub instance
          USD_WebServiceLocator ws = new USD_WebServiceLocator();
          java.net.URL url = new java.net.URL(endpoint);
        
          USD_WebServiceSoap usd = ws.getUSD_WebServiceSoap(url);
           
           
            // login to server
            int sid = usd.login(user, pwd);


Does anyone know where this error comes from? I read on the internet that keytool.exe can add an extra line break to the .cer file. I even deleted that extra line before creating the vm3Keystore and still I get this error.

Thanks again for all your efforts!
Avatar of prohacx

ASKER

Found my problem!

As I said I clearly did not understand this certificate stuff good enough...

The keystore I initially had was imported from a certificate I created myself. This was different from the certificate that was running on the server. I thought any valid certificate would do, but clearly you need to use the one that is installed on the server (yes, you can stop laughing now ;).

So... to make a long story short: browse (in IE) to the WSDL URL, view the certificate, go to the details tab, click "copy to file" and save as .cer

Then, use keytool to create the keystore. Move the keystore to where you want to call it.

Use following code to make it work:

        System.setProperty("javax.net.ssl.trustStore", "c:\\...\\myKeyStore");
        System.setProperty("javax.net.ssl.trustStorePassword", "password");

if you have problems, System.setProperty("javax.net.debug", "all" ); can help to understand the process better.
Avatar of prohacx

ASKER

Although I mostly found the solution myself, reading the document provided by Mayankeagle explains it all. So, thanks for the info!
>> This was different from the certificate that was running on the server.

Well, oh :) they have to be the same otherwise how would you authenticate :) ?
Just like the password you type at the client-side for logging on to a website has to be same as the password stored on the server :)