1

私はかなり長い間この問題に苦しんでいて、至る所を見回しているにもかかわらず、まだそれを解決することができていません。

シナリオの詳細(コード、構成、その他のものは最後に掲載されています):

  1. WCF Webサービス(.NET 4)、2つのエンドポイントを公開します。1つはセキュリティで保護されておらず、もう1つはメッセージセキュリティとユーザー名認証(メンバーシップインフラストラクチャを使用)を使用してセキュリティで保護されています-トランスポートセキュリティはありません。
  2. 両方のエンドポイントはMTOMエンコーディングを使用します。WSDLによって参照されるすべてのクラスは、MessageContract属性でマークされ、メンバーはMessageBodyMember属性でマークされます。
  3. WCFバインディングの構成では、「establishSecurityContext」と「negotiateServiceCredential」がfalseに設定されています。
  4. 暗号化の目的で自己署名証明書で保護されたWCFサービス。
  5. ApacheCXF2.5.1を使用してJavaクライアントからアクセスを試みています。クラスパスからアクセス可能なKeyStoreに証明書を設定しました。

結果:

  1. .NETクライアントからのWebサービスへのアクセスは正常に機能します
  2. Apache CXFからセキュリティで保護されていないエンドポイントにアクセスすることは、MTOMエンコーディングの有無にかかわらず正常に機能します。
  3. Apache CXFから(MTOMなしで)保護されたエンドポイントにアクセスすることは正常に機能します。CXFトレースは、暗号化/復号化プロセスが正常に実行されていることを示しています。
  4. MTOMがWCFでアクティブ化されると、問題が発生しました。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を投稿できませんでした。必要に応じてリクエストに応じて利用できます。

よろしく、

エドゥアルド・キロス-カンポス

4

1 に答える 1

1

私が知る限り、CXF は署名が有効な場合、MTOM を完全にはサポートしていません。添付ファイルの署名や暗号化は行いません。WCF は添付ファイルに署名または暗号化するため、機能しません。http://cxf.547215.n5.nabble.com/Signature-digest-mismatch-when-NET-supplies-MTOM-attachment-td3270961.htmlおよびhttps://issues.apache.org/jira/browse/CXFを参照してください。 -3687 .

于 2012-04-04T09:19:56.673 に答える