简体   繁体   中英

javax.xml.ws.Service to consume SOAP service via SSL

I want to consume a SOAP service via HTTPS. I have written a client to do that. I didn't use automatic class generation because the target service runs on multiple systems so the service URL changes during runtime.

This is the implementation using JAX-WS:

public class SAPClient implements Callable<...> {

private Service service = null;
private SOAPMessage response = null;
private boolean submitted = false;
private boolean successfull = false;
private QName serviceName;
private QName portName;
private SAPResult result = new SAPResult();
private Dispatch<SOAPMessage> dispatch = null;
private SOAPBody resBody = null;
private SapConnector connector;

public SAPClient(EricAgent agent, SapConnector connector) {
    this.connector = connector;
    serviceName = new QName(connector.getUrl(), Environment.SAP_CLIENT_SERVICE_NAME);
    portName = new QName(connector.getUrl(), Environment.SAP_CLIENT_PORT);
    this.service = Service.create(serviceName);
    service.addPort(portName, SOAPBinding.SOAP11HTTP_BINDING, connector.getUrl());
    this.successfull = false;
}

(...)

public synchronized void invoke() throws SOAPException {
    try {
        dispatch = service.createDispatch(portName, SOAPMessage.class, Service.Mode.MESSAGE);

        MessageFactory mf = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
        SOAPMessage message = mf.createMessage();
        SOAPPart part = message.getSOAPPart();
        SOAPEnvelope env = part.getEnvelope();
        SOAPBody body = env.getBody();

        SOAPElement operation = body.addChildElement(
                Environment.SAP_CLIENT_OPERATION_NAME,
                Environment.SAP_CLIENT_TARGET_NAMESPACE.getPrefix(),
                Environment.SAP_CLIENT_TARGET_NAMESPACE.getURI());

        // Add ticket
        SOAPElement ticketValue = operation.addChildElement("ITicket");
        ticketValue.addTextNode(...);

        // Add "Informationsprotokoll"
        String resultString = buildEricResultString(agent);
        SOAPElement xmlValue = operation.addChildElement("IXml");
        xmlValue.addTextNode(resultString);
        message.saveChanges();

        Response<SOAPMessage> sapResponse = dispatch.invokeAsync(message);

        long waitingTime = 0;

        while (true) {
            if (waitingTime > Environment.SAP_CLIENT_TIME_OUT) {
                //... handle timeout
            }

            if (sapResponse.getContext() != null) {
                Environment.LOGGER.debug("got response");
                response = sapResponse.get();
                submitted = true;
                successfull = result.returnCode.equals("0");

                //...

                break;
            }

            wait(1000);
            waitingTime += 1000;
        }
    } catch (Throwable ex) {
        Environment.LOGGER.error(null, ex);
        this.submitted = false;
        this.successfull = false;
    }
}

}

I want to consume this service via SSL now. Can you explain me how I tell the Service class to use a specific certificate? How do I pass the keystore for example... I googled around and didn't find satisfying results. Thanks in advance!

UPDATE 1:

By adding:

    System.setProperty("javax.net.ssl.keyStore", certPath);
    System.setProperty("javax.net.ssl.keyStorePassword", certPass);

I could get SSL to work - thanks zuxqoj!

The output looked liked this and the connection timed out:

keyStore type is : jks
keyStore provider is : 
init keystore
init keymanager of type SunX509
trustStore is: ***
trustStore type is : jks
trustStore provider is : 
init truststore
adding as trusted cert:
  Subject: CN=***, OU=I0020498236, OU=SAP Web AS, O=SAP Trust Community, C=DE
  Issuer:  CN=***, OU=I0020498236, OU=SAP Web AS, O=SAP Trust Community, C=DE
  Algorithm: RSA; Serial number: 0x20120718050810
  Valid from Wed Jul 18 07:08:10 CEST 2012 until Fri Jan 01 01:00:01 CET 2038

trigger seeding of SecureRandom
done seeding SecureRandom
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256

To get pass the timeout I had to pass this property to the JVM and the http(s) request went through:

-Djava.net.preferIPv4Stack=true

add this to your code before SOAP call

System.setProperty("javax.net.ssl.keyStore",certificatePath);
System.setProperty("javax.net.ssl.keyStorePassword", certificatePassword));
System.setProperty("javax.net.ssl.keyStoreType", "JKS");

you can download .cer certificate from server url and convert it into jks using command

keytool -importcert -file certificate.cer -keystore keystore.jks -alias "Alias"

now you need certificate corresponding to each target server and in your system somewhere you need to maintain mapping between server url and certificate

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM