2016-12-30 51 views
4

我正在努力與WCF綁定配置。我有第三方服務添加爲我的項目的參考。我被提供了一些規範。WSHttpBinding TransportWithMessageCredential SecurityMode改變請求

我需要使用SOAP v1.2所以我想,我需要WSHttpBinding這將是https所以我需要SecurityMode.Transport

事情是這樣的:

var binding = new WSHttpBinding(); 
binding.Security.Mode = SecurityMode.Transport; 
var client = new MyClient(binding, addr); 
var result = client.Method(new MyObject()); 

它導致此請求主體。

<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope"  
      xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"> 
    <S:Header> 
    <wsa:MessageID> 
     uuid:6B29FC40-CA47-1067-B31D-00DD010662DA 
    </wsa:MessageID> 
    <wsa:ReplyTo> 
     <wsa:Address>example</wsa:Address> 
    </wsa:ReplyTo> 
    <wsa:To>example</wsa:To> 
    <wsa:Action>example</wsa:Action> 
    </S:Header> 
    <S:Body> 
    <MyObject>...</MyObject> 
    </S:Body> 
</S:Envelope> 

根據我所提供的說明書中,我需要包括在報頭Security元件與UsernameTokenTimestamp。究竟是什麼我會BasicHttpBindingBasicHttpSecurityMode.TransportWithMessageCredential

獲得當我嘗試設置TransportWithMessageCredential模式WSHttpBinding請求主體急劇變化。

binding.Security.Mode = SecurityMode.TransportWithMessageCredential; 
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName; 
var client = new MyClient(binding, addr); 
client.ClientCredentials.UserName.UserName = "username"; 
client.ClientCredentials.UserName.Password = "123456"; 
var result = client.Method(new MyObject()); 
<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope"  
      xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"> 
    <S:Header> 
    <wsa:MessageID> 
     uuid:b633067e-9a9e-4216-b036-4afa3aca161e 
    </wsa:MessageID> 
    <wsa:ReplyTo> 
     <wsa:Address>http://www.w3.org/2005/08/addressing/anonymous</wsa:Address> 
    </wsa:ReplyTo> 
    <wsa:To>example</wsa:To> 
    <wsa:Action>http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT</wsa:Action> 
    <o:Security s:mustUnderstand=1 xmlns:o=http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd> 
     <u:Timestamp>...<u:Timestamp> 
     <o:UsernameToken> 
     <o:Username>...</o:Username> 
     <o:Password>...</o:Password> 
     </o:UsernameToken> 
    </o:Security> 
    </S:Header> 
    <S:Body> 
    <t:RequestSecurityToken>...</t:RequestSecurityToken> 
    </S:Body> 
</S:Envelope> 

現在我有安全部分正確的,但所有的尋址部分是錯誤的,身體也是如此。我該怎麼辦?

我期待(我需要)是這樣的:

<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope"  
      xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"> 
    <S:Header> 
    <wsa:MessageID> 
     uuid:6B29FC40-CA47-1067-B31D-00DD010662DA 
    </wsa:MessageID> 
    <wsa:ReplyTo> 
     <wsa:Address>example</wsa:Address> 
    </wsa:ReplyTo> 
    <wsa:To>example</wsa:To> 
    <wsa:Action>example</wsa:Action> 
    <o:Security s:mustUnderstand=1 xmlns:o=http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd> 
     <u:Timestamp>...<u:Timestamp> 
     <o:UsernameToken> 
     <o:Username>...</o:Username> 
     <o:Password>...</o:Password> 
     </o:UsernameToken> 
    </o:Security> 
    </S:Header> 
    <S:Body> 
    <MyObject>...</MyObject> 
    </S:Body> 
</S:Envelope> 
+1

我建議你嘗試的步驟在那裏http://stackoverflow.com/questions/25776403/wcf-create-usernametoken-with-timestamp-and-password-digest-for-oasis-200401-w – mfatih

回答

0

您發佈的第二包不是WCF呼叫請求,但安全通道建立的一部分。這是RequestSecurityToken數據包,將用RequestSecurityTokenResponse回答。之後,如果通道設置正確,則會在發送第一個片段時發送包含方法調用的相同數據包。你可以看到這個數據包服務跟蹤查看序列:

enter image description here

什麼是你試圖解決的實際問題?你的WCF調用失敗了嗎?如果是這樣,請提供例外詳情。最可能的原因是WCF配置或身份驗證錯誤。

如果你是努力避免這些協議報文,看看這個answer,顯示如何切換到SecurityModeMessageNegotiateServiceCredential選項設置爲false

UPDATE:

質疑更新,要求用於固定請求的尋址部分這部分是相關的。

要手動設置的wsa:ReplyTo頭,你需要設置的OperationContext.OutgoingMessageHeadersReplyTo財產,像這樣:

using (new OperationContextScope(client.InnerChannel)) 
{ 
    OperationContext.Current.OutgoingMessageHeaders.ReplyTo = new EndpointAddress("http://someclient/callback"); 
    var request = client.Method(new MyObject()); 
} 

有關詳細信息,請參閱本answer

+0

ty爲你的答案。我更新了問題並提供了我需要的請求主體。 –

+0

在'UPDATE'標題後查看我的答案更新。 – CodeFuller

0

最後我不得不使用CustomBinding發送所需的請求。

var b = new CustomBinding(); 

var security = TransportSecurityBindingElement.CreateUserNameOverTransportBindingElement(); 
    security.IncludeTimestamp = true; 
    security.DefaultAlgorithmSuite = SecurityAlgorithmSuite.Default; 
    security.MessageSecurityVersion = MessageSecurityVersion.Default; 
    security.SecurityHeaderLayout = SecurityHeaderLayout.Lax; 
    security.EnableUnsecuredResponse = true; 

var encoding = new TextMessageEncodingBindingElement(); 
    encoding.MessageVersion = MessageVersion.Soap12WSAddressing10; 

var transport = new HttpsTransportBindingElement 
    { 
     MaxBufferPoolSize = 2147483647, 
     MaxBufferSize = 2147483647, 
     MaxReceivedMessageSize = 2147483647, 
    }; 

    b.Elements.Add(security); 
    b.Elements.Add(encoding); 
    b.Elements.Add(transport); 

var client = new MyClient(binding, addr); 
var result = client.Method(new MyObject());