I am tasked with creating a WCF service that will be consumed by an external client. The client uses WSSE security, in particular, they pass the username token through the SOAP header.
WCF is hosted on an IIS server with SSL enabled.
At this moment, I have a semi-working prototype. The problem I'm currently facing is that the SOAP header has the mustUnderstand attribute set to 1, and this leads to the process crashing.
I would like some advice (or better yet, an example of emoticon code) on how to handle the username token in such a way as to return the correct answer when the mustUnderstand attribute is true.
Here is an example of a SOAP request that does not execute:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/"> <soapenv:Header> <wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <wsse:UsernameToken> <wsse:Username>TestUser</wsse:Username> <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">TestPWD</wsse:Password> <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">NzU3MjFhN2YtYTlmYS00ZWZjLTkxNjktY2ExZjlkZDEwNzE5</wsse:Nonce> <wsu:Created xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2011-10-26T03:04:39Z</wsu:Created> </wsse:UsernameToken> </wsse:Security> </soapenv:Header> <soapenv:Body> <tem:Getstuff> <tem:Arg1>Arg1</tem:Arg1> <tem:Arg2>Arg2</tem:Arg2> </tem:Getstuff> </soapenv:Body> </soapenv:Envelope>
If soapenv: mustUnderstand = "1" changes to soapenv: mustUnderstand = "0", then the process works.
PS: Here is the revised sample request sent by the client:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Header> <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/WService/Getstuff</Action> <Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="removed" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <wsse:Username>TestUser</wsse:Username> <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">TestPass</wsse:Password> <wsse:Nonce>2Udx78sh2y2xRJYJpZZ9+w==</wsse:Nonce> <wsu:Created>2011-09-26T19:12:48Z</wsu:Created> </wsse:UsernameToken> </Security> </s:Header> <s:Body> <Getstuff xmlns="http://tempuri.org/"> <Arg1>Arg1</Arg1> <Arg2>Arg2</Arg2> </Getstuff> </s:Body> </s:Envelope>
I get the following response to the above requests:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Body> <s:Fault> <faultcode>s:MustUnderstand</faultcode> <faultstring xml:lang="en-US">The header 'Security' from the namespace 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' was not understood by the recipient of this message, causing the message to not be processed. This error typically indicates that the sender of this message has enabled a communication protocol that the receiver cannot process. Please ensure that the configuration of the client binding is consistent with the service binding.</faultstring> </s:Fault> </s:Body> </s:Envelope>
Here's the binding:
<bindings> <basicHttpBinding> <binding name="TransportBind" maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"> <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" /> <security mode="Transport"> <transport clientCredentialType="None" /> </security> </binding> <binding name="basic" maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"> <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" /> </binding> </basicHttpBinding> </bindings>