Мне поручено создать службу WCF, которая будет использоваться внешним клиентом. Клиент использует безопасность WSSE, в частности, они передают токен имени пользователя через заголовок SOAP.
Служба WCF размещается на сервере IIS с включенным SSL.
На данный момент у меня есть полуработающий прототип. Проблема, с которой я сейчас сталкиваюсь, заключается в том, что для атрибута mustUnderstand в заголовке SOAP установлено значение 1, и это приводит к сбою процесса.
Мне нужен совет (или еще лучше, пример кода улыбается ) о том, как обрабатывать токен имени пользователя таким образом, чтобы возвращать правильный ответ, когда атрибут mustUnderstand имеет значение true.
Вот пример неудачного запроса SOAP:
<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>
Если soapenv: mustUnderstand = "1" изменить на soapenv: mustUnderstand = "0", то процесс работает.
PS: Вот исправленный образец запроса, отправленного клиентом:
<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>
Я получаю следующий ответ на вышеуказанные запросы:
<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's binding is consistent with the service's binding.</faultstring>
</s:Fault>
</s:Body>
</s:Envelope>
Вот привязка:
<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>