I am struggling with WCF
binding configurations.I have third party service added as reference to my project. I was provided with some specifications.
I need to use SOAP v1.2
so I figured that I need WSHttpBinding
it's going to be https
so I need SecurityMode.Transport
Something like this:
var binding = new WSHttpBinding();
binding.Security.Mode = SecurityMode.Transport;
var client = new MyClient(binding, addr);
var result = client.Method(new MyObject());
It results in this request body.
<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>
According to the specification I was provided I need to include Security
element in Header with UsernameToken
and Timestamp
. Exactly what I would get with BasicHttpBinding
and BasicHttpSecurityMode.TransportWithMessageCredential
When I try to set TransportWithMessageCredential
mode with WSHttpBinding
request body changes drastically.
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>
Now I have the security part correct, but all the addressing part is wrong and the body as well. What should I do?
I was expecting(and I need) something like this:
<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>
The second packet you posted is not a WCF call request but a part of security channel setup. This is
RequestSecurityToken
packet that will be answered withRequestSecurityTokenResponse
. After that, if the channel is set up correctly, the same packet with method call will be sent as you posted in first snippet. You can see this packets sequence in Service Trace Viewer:What is the actual problem you're trying to fix? Does your WCF call fail? If so please provide exception details. The most likely reason is WCF configuration or authentication error.
If you strive to avoid these negotiation packets, check this answer that shows how to switch
SecurityMode
toMessage
and setNegotiateServiceCredential
option tofalse
.UPDATE:
This part is related to question update that asks for fixing addressing part of the request.
To manually set wsa:ReplyTo header you need to set ReplyTo property of OperationContext.OutgoingMessageHeaders, like this:
See this answer for more details.