1

Am bit similar situation as explained in this question. I also have a WSDL at a particular link. When I open that link I get the There is a problem with this website's security certificate... error in IE. When I click continue it opens up WSDL file.

Now I am writing a client for this webservice in Java. And it throws following exception:

Exception in thread "main" com.sun.xml.internal.ws.wsdl.parser.InaccessibleWSDLException: 2 counts of InaccessibleWSDLException.

java.io.IOException: Got java.security.cert.CertificateException: No subject alternative names matching IP address 172.17.245.196 found while opening stream from https://172.17.245.196/ews/Services.wsdl
java.io.IOException: Got java.security.cert.CertificateException: No subject alternative names matching IP address 172.17.245.196 found while opening stream from https://172.17.245.196/ews/Services.wsdl?wsdl
    at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.tryWithMex(Unknown Source)
    at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(Unknown Source)    
    at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(Unknown Source)
    at com.sun.xml.internal.ws.client.WSServiceDelegate.parseWSDL(Unknown Source)
    at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(Unknown Source)
    at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(Unknown Source)
    at com.sun.xml.internal.ws.spi.ProviderImpl.createServiceDelegate(Unknown Source)
    at javax.xml.ws.Service.<init>(Unknown Source)
    at com.microsoft.schemas.exchange.services._2006.messages.ExchangeWebService.<init>(ExchangeWebService.java:58)
    at com.xyz.cms.EWSJavaAPI.ExchangeAuthenticator.getExchangeServicePort(ExchangeAuthenticator.java:32)
    at com.xyz.cms.test.ExchangeDevelopmentTest.main(ExchangeDevelopmentTest.java:31)

So I guess it is related to resolving certificates and since the guy on the said thread got similar exception, I am trying out the solution suggested there - downloading and adding the certificate to the private using keytool.exe, though I really dont think I have completely understood this certificate stuff and also keytool.

So I

  • Downloaded the certificate by visiting the link in browser and then copy pasted it in app directory in eclipse.
  • Also I copy pasted $JAVA_HOME/lib/security/cacerts to my app directory. So by now my app hierarchy looks something like this in eclipse: enter image description here
  • Then opened command prompt and navigated to the app directory.
  • Finally executed the command (as suggested in that thread). It gave me following output. It gave me following output enter image description here

However it is giving me exactly the same exception. What should I do?

Edit

Well this is my effort to write java client for Exchange Web Services. Their is ExchangeAuthenticator which manages web services authentication requests to the Exchange and ExchangeDevelopmentTest which contains main method to test functionality of above class. a Here is the code:

ExchangeAuthenticator

public class ExchangeAuthenticator {    
/**
 * Obtains an authenticated ExchangeServicePortType with given credentials.
 *     
 */
    public ExchangeServicePortType getExchangeServicePort(String username, String password, String domain, URL wsdlURL) throws MalformedURLException {
        // Concatinate our domain and username for the UID needed in authentication.
        String uid = "domain" + "\\" + "uname";

        // Create an ExchangeWebService object that uses the supplied WSDL file, wsdlURL.
        ExchangeWebService exchangeWebService = new ExchangeWebService(wsdlURL, new QName("<a href=\"http://schemas.microsoft.com/exchange/services/2006/messages\">http://schemas.microsoft.com/exchange/services/2006/messages</a>", "ExchangeWebService"));
        ExchangeServicePortType port = exchangeWebService.getExchangeWebPort();
        // Supply your username and password when the ExchangeServicePortType is used for binding in the SOAP request.
        ((BindingProvider)port).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, uid);
        ((BindingProvider)port).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, password);

        return port;
    }
}

ExchangeDevelopmentTest

public class ExchangeDevelopmentTest {    
    public static void main (String[] args) {
        ExchangeAuthenticator exchangeAuthenticator = new ExchangeAuthenticator();

        // Print statement so we can easily see where our statements start in the Java console.
        System.out.println("Let's get started!");

        try {
            // Create a URL object which points at the .wsdl we deployed in the previous step.
            URL wsdlURL = new URL("https://172.17.245.196/ews/Services.wsdl");
            //URL wsdlURL = new URL("<a href=\"https://172.17.245.196/ews/Services.wsdl\">https://172.17.245.196/ews/Services.wsdl</a>");
            // Call to the class we just created to return an ExchangeServicePortType with authentication credentials.
            ExchangeServicePortType port = exchangeAuthenticator.getExchangeServicePort("uname", "password@123", "domain", wsdlURL);

            // Prints out the default toString() for the ExchangeServicePortType.
            System.out.println(port.toString());
        } catch (MalformedURLException ex) {
            // Catch any errors that may occur.
            Logger.getLogger(ExchangeDevelopmentTest.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println(ex.getMessage()+"\n"+ex.getStackTrace());
        }
    }
}
Community
  • 1
  • 1
Mahesha999
  • 22,693
  • 29
  • 116
  • 189
  • I think you're forgetting to tell your connection to trust the new keystore. Post up the code you're using to fetch the wsdl. – tom Oct 03 '13 at 13:55
  • Exactly the same problem as [here](http://stackoverflow.com/a/8444863/372643): it's the server certificate that's incorrect (or you should use it by its name, not by its IP address). – Bruno Oct 03 '13 at 14:06
  • @tom updated question to include the code – Mahesha999 Oct 03 '13 at 14:11

1 Answers1

3

The problem is that your certificate is not issued for 172.17.245.196 IP address, so the client used to parse WSDL does not trust it. That IP address shall be in subject field of the certificate.

Is your certificate trusted by official certification authority or is it self signed? Probably you will need Java to trust it. Add it to keystore and then set system properties:

System.setProperty("javax.net.ssl.keyStore", "lfkeystore2");
System.setProperty("javax.net.ssl.keyStorePassword", "wshr.ut");
Leos Literak
  • 8,805
  • 19
  • 81
  • 156
  • You mean that in command prompt `keytool` output should have `172.17.245.196` for `SubjectAlternativeName` ? – Mahesha999 Oct 03 '13 at 14:09
  • Yes, and of type "IP address" not "DNSName". That's only if you want to use an URL with an IP address. You could of course use an URL with the existing DNS SAN (if it resolves to that IP address, of course). – Bruno Oct 03 '13 at 14:12
  • ohkay but then why its not there, I mean why it is showing DNSName not IP address - and what should be done to get it that way? - I might be sounding stupid – Mahesha999 Oct 03 '13 at 14:14
  • When I ping to that name it gets resolved to the IP address I specified in the code. Is that ok? – Mahesha999 Oct 03 '13 at 14:16
  • It's just that the server is not configured to be used by its IP address using an HTTPS URL. That's very common (and sensible). Use its name instead. – Bruno Oct 03 '13 at 14:25
  • Ohkay I tried by changing `172.17.245.196` in my code with the name and it gave me different exception `java.io.IOException: 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 https://site.domain.com/ews/Services.wsdl` Also I can hit the WSDL by both IPs and name too: `https://172.17.245.196/ews/Services.wsdl` and `https://site.domain.com/ews/Services.wsdl` – Mahesha999 Oct 03 '13 at 14:30
  • @LeosLiterak Thanks for reply. I tried adding those two lines. If I remove those lines I used to get `401: Unauthorized` error, but with those two lines added now am getting `java.security.NoSuchAlgorithmException`. Am not able to figure out if this is new problem or same, but if am not getting `401` then certificate must have worked. But then whats wrong now? Thinking that its different issue I created a new question for it [here](http://stackoverflow.com/questions/19177704/java-security-nosuchalgorithmexception-while-accessing-wsdl-in-java-web-service). – Mahesha999 Oct 04 '13 at 09:45
  • Have you inserted your new certificate into keystore and updated values in my sample to match your environment? If you are new to PKI, google for importing certificates, keystore and SSL. It is quite complex area and your shall understand the background first, otherwise it will be very painfull for you to set it up. – Leos Literak Oct 04 '13 at 09:52
  • Is there any source/site/tut that explains all this all at one place? I was thinking to read [JSSE Ref Guide](http://docs.oracle.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html). But its damn big and be a bit irrelevant. – Mahesha999 Oct 04 '13 at 11:34