简体   繁体   English

javax.xml.ws.Service通过SSL使用SOAP服务

[英]javax.xml.ws.Service to consume SOAP service via SSL

I want to consume a SOAP service via HTTPS. 我想通过HTTPS使用SOAP服务。 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. 我没有使用自动类生成,因为目标服务在多个系统上运行,因此服务URL在运行时会更改。

This is the implementation using JAX-WS: 这是使用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. 我现在想通过SSL使用此服务。 Can you explain me how I tell the Service class to use a specific certificate? 您能解释一下我如何告诉Service类使用特定证书吗? How do I pass the keystore for example... I googled around and didn't find satisfying results. 例如,如何传递密钥库...我在Google周围搜索,但未找到满意的结果。 Thanks in advance! 提前致谢!

UPDATE 1: 更新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! 我可以使用SSL,谢谢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: 要获得超时,我必须将此属性传递给JVM,并且http(s)请求通过了:

-Djava.net.preferIPv4Stack=true

add this to your code before SOAP call 在SOAP调用之前将其添加到您的代码中

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 您可以从服务器URL下载.cer证书,并使用命令将其转换为jks

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 现在,您需要与每个目标服务器相对应的证书,并且在系统中的某个位置,您需要维护服务器url和证书之间的映射

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 NoClassDefinitionFound:javax.xml.ws.Service - NoClassDefinitionFound: javax.xml.ws.Service 如何通过javax.xml.ws.Service进行调用 - How to do a call through a javax.xml.ws.Service 实例化Springboot javax.xml.ws.service NullpointerException - Springboot javax.xml.ws.service Nullpointerexception while instantiating it javax.xml.ws.Service 构造函数不返回 - javax.xml.ws.Service constructor does not return App Engine上的javax.xml.ws.Service初始化错误 - Error in javax.xml.ws.Service initialization on App Engine 重用javax.xml.ws.Service对象是否安全? - Is it safe to reuse javax.xml.ws.Service objects? 在 weblogic 12.2.1.3 上创建 javax.xml.ws.Service 实例时出现 NullPointerException - NullPointerException when creating instance of javax.xml.ws.Service on weblogic 12.2.1.3 javax.xml.ws.Service无法读取wsdlDocumentationLocation,该文件声明为URL(&#39;file:Authentication.wsdl&#39;) - javax.xml.ws.Service could not read wsdlDocumentationLocation which is declare as URL('file:Authentication.wsdl') 超级调用javax.xml.ws.Service期间出现“找不到符号”错误 - 'cannot find symbol' error during super call to javax.xml.ws.Service javax.xml.ws.Service在构造函数中失败,因为站点具有用户名/密码 - javax.xml.ws.Service fails in constructor because site has username/password
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM