2012-03-28 5 views
5

私はWCF WS-Securityを使用してnon.Net Webサービスを使用するクライアントを作成しています。サービスの応答にmustUnderstandがtrueに設定されたSecurityヘッダーが含まれています。WCFクライアント - MustUnderstandヘッダー要素を処理または無視する方法

ServiceModelListenerを使用すると、実際のデータがサービスから戻ってくるのがわかります。 WCFクライアントは、セキュリティヘッダーを処理していないため、失敗します。

<env:Header> 
<wsse:Security env:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> 
<wsu:Timestamp wsu:Id="timestamp"> 
<wsu:Created>2012-03-28T13:43:54.474Z</wsu:Created> 
<wsu:Expires>2012-03-28T13:48:54.474Z</wsu:Expires> 
</wsu:Timestamp> 
</wsse:Security> 
</env:Header> 

WCFクライアントエラーメッセージ:

ヘッダのネームスペースから「セキュリティ「http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd」は処理されないメッセージを引き起こし、このメッセージの受信者によって理解されませんでした。このエラーは、通常、このメッセージの送信者が受信者が処理できない通信プロトコルを有効にしたことを示します。クライアントのバインディングの設定がサービスのバインドと一貫していることを確認してください。

私のWCFクライアントはタイムスタンプ情報を必要としません。処理ルーチンで簡単にスタブする方法はありますか?私は既にResponseクラスを拡張しようとしました& [MessageHeader]プロパティを追加しました。

編集:どのように私は理解しなければならないとマークされているカスタムヘッダー要素を受け入れWCFクライアントを実装します:

は別の方法を尋ねましたか?

答えて

1

WS-Securityにはさまざまな標準があります。 basicHttpBindingとwsHttpBindingsは異なるセキュリティ標準で動作しているので、クライアント側でバインディングを変更することは意味があります。

+1

ありがとうございますが、サービスはbasicHttpBindingだけをサポートしています。 –

2

同様の問題が発生しました。これが有用かどうかはわかりません。

MSDN WCF拡張

http://blogs.msdn.com/b/carlosfigueira/archive/2011/04/19/wcf-extensibility-message-inspectors.aspx

ここでの設定は、証明書ベースのは、Oracle Application Server 10gの、および.NETは、サービスを利用することです。 SOAPUiを使用することは、Requestで何が起こっていたのか、それから応答があるのか​​を把握するのに非常に役立ちました。

私はbasicHttpBindingを使用するようにコードを修正しようとはしませんでしたが、私はコードで自分の設定のベースとしてWSHttpBindingを使用しました。そして、NoneにSOAP11とAddressingVersionを設定するTextMessageEncodingBindingElement用ループスルー

WSHttpBinding binding = new WSHttpBinding() 
     { 
      CloseTimeout = new TimeSpan(0, 1, 0), 
      OpenTimeout = new TimeSpan(0, 1, 0), 
      SendTimeout = new TimeSpan(0, 1, 0), 
      AllowCookies = false, 
      BypassProxyOnLocal = false, 
      HostNameComparisonMode = HostNameComparisonMode.StrongWildcard, 
      MaxBufferPoolSize = 524288, 
      MaxReceivedMessageSize = 65536, 
      MessageEncoding = WSMessageEncoding.Text, 
      UseDefaultWebProxy = false, 
      ReaderQuotas = new System.Xml.XmlDictionaryReaderQuotas() 
      { 
       MaxDepth = 32, 
       MaxArrayLength = 16384, 
       MaxBytesPerRead = 4096, 
       MaxNameTableCharCount = 16384, 
       MaxStringContentLength = 8192 
      } 
     }; 
     binding.Security.Mode = SecurityMode.Transport; 
     binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate; 
     binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None; 
     binding.Security.Transport.Realm = string.Empty; 
     binding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate; 
     binding.Security.Message.EstablishSecurityContext = true; 
     binding.Security.Message.NegotiateServiceCredential = true; 

     CustomBinding customBinding = new CustomBinding(); 
     BindingElementCollection collection = binding.CreateBindingElements(); 

を使用。

foreach (BindingElement element in collection) 
     { 
      if (typeof(TextMessageEncodingBindingElement) == element.GetType()) 
      { 
       TextMessageEncodingBindingElement item = element as TextMessageEncodingBindingElement; 
       if (null != item) 
       { 
        item.MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap11, AddressingVersion.None); 
        customBinding.Elements.Add(item); 
       } 
      } 
      else 
       customBinding.Elements.Add(element); 
     } 

私はChannelFactoryを使用し、メッセージインスペクタにエンドポイント動作を追加しました。 この時点で、私は要求の制御権を持っていました。適切なヘッダーを追加して、アクションのmustUnderstandを変更しました。

SOAPUiを使用してMessage.ToString()をSOAPUIに入れ、リクエストをテストしました。必要な項目がリクエストに追加されると、OASサーバーが必要なすべての要素に応答していないと判断されました。返信用のメッセージインスペクタを使用して、紛失したヘッダを含むようにメッセージを修正しました。私はメッセージインスペクタのベースコードがどこにあるのか覚えていませんが、コードを適切にutlizeするように変更する必要があります。

私の例では、いくつかのスニペットがあります。

私は私のXElementをつかんで、OASISのヘッダを追加し、ヘッダに追加forループを使用して、ヘッダを変更する必要

public object BeforeSendRequest 

に変換メッセージについて

XNamespace xmlns = "http://schemas.xmlsoap.org/soap/envelope/"; 
       XElement securityHeader = new XElement(
        xmlns + "Security", 
        new XAttribute(xmlns + "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"), 
        new XAttribute(xmlns + "xmlns", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"), 
        new XAttribute(xmlns + "mustUnderstand", "0")); 
       element.Add(securityHeader); 

私もアクションヘッダー

else if (localName.Equals("Action", StringComparison.InvariantCultureIgnoreCase)) 
      { 
       foreach (XAttribute a in element.Attributes()) 
       { 
        if (a.Name.LocalName == "mustUnderstand") 
         a.Value = "0"; 
       } 
      } 

を変更しなければならなかった私の問題は、サービスがそう

public void AfterReceiveReply 

にアクションヘッダー

で応答しなかったことでしたTransformReplyは次のようなタイプのMessage型を返します。 string.Emptyの値を変更する必要があるかもしれませんが、これは単なる例です。

...

Message reply = Message.CreateMessage(message.Version, null, reader); 
     reply.Headers.Add(MessageHeader.CreateHeader("Action", string.Empty, string.Empty, false)); 
     reply.Properties.CopyProperties(message.Properties); 

...

私は本当に封筒を台無しにbeableと回答を確認するために、このようなSOUPUIなどのツールを使用してお勧めします。 SSLを使用する場合は、cacertファイルを作成し、プリファレンスのSSLSettingsに配置する必要があります。

+0

ありがとうアダム!興味深い情報のように見えます。私は今でも別のコンサルティングエンゲージメントに移りました。だから、もはやそのシステムに対して何かを試してみることはできません。以前はクライアントが最終的に異なるアーキテクチャーアプローチでこの問題を解決しました。 –

関連する問題