1

I need to create a Java client that consumes a soap webservice using https.

I can get authorization to work and I can download the wsdl file by issuing this command from a command line:

wget --certificate=undisclosed.crt.pem https://service.an-organization.com/foo/bar?wsdl

(Not really, the example has been obfuscated a bit)

My problem is that I have a hard time to find a Java example I can use to get the same thing working from a Java client. I'm currently not certain how the certificate should be handled. I am sure that I don't want to fiddle with the keystore and instead supply the certificate programatically.

The ultimate goal is to use some generated stubs that extends javax.xml.ws.Service. Such an example would be wonderful. But I would be more than happy with a vanilla Java client that was able just to download the wsdl file like I'm able to do using wget.

Please include any imports as well as any Maven coordinates if you use a library.

Thomas Sundberg
  • 4,098
  • 3
  • 18
  • 25
  • I'm afraid you MUST fiddle with the keystore. I have never seen an alternative in the Java world. Your best chance is to import the certificate into a keystore (existing or newly generated) and to use that keystore in the java command line parameters. Something along the lines of what's described here: https://stackoverflow.com/questions/875467/java-client-certificates-over-https-ssl – Alin Pandichi Feb 06 '18 at 15:43
  • Have a look at this https://stackoverflow.com/questions/11001102/how-to-programmatically-set-the-sslcontext-of-a-jax-ws-client – Bogdan Feb 06 '18 at 17:10

2 Answers2

0

I've had best success here with actually creating a keystore file to authenticate my client class (and/or truststore to trust the server) but then load it programmatically, rather than as a system property for the JVM.

So, step one, import your private key and certificate into a keystore (sigh... painful, but only done once, at least), and then step two, do something like this (this uses Spring for some parts):

/**
 * Loads an SSL context given the specified properties.
 *
 * @return An SSL context created using the given keystore and truststore properties
 * @throws KeyManagementException
 */
@Bean
public SSLContext getSSLContext() throws KeyManagementException{
    SslConfigurator sslConfig = SslConfigurator.newInstance();
    if(!this.trustStore.isEmpty()){
        sslConfig
                .trustStore(loadKeyStore(this.trustStore, this.trustStoreType, this.truststorePassword))
                .trustStorePassword(this.truststorePassword);
    }
    if(!this.keyStore.isEmpty()){
        sslConfig
                .keyStore(loadKeyStore(this.keyStore, this.keystoreType, this.keystorePassword))
                .keyStorePassword(this.keystorePassword);
    }

    return sslConfig.createSSLContext();
}
/**
 * Loads a keystore from the classpath
 * @param name the name of the keystore resource
 * @param type the type of the keystore
 * @param password the password of the keystore
 * @return the keystore
 */
private KeyStore loadKeyStore(String name, String type, String password) {
    try {
        KeyStore keyStore = KeyStore.getInstance(type);
        keyStore.load(this.applicationContext.getResource(name).getInputStream(), password.toCharArray());
        return keyStore;
    } catch (Exception e) {
        throw new InvalidValueException("Could not read keystore", e);
    }
}
Daniel Lundmark
  • 2,370
  • 16
  • 11
0
//import cert into jdk using cmd key tool command (google it)

import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPMessage;
  
public SOAPMessage send(SOAPMessage requestMessage, String url) throws Exception {

    System.setProperty("javax.net.ssl.keyStore", "C:\\cert.jks");
    System.setProperty("javax.net.ssl.keyStorePassword", "password");
    System.setProperty("javax.net.ssl.trustStore", "cacerts");
    System.setProperty("javax.net.ssl.trustStorePassword", "password");

    // CreateApplication SOAP Connection
    SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
    SOAPConnection soapConnection = soapConnectionFactory.createConnection();

    // Send SOAP Message to SOAP Server
    SOAPMessage soapResponse = soapConnection.call(requestMessage, url);

    // print SOAP Response
    System.out.print("Response SOAP Message:");
    soapResponse.writeTo(System.out);
    soapConnection.close();

    return soapResponse;
}
Neuron
  • 5,141
  • 5
  • 38
  • 59