How to use wsimport when server expects client certificate?
Asked Answered
L

3

10

I have a web service using mutual SSL authentication. I can access it just fine in the browser when I have the client's certificate installed.

I need to be able to access this using wsimport for generating the Java code to access the service.

How can I set up my credentials so that I may access the URL using wsimport?

Here's an example of what I'm trying, but it times out due to the inability to authenticate.

wsimport ./sample.wsdl -p com.company.ws.sample -Xnocompile -d ./src -extension -keep -XadditionalHeaders

Thanks for any help

Edit:

This is what wsimport prints. The WSDL is definitely valid, and at the given location, it's a matter of figuring out how to pass in my credentials for authenticating:

wsimport https://wsdl.location.com?WSDL -p com.company.ws.sample -Xnocompile 
-d ./src -extension -keep -XadditionalHeaders


parsing WSDL...

[ERROR] Received fatal alert: handshake_failure

Failed to read the WSDL document: "https://wsdl.location.com?WSDL", because 1) could 
not find the document; /2) the document could not be read; 3) the root element of 
the document is not <wsdl:definitions>.

[ERROR] failed.noservice=Could not find wsdl:service in the provided WSDL(s): 

 At least one WSDL with at least one service definition needs to be provided.

    Failed to parse the WSDL.
Larkin answered 7/8, 2012 at 14:36 Comment(3)
sharing the error/exception stacktrace you faced helps others to understand the problem.Laurustinus
I've updated the post to show more details. ThanksLarkin
ibswings.blogspot.in/2008/12/… try thisLaurustinus
G
13

You can call directly the WsImport java class (source) and add the JVM necessary args for Java knowing where to look for client certificates.

Something like

java -classpath C:\jdk160_29\lib\tools.jar -Djavax.net.ssl.trustStore=c:\jdk160_29\.mykeystore com.sun.tools.internal.ws.WsImport https://host:8443/Webservice?wsdl -p com.test -s ./src"

should do the trick.

Groh answered 29/11, 2012 at 16:31 Comment(1)
Failed for me with a Exception in thread "main" java.lang.NoSuchFieldError: theInstance, however I've found an alternative.Sunlight
S
4

I managed to do this by setting the _JAVA_OPTIONS environment variable with all the extra system properties to pass through; as a Windows batch file it looks like this (putting your password in as appropriate:

setlocal
set _JAVA_OPTIONS=%_JAVA_OPTIONS% -Djavax.net.ssl.trustStore="%JAVA_HOME%\jre\lib\security\cacerts" -Djavax.net.ssl.keyStoreType=PKCS12 -Djavax.net.ssl.keyStorePassword={...passwordForThePFX...} -Djavax.net.ssl.keyStore=r:\cert.pfx
wsimport -s . -verbose https://your.host.name/path/to/service?wsdl
endlocal

For sanity's sake, the Java options in the long 'set' line are:

-Djavax.net.ssl.trustStore="%JAVA_HOME%\jre\lib\security\cacerts"
-Djavax.net.ssl.keyStoreType=PKCS12
-Djavax.net.ssl.keyStorePassword={...passwordForThePFX...}   
-Djavax.net.ssl.keyStore=R:\cert.pfx

You may or may not need to specift the trustStore setting; I had to as I've got a couple of installs on and Java was picking up the wrong cacerts file for me.

Similarly you won't need the keyStorePassword if the keystore isn't password protected. As for keyStoreType, you'll need to specify this if you're not accessing a Java keystore.

Ultimately, the only "mandatory" option is the keyStore which defines where the client certificate and keys live (and it's only mandatory if the client certificate isn't in any of the core Java certificate stores). As it stands, the example above is for a client certificate in a PFX file generated by exporting it from the Windows certificate store.

Sunlight answered 14/10, 2013 at 15:29 Comment(1)
Thanks for this. In my case, I also needed to include -Djavax.net.ssl.trustStorePasswordCilo
A
2

I found much easier (no need to play with -D, classpath, ...) to:
1. download the wsdl via ssl with your browser (install the certificate in your default browser by double-click on the keystore) or even easier with soapUI (install the keystore via config/ssl) that shows the wsdl contents
2. run the wsimport against the downloaded wsdl
That's all.

Amalburga answered 28/10, 2014 at 8:28 Comment(1)
One should add the option -wsdllocation <actualWsdlLocationURI> to wsimport because otherwise the generated webservice classes will point to the absolute local path of the wsdl.Forby

© 2022 - 2024 — McMap. All rights reserved.