从 Apache CXF 访问 WCF Web 服务(MTOM + WS-Security)

发布于 2025-01-03 10:29:49 字数 17727 浏览 3 评论 0 原文

我已经为这个问题苦苦挣扎了很长一段时间,尽管到处寻找,但仍无法解决。

场景详细信息(代码、配置和其他内容发布在最后):

  1. WCF Web 服务 (.NET 4),公开两个端点:一个不安全,一个使用消息安全和用户名身份验证(使用成员资格基础结构)进行保护 - 无传输安全。
  2. 两个端点都使用MTOM编码; WSDL 引用的所有类都用 MessageContract 属性标记,并且用 MessageBodyMember 属性标记成员。
  3. WCF 绑定上的配置将“assetSecurityContext”和“negotiateServiceCredential”设置为 false。
  4. WCF 服务使用自签名证书进行保护以进行加密。
  5. 尝试使用 Apache CXF 2.5.1 从 Java 客户端进行访问。我已将证书设置到可从类路径访问的 KeyStore 中。

结果:

  1. 从 .NET 客户端访问 Web 服务工作正常
  2. 从 Apache CXF 访问不安全的端点,无论是否使用 MTOM 编码,都工作正常。
  3. 从 Apache CXF 访问安全端点(没有 MTOM)效果很好。 CXF追踪表明加解密过程正常进行。
  4. 一旦在WCF中激活MTOM,问题就出现了。我们能够确定在 WCF 端,消息的接收、消息的处理以及响应的生成/加密正常发生。
  5. 问题发生在CXF接收消息的过程中。我们认为 CXF 在尝试解密消息之前没有正确反序列化 MTOM 附件;因此,解密逻辑发现消息在响应中仍然有一个要解密的元素,但发现一个空元素要解密并失败。我们尝试添加 RECEIVE 阶段拦截器来初始化附件,但无济于事(尝试在多部分响应中找到边界标记失败)。
  6. 使用 Fiddler,我们发现响应看起来格式良好,并带有一个引用

CODE/CONFIG/STUFF 的附件:

Web.Config(为清楚起见而缩短):

  <system.serviceModel>
    <!-- Services -->
    <services>
      <service name="TestServices.Services.TestService" behaviorConfiguration="TestService.Basic">
        <!-- Plain (unsecured) endpoint -->
        <endpoint address="" binding="wsHttpBinding" bindingConfiguration="TestService.Basic" name="TestService.Basic"
                  contract="TestServices.Interfaces.ITestService" bindingNamespace="http://searchtechnologies.com/cpa/wcfinterop"/>
        <!-- Secure endpoint -->
        <endpoint address="/secure" binding="wsHttpBinding" bindingConfiguration="TestService.Secure" name="TestService.Secure"
                  contract="TestServices.Interfaces.ITestService" bindingNamespace="http://searchtechnologies.com/cpa/wcfinterop"/>
      </service>
    </services>
    <!-- Bindings -->
    <bindings>
      <wsHttpBinding>
        <binding name="TestService.Basic" messageEncoding="Mtom">
          <security mode="None">
            <message clientCredentialType="None"/>
            <transport clientCredentialType="None"/>
          </security>
        </binding>
        <binding name="TestService.Secure" messageEncoding="Mtom">
          <security mode="Message">
            <message clientCredentialType="UserName" establishSecurityContext="false" negotiateServiceCredential="false"/>
            <transport clientCredentialType="None"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <!-- Behaviors -->
    <behaviors>
      <serviceBehaviors>
        <behavior name="TestService.Basic">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
          <serviceCredentials>
            <serviceCertificate storeName="My" storeLocation="LocalMachine" x509FindType="FindBySubjectName" findValue="equiros-PC2.search.local"/>
            <userNameAuthentication userNamePasswordValidationMode="MembershipProvider" membershipProviderName="SqlProvider"/>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>

Java 客户端代码(为清楚起见省略了部分):

  private static void secureTest() {
    try {
      logger.debug("Secure test starting. Instatiating service");
      // service instantiation
      TestService service = new TestService();
      ITestService port = service.getTestServiceSecure();
      // request creation
      BasicRequest request = objectFactory.createBasicRequest();
      request.setStringData("String data");
      request.setIntegerData("Integer data");
      // setup logging
      setupInterceptors(port);
      // setup security & binding
      setupBinding(port);
      // service call
      logger.debug("Attempting service call");
      BasicResponse response = port.simpleOperation(request);
      logger.debug("Call success!!!");
      logger.debug(String.format("Response data: str: %1$s; int: %2$s",
          response.getStringData(), response.getIntegerData()));
    } catch (Exception e) {
      logger.error("Error during service invocation", e);
    }
  }

  private static void setupInterceptors(ITestService port) {
    Client proxy = JaxWsClientProxy.getClient(port);
    proxy.getInInterceptors().add(new LoggingInInterceptor());
    proxy.getOutInterceptors().add(new LoggingOutInterceptor());
  }

  private static void setupBinding(ITestService port) {
    javax.xml.ws.BindingProvider bp = (javax.xml.ws.BindingProvider) port;
    SOAPBinding binding = (SOAPBinding) bp.getBinding();
    binding.setMTOMEnabled(true);
    Map<String, Object> context = bp.getRequestContext();
    context.put("ws-security.username", "systemadmin");
    context.put("ws-security.password", "Pass@word1");
    context.put("ws-security.encryption.properties",
        "clientKeystore.properties");
    context.put("ws-security.encryption.username", "serviceKey");
  }

错误跟踪(仅解密阶段) :

[main] DEBUG org.apache.ws.security.components.crypto.CryptoFactory  - Using Crypto Engine [class org.apache.ws.security.components.crypto.Merlin]
[main] DEBUG org.apache.ws.security.util.Loader  - Trying to find [clientKeystore.jks] using sun.misc.Launcher$AppClassLoader@2a340e class loader.
[main] DEBUG org.apache.ws.security.components.crypto.Merlin  - The KeyStore clientKeystore.jks of type jks has been loaded
[main] DEBUG org.apache.ws.security.processor.TimestampProcessor  - Found Timestamp list element
[main] DEBUG org.apache.ws.security.message.token.Timestamp  - Current time: 2012-02-07T22:52:22.852Z
[main] DEBUG org.apache.ws.security.message.token.Timestamp  - Timestamp created: 2012-02-07T22:52:22.641Z
[main] DEBUG org.apache.ws.security.message.token.Timestamp  - Timestamp expires: 2012-02-07T22:57:22.641Z
[main] DEBUG org.apache.ws.security.message.token.Timestamp  - Validation of Timestamp: Everything is ok
[main] DEBUG org.apache.ws.security.message.token.DerivedKeyToken  - DerivedKeyToken: created : element constructor
[main] DEBUG org.apache.ws.security.message.token.DerivedKeyToken  - DerivedKeyToken: created : element constructor
[main] DEBUG org.apache.ws.security.processor.ReferenceListProcessor  - Found reference list element
[main] DEBUG org.apache.ws.security.processor.ReferenceListProcessor  - Found data reference: _3
[main] DEBUG org.apache.ws.security.processor.X509Util  - Sym Enc Algo: http://www.w3.org/2001/04/xmlenc#aes256-cbc
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - Getting XMLCipher with transformation
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - Constructing XMLCipher...
[main] DEBUG org.apache.xml.security.algorithms.JCEMapper  - Request for URI http://www.w3.org/2001/04/xmlenc#aes256-cbc
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - cipher._algorithm = AES/CBC/ISO10126Padding
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - Initializing XMLCipher...
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - opmode = DECRYPT_MODE
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - Processing source element...
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - Decrypting element...
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - Decrypting to ByteArray...
[main] DEBUG org.apache.xml.security.utils.ElementProxy  - setElement("KeyInfo", "null")
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - Encrypted octets:
x1eLqhngbuRTq2XJIkcTdzyu1UFb4eV0kwno04/w4yW0HiY6RyYa7OHqniV63aaxgZPxm0NOK2ZUgjggtkM0O9myJ6ZJOFxCLmqREjQMD+mFW+WuTSEZ5cgc3SFule3MmryqoStNLsmzM8t5yaT3drF1ctT7DJQnV6W858WwpD+Dw+WYmO0RaUlgsfbTnWiBvCZ8yyCzvgmZTMGr8y9LXnwaw+FsspReuMpcIOsqU9LE5u5uW5ZJglgn5cv/8XWikD3TwNzqL+7qAVN8R6WnXgUmb1DuX5lx4cyxlwcLnkfOQKbGrwGvKJUY47ohAgKH
[main] DEBUG org.apache.xml.security.algorithms.JCEMapper  - Request for URI http://www.w3.org/2001/04/xmlenc#aes256-cbc
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - JCE Algorithm = AES/CBC/ISO10126Padding
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - Decrypted octets:
<BasicResponse xmlns="http://searchtechnologies.com/cpa/wcfinterop/data"><DateTimeData>0001-01-02T00:00:00</DateTimeData><IntegerData>Integer data</IntegerData><StringData>String data</StringData></BasicResponse>
[main] DEBUG org.apache.ws.security.processor.ReferenceListProcessor  - Found data reference: _6
[main] DEBUG org.apache.ws.security.processor.X509Util  - Sym Enc Algo: http://www.w3.org/2001/04/xmlenc#aes256-cbc
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - Getting XMLCipher with transformation
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - Constructing XMLCipher...
[main] DEBUG org.apache.xml.security.algorithms.JCEMapper  - Request for URI http://www.w3.org/2001/04/xmlenc#aes256-cbc
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - cipher._algorithm = AES/CBC/ISO10126Padding
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - Initializing XMLCipher...
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - opmode = DECRYPT_MODE
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - Processing source element...
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - Decrypting element...
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - Decrypting to ByteArray...
[main] DEBUG org.apache.xml.security.utils.ElementProxy  - setElement("KeyInfo", "null")
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - Encrypted octets:

[main] DEBUG org.apache.xml.security.algorithms.JCEMapper  - Request for URI http://www.w3.org/2001/04/xmlenc#aes256-cbc
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - JCE Algorithm = AES/CBC/ISO10126Padding
Feb 07, 2012 4:52:22 PM org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor handleMessage
WARNING: 
org.apache.ws.security.WSSecurityException: The signature or decryption was invalid
    at org.apache.ws.security.processor.ReferenceListProcessor.decryptEncryptedData(ReferenceListProcessor.java:298)
    at org.apache.ws.security.processor.ReferenceListProcessor.decryptDataRefEmbedded(ReferenceListProcessor.java:159)
    at org.apache.ws.security.processor.ReferenceListProcessor.handleReferenceList(ReferenceListProcessor.java:93)
    at org.apache.ws.security.processor.ReferenceListProcessor.handleToken(ReferenceListProcessor.java:60)
    at org.apache.ws.security.WSSecurityEngine.processSecurityHeader(WSSecurityEngine.java:396)
    at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:249)
    at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:85)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
    at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:799)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1627)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1494)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1402)
    at org.apache.cxf.io.CacheAndWriteOutputStream.postClose(CacheAndWriteOutputStream.java:47)
    at org.apache.cxf.io.CachedOutputStream.close(CachedOutputStream.java:195)
    at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
    at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:649)
    at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
    at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:533)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:463)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:366)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:319)
    at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:88)
    at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:134)
    at $Proxy33.simpleOperation(Unknown Source)
    at com.searchtechnologies.wcfinterop.TestServiceClient.secureTest(TestServiceClient.java:74)
    at com.searchtechnologies.wcfinterop.TestServiceClient.main(TestServiceClient.java:32)
Caused by: java.lang.ArrayIndexOutOfBoundsException
    at java.lang.System.arraycopy(Native Method)
    at org.apache.xml.security.encryption.XMLCipher.decryptToByteArray(Unknown Source)
    at org.apache.xml.security.encryption.XMLCipher.decryptElement(Unknown Source)
    at org.apache.xml.security.encryption.XMLCipher.doFinal(Unknown Source)
    at org.apache.ws.security.processor.ReferenceListProcessor.decryptEncryptedData(ReferenceListProcessor.java:296)
    ... 26 more

Feb 07, 2012 4:52:22 PM org.apache.cxf.phase.PhaseInterceptorChain doDefaultLogging
WARNING: Interceptor for {http://searchtechnologies.com/cpa/wcfinterop}TestService#{http://searchtechnologies.com/cpa/wcfinterop}SimpleOperation has thrown exception, unwinding now
org.apache.cxf.binding.soap.SoapFault: The signature or decryption was invalid
    at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.createSoapFault(WSS4JInInterceptor.java:643)
    at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:308)
    at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:85)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
    at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:799)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1627)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1494)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1402)
    at org.apache.cxf.io.CacheAndWriteOutputStream.postClose(CacheAndWriteOutputStream.java:47)
    at org.apache.cxf.io.CachedOutputStream.close(CachedOutputStream.java:195)
    at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
    at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:649)
    at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
    at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:533)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:463)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:366)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:319)
    at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:88)
    at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:134)
    at $Proxy33.simpleOperation(Unknown Source)
    at com.searchtechnologies.wcfinterop.TestServiceClient.secureTest(TestServiceClient.java:74)
    at com.searchtechnologies.wcfinterop.TestServiceClient.main(TestServiceClient.java:32)
Caused by: org.apache.ws.security.WSSecurityException: The signature or decryption was invalid
    at org.apache.ws.security.processor.ReferenceListProcessor.decryptEncryptedData(ReferenceListProcessor.java:298)
    at org.apache.ws.security.processor.ReferenceListProcessor.decryptDataRefEmbedded(ReferenceListProcessor.java:159)
    at org.apache.ws.security.processor.ReferenceListProcessor.handleReferenceList(ReferenceListProcessor.java:93)
    at org.apache.ws.security.processor.ReferenceListProcessor.handleToken(ReferenceListProcessor.java:60)
    at org.apache.ws.security.WSSecurityEngine.processSecurityHeader(WSSecurityEngine.java:396)
    at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:249)
    ... 21 more
Caused by: java.lang.ArrayIndexOutOfBoundsException
    at java.lang.System.arraycopy(Native Method)
    at org.apache.xml.security.encryption.XMLCipher.decryptToByteArray(Unknown Source)
    at org.apache.xml.security.encryption.XMLCipher.decryptElement(Unknown Source)
    at org.apache.xml.security.encryption.XMLCipher.doFinal(Unknown Source)
    at org.apache.ws.security.processor.ReferenceListProcessor.decryptEncryptedData(ReferenceListProcessor.java:296)
    ... 26 more

[main] ERROR com.searchtechnologies.wcfinterop.TestServiceClient  - Error during service invocation
java.lang.NullPointerException
    at com.sun.xml.internal.messaging.saaj.soap.impl.ElementImpl.addTextNode(ElementImpl.java:439)
    at com.sun.xml.internal.messaging.saaj.soap.ver1_2.Fault1_2Impl.setFaultRole(Fault1_2Impl.java:323)
    at com.sun.xml.internal.messaging.saaj.soap.ver1_2.Fault1_2Impl.setFaultActor(Fault1_2Impl.java:559)
    at org.apache.cxf.jaxws.JaxWsClientProxy.createSoapFault(JaxWsClientProxy.java:219)
    at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:152)
    at $Proxy33.simpleOperation(Unknown Source)
    at com.searchtechnologies.wcfinterop.TestServiceClient.secureTest(TestServiceClient.java:74)
    at com.searchtechnologies.wcfinterop.TestServiceClient.main(TestServiceClient.java:32)

如您所见,当 CxF 尝试解码引用附件的元素时,它发现其内容为空,并且失败。

任何帮助将深切感激。

由于大小限制,无法发布 WSDL。如有需要,可应要求提供。

此致,

爱德华多·基罗斯-坎波斯

I've been struggling with this problem for quite a bit of time, and have not been able to solve it yet, despite looking around everywhere.

Scenario details (code, config and other stuff is posted at the end):

  1. WCF Web Service (.NET 4), exposing two endpoints: one unsecured and one secured using Message Security and UserName authentication (using Membership infrastructure) -- No Transport Security.
  2. Both endpoints use MTOM encoding; all classed referred to by the WSDL are marked with the MessageContract attribute, and members with MessageBodyMember attribute.
  3. Configuration on WCF bindings has 'establishSecurityContext' and 'negotiateServiceCredential' set to false.
  4. WCF service protected with a self-signed certificate for encryption purposes.
  5. Attempting access from Java client using Apache CXF 2.5.1. I have setup the certificate into a KeyStore accesible from the classpath.

The results:

  1. Accessing the Web Service from a .NET client works fine
  2. Accessing the unsecured endpoint from Apache CXF works fine both with and without MTOM encoding.
  3. Accessing the secured endpoint (without MTOM) from Apache CXF works fine. CXF tracing indicates that the encryption/decryption process is carried on normally.
  4. Once MTOM was activated in WCF, the problem arose. We were able to determine that in the WCF side, the reception of the message, its processing and generation/encryption of the response happens normally.
  5. It is during the reception of the message in CXF that the problem happens. It looks to us that CXF is not deserializing the MTOM attachment properly before trying to decrypt the message; hence, the decryption logic founds that the message still has an element to decrypt in the response, but founds an empty element to decrypt and fails. We tried to add a RECEIVE phase interceptor to initialize attachments, to no avail (fails trying to find the boundary marker in the multipart response).
  6. Using Fiddler, we found that the response looks well formed, with an attachment referred

CODE/CONFIG/STUFF:

Web.Config (shortened for clarity):

  <system.serviceModel>
    <!-- Services -->
    <services>
      <service name="TestServices.Services.TestService" behaviorConfiguration="TestService.Basic">
        <!-- Plain (unsecured) endpoint -->
        <endpoint address="" binding="wsHttpBinding" bindingConfiguration="TestService.Basic" name="TestService.Basic"
                  contract="TestServices.Interfaces.ITestService" bindingNamespace="http://searchtechnologies.com/cpa/wcfinterop"/>
        <!-- Secure endpoint -->
        <endpoint address="/secure" binding="wsHttpBinding" bindingConfiguration="TestService.Secure" name="TestService.Secure"
                  contract="TestServices.Interfaces.ITestService" bindingNamespace="http://searchtechnologies.com/cpa/wcfinterop"/>
      </service>
    </services>
    <!-- Bindings -->
    <bindings>
      <wsHttpBinding>
        <binding name="TestService.Basic" messageEncoding="Mtom">
          <security mode="None">
            <message clientCredentialType="None"/>
            <transport clientCredentialType="None"/>
          </security>
        </binding>
        <binding name="TestService.Secure" messageEncoding="Mtom">
          <security mode="Message">
            <message clientCredentialType="UserName" establishSecurityContext="false" negotiateServiceCredential="false"/>
            <transport clientCredentialType="None"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <!-- Behaviors -->
    <behaviors>
      <serviceBehaviors>
        <behavior name="TestService.Basic">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
          <serviceCredentials>
            <serviceCertificate storeName="My" storeLocation="LocalMachine" x509FindType="FindBySubjectName" findValue="equiros-PC2.search.local"/>
            <userNameAuthentication userNamePasswordValidationMode="MembershipProvider" membershipProviderName="SqlProvider"/>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>

The Java client code (portions omitted for clarity):

  private static void secureTest() {
    try {
      logger.debug("Secure test starting. Instatiating service");
      // service instantiation
      TestService service = new TestService();
      ITestService port = service.getTestServiceSecure();
      // request creation
      BasicRequest request = objectFactory.createBasicRequest();
      request.setStringData("String data");
      request.setIntegerData("Integer data");
      // setup logging
      setupInterceptors(port);
      // setup security & binding
      setupBinding(port);
      // service call
      logger.debug("Attempting service call");
      BasicResponse response = port.simpleOperation(request);
      logger.debug("Call success!!!");
      logger.debug(String.format("Response data: str: %1$s; int: %2$s",
          response.getStringData(), response.getIntegerData()));
    } catch (Exception e) {
      logger.error("Error during service invocation", e);
    }
  }

  private static void setupInterceptors(ITestService port) {
    Client proxy = JaxWsClientProxy.getClient(port);
    proxy.getInInterceptors().add(new LoggingInInterceptor());
    proxy.getOutInterceptors().add(new LoggingOutInterceptor());
  }

  private static void setupBinding(ITestService port) {
    javax.xml.ws.BindingProvider bp = (javax.xml.ws.BindingProvider) port;
    SOAPBinding binding = (SOAPBinding) bp.getBinding();
    binding.setMTOMEnabled(true);
    Map<String, Object> context = bp.getRequestContext();
    context.put("ws-security.username", "systemadmin");
    context.put("ws-security.password", "Pass@word1");
    context.put("ws-security.encryption.properties",
        "clientKeystore.properties");
    context.put("ws-security.encryption.username", "serviceKey");
  }

The error trace (decryption phase only):

[main] DEBUG org.apache.ws.security.components.crypto.CryptoFactory  - Using Crypto Engine [class org.apache.ws.security.components.crypto.Merlin]
[main] DEBUG org.apache.ws.security.util.Loader  - Trying to find [clientKeystore.jks] using sun.misc.Launcher$AppClassLoader@2a340e class loader.
[main] DEBUG org.apache.ws.security.components.crypto.Merlin  - The KeyStore clientKeystore.jks of type jks has been loaded
[main] DEBUG org.apache.ws.security.processor.TimestampProcessor  - Found Timestamp list element
[main] DEBUG org.apache.ws.security.message.token.Timestamp  - Current time: 2012-02-07T22:52:22.852Z
[main] DEBUG org.apache.ws.security.message.token.Timestamp  - Timestamp created: 2012-02-07T22:52:22.641Z
[main] DEBUG org.apache.ws.security.message.token.Timestamp  - Timestamp expires: 2012-02-07T22:57:22.641Z
[main] DEBUG org.apache.ws.security.message.token.Timestamp  - Validation of Timestamp: Everything is ok
[main] DEBUG org.apache.ws.security.message.token.DerivedKeyToken  - DerivedKeyToken: created : element constructor
[main] DEBUG org.apache.ws.security.message.token.DerivedKeyToken  - DerivedKeyToken: created : element constructor
[main] DEBUG org.apache.ws.security.processor.ReferenceListProcessor  - Found reference list element
[main] DEBUG org.apache.ws.security.processor.ReferenceListProcessor  - Found data reference: _3
[main] DEBUG org.apache.ws.security.processor.X509Util  - Sym Enc Algo: http://www.w3.org/2001/04/xmlenc#aes256-cbc
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - Getting XMLCipher with transformation
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - Constructing XMLCipher...
[main] DEBUG org.apache.xml.security.algorithms.JCEMapper  - Request for URI http://www.w3.org/2001/04/xmlenc#aes256-cbc
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - cipher._algorithm = AES/CBC/ISO10126Padding
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - Initializing XMLCipher...
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - opmode = DECRYPT_MODE
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - Processing source element...
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - Decrypting element...
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - Decrypting to ByteArray...
[main] DEBUG org.apache.xml.security.utils.ElementProxy  - setElement("KeyInfo", "null")
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - Encrypted octets:
x1eLqhngbuRTq2XJIkcTdzyu1UFb4eV0kwno04/w4yW0HiY6RyYa7OHqniV63aaxgZPxm0NOK2ZUgjggtkM0O9myJ6ZJOFxCLmqREjQMD+mFW+WuTSEZ5cgc3SFule3MmryqoStNLsmzM8t5yaT3drF1ctT7DJQnV6W858WwpD+Dw+WYmO0RaUlgsfbTnWiBvCZ8yyCzvgmZTMGr8y9LXnwaw+FsspReuMpcIOsqU9LE5u5uW5ZJglgn5cv/8XWikD3TwNzqL+7qAVN8R6WnXgUmb1DuX5lx4cyxlwcLnkfOQKbGrwGvKJUY47ohAgKH
[main] DEBUG org.apache.xml.security.algorithms.JCEMapper  - Request for URI http://www.w3.org/2001/04/xmlenc#aes256-cbc
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - JCE Algorithm = AES/CBC/ISO10126Padding
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - Decrypted octets:
<BasicResponse xmlns="http://searchtechnologies.com/cpa/wcfinterop/data"><DateTimeData>0001-01-02T00:00:00</DateTimeData><IntegerData>Integer data</IntegerData><StringData>String data</StringData></BasicResponse>
[main] DEBUG org.apache.ws.security.processor.ReferenceListProcessor  - Found data reference: _6
[main] DEBUG org.apache.ws.security.processor.X509Util  - Sym Enc Algo: http://www.w3.org/2001/04/xmlenc#aes256-cbc
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - Getting XMLCipher with transformation
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - Constructing XMLCipher...
[main] DEBUG org.apache.xml.security.algorithms.JCEMapper  - Request for URI http://www.w3.org/2001/04/xmlenc#aes256-cbc
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - cipher._algorithm = AES/CBC/ISO10126Padding
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - Initializing XMLCipher...
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - opmode = DECRYPT_MODE
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - Processing source element...
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - Decrypting element...
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - Decrypting to ByteArray...
[main] DEBUG org.apache.xml.security.utils.ElementProxy  - setElement("KeyInfo", "null")
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - Encrypted octets:

[main] DEBUG org.apache.xml.security.algorithms.JCEMapper  - Request for URI http://www.w3.org/2001/04/xmlenc#aes256-cbc
[main] DEBUG org.apache.xml.security.encryption.XMLCipher  - JCE Algorithm = AES/CBC/ISO10126Padding
Feb 07, 2012 4:52:22 PM org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor handleMessage
WARNING: 
org.apache.ws.security.WSSecurityException: The signature or decryption was invalid
    at org.apache.ws.security.processor.ReferenceListProcessor.decryptEncryptedData(ReferenceListProcessor.java:298)
    at org.apache.ws.security.processor.ReferenceListProcessor.decryptDataRefEmbedded(ReferenceListProcessor.java:159)
    at org.apache.ws.security.processor.ReferenceListProcessor.handleReferenceList(ReferenceListProcessor.java:93)
    at org.apache.ws.security.processor.ReferenceListProcessor.handleToken(ReferenceListProcessor.java:60)
    at org.apache.ws.security.WSSecurityEngine.processSecurityHeader(WSSecurityEngine.java:396)
    at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:249)
    at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:85)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
    at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:799)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1627)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1494)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1402)
    at org.apache.cxf.io.CacheAndWriteOutputStream.postClose(CacheAndWriteOutputStream.java:47)
    at org.apache.cxf.io.CachedOutputStream.close(CachedOutputStream.java:195)
    at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
    at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:649)
    at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
    at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:533)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:463)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:366)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:319)
    at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:88)
    at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:134)
    at $Proxy33.simpleOperation(Unknown Source)
    at com.searchtechnologies.wcfinterop.TestServiceClient.secureTest(TestServiceClient.java:74)
    at com.searchtechnologies.wcfinterop.TestServiceClient.main(TestServiceClient.java:32)
Caused by: java.lang.ArrayIndexOutOfBoundsException
    at java.lang.System.arraycopy(Native Method)
    at org.apache.xml.security.encryption.XMLCipher.decryptToByteArray(Unknown Source)
    at org.apache.xml.security.encryption.XMLCipher.decryptElement(Unknown Source)
    at org.apache.xml.security.encryption.XMLCipher.doFinal(Unknown Source)
    at org.apache.ws.security.processor.ReferenceListProcessor.decryptEncryptedData(ReferenceListProcessor.java:296)
    ... 26 more

Feb 07, 2012 4:52:22 PM org.apache.cxf.phase.PhaseInterceptorChain doDefaultLogging
WARNING: Interceptor for {http://searchtechnologies.com/cpa/wcfinterop}TestService#{http://searchtechnologies.com/cpa/wcfinterop}SimpleOperation has thrown exception, unwinding now
org.apache.cxf.binding.soap.SoapFault: The signature or decryption was invalid
    at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.createSoapFault(WSS4JInInterceptor.java:643)
    at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:308)
    at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:85)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
    at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:799)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1627)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1494)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1402)
    at org.apache.cxf.io.CacheAndWriteOutputStream.postClose(CacheAndWriteOutputStream.java:47)
    at org.apache.cxf.io.CachedOutputStream.close(CachedOutputStream.java:195)
    at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
    at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:649)
    at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
    at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:533)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:463)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:366)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:319)
    at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:88)
    at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:134)
    at $Proxy33.simpleOperation(Unknown Source)
    at com.searchtechnologies.wcfinterop.TestServiceClient.secureTest(TestServiceClient.java:74)
    at com.searchtechnologies.wcfinterop.TestServiceClient.main(TestServiceClient.java:32)
Caused by: org.apache.ws.security.WSSecurityException: The signature or decryption was invalid
    at org.apache.ws.security.processor.ReferenceListProcessor.decryptEncryptedData(ReferenceListProcessor.java:298)
    at org.apache.ws.security.processor.ReferenceListProcessor.decryptDataRefEmbedded(ReferenceListProcessor.java:159)
    at org.apache.ws.security.processor.ReferenceListProcessor.handleReferenceList(ReferenceListProcessor.java:93)
    at org.apache.ws.security.processor.ReferenceListProcessor.handleToken(ReferenceListProcessor.java:60)
    at org.apache.ws.security.WSSecurityEngine.processSecurityHeader(WSSecurityEngine.java:396)
    at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:249)
    ... 21 more
Caused by: java.lang.ArrayIndexOutOfBoundsException
    at java.lang.System.arraycopy(Native Method)
    at org.apache.xml.security.encryption.XMLCipher.decryptToByteArray(Unknown Source)
    at org.apache.xml.security.encryption.XMLCipher.decryptElement(Unknown Source)
    at org.apache.xml.security.encryption.XMLCipher.doFinal(Unknown Source)
    at org.apache.ws.security.processor.ReferenceListProcessor.decryptEncryptedData(ReferenceListProcessor.java:296)
    ... 26 more

[main] ERROR com.searchtechnologies.wcfinterop.TestServiceClient  - Error during service invocation
java.lang.NullPointerException
    at com.sun.xml.internal.messaging.saaj.soap.impl.ElementImpl.addTextNode(ElementImpl.java:439)
    at com.sun.xml.internal.messaging.saaj.soap.ver1_2.Fault1_2Impl.setFaultRole(Fault1_2Impl.java:323)
    at com.sun.xml.internal.messaging.saaj.soap.ver1_2.Fault1_2Impl.setFaultActor(Fault1_2Impl.java:559)
    at org.apache.cxf.jaxws.JaxWsClientProxy.createSoapFault(JaxWsClientProxy.java:219)
    at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:152)
    at $Proxy33.simpleOperation(Unknown Source)
    at com.searchtechnologies.wcfinterop.TestServiceClient.secureTest(TestServiceClient.java:74)
    at com.searchtechnologies.wcfinterop.TestServiceClient.main(TestServiceClient.java:32)

As you can see, it looks like when CxF tries to decode the element which references the attachment, it finds its contents empty, and fails.

Any help will be deeply appreciated.

Couldn't post the WSDL because of size constraints. Available on request if necessary.

Regards,

Eduardo Quiros-Campos

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

赠意 2025-01-10 10:29:49

据我所知,当启用签名时,CXF 并不完全支持 MTOM:它不会对附件进行签名或加密。由于 WCF 会对附件进行签名或加密,因此它不起作用。
请参阅http://cxf.547215.n5.nabble.com/Signature-digest-mismatch-when-NET-supplies-MTOM-attachment-td3270961.htmlhttps://issues.apache.org/jira/browse/CXF-3687

As far as I known, CXF does not support completely MTOM when signature is enable : it doesn't sign or encrypt the attachments. As WCF do sign or encryt attachments, it won't work.
See http://cxf.547215.n5.nabble.com/Signature-digest-mismatch-when-NET-supplies-MTOM-attachment-td3270961.html and https://issues.apache.org/jira/browse/CXF-3687.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文