Случайно залипание тела SOAP внутри заголовка SOAP при попытке доступа к службе WSE с клиентом WCF
Я пытаюсь попасть в защищенный веб-сервис WSE с помощью WCF. Заголовок SOAP, который мне нужно сгенерировать, должен содержать имя пользователя, пароль, одноразовый номер и дату создания... Вот пример заголовка мыльного пользовательского интерфейса, который я использую для доступа к той же службе...
<soap:Header>
<wsse:Security soap:mustUnderstand="true" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-2" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>----------</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">----------</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">Hozef94FFwOhuiF5QixaMQ==</wsse:Nonce>
<wsu:Created>2012-08-21T13:26:03.642Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</soap:Header>
Теперь я нашел урок, который был довольно полезным. полезное руководство
Я успешно реализовал это... Но теперь я вставляю тело SOAP в заголовок soap, и не генерируется одноразовый номер.
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Header>
<VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPo9VZylDHg5JMgjsNnWLhATkAAAAA+YtOxHdh0Uqd4a64raX/nIzYz20mPHlBv4Wk5S8d5PsACQAA</VsDebuggerCausalityData>
<wsse:Security s:mustUnderstand="0" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<UsernameToken xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<Username>------------</Username>
<Password>************</Password>
</UsernameToken>
</wsse:Security>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<GetOrganizations xmlns="http://------------------------/businessobjects/messaging/">
<personId xmlns="">0</personId>
<typeId xmlns="">
<int>1</int>
<int>2</int>
<int>3</int>
<int>4</int>
</typeId>
</GetOrganizations>
</s:Body>
</s:Header>
</s:Envelope>
Не знаю, почему он это делает. Я следовал за учебником к письму. Мой репозиторий получает все...
using (DistListServiceReference.DistributionListClient dlc = new DistListServiceReference.DistributionListClient())
{
try
{
PasswordDigestBehavior behavior = new PasswordDigestBehavior("********", "********");
dlc.Endpoint.Behaviors.Add(behavior);
GetDistributionLists gdl = new GetDistributionLists();
gdl.PersonID = 0;
GetDistributionListsResponse gdlr = new GetDistributionListsResponse();
gdlr = dlc.GetDistributionLists(gdl);
return gdlr;
}
catch (Exception e)
{
dlc.Abort();
return null;
}
}
Мой пароль DigentInspector
public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
{
// Use the WSE 3.0 security token class
UsernameToken token = new UsernameToken(this.Username, this.Password, PasswordOption.SendPlainText);
WseHeader header = new WseHeader(this.Username, this.Password);
// Serialize the token to XML
XmlElement securityToken = token.GetXml(new XmlDocument());
MessageHeader securityHeader = MessageHeader.CreateHeader("Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken", securityToken, false);
request.Headers.Add(header);
// complete
return Convert.DBNull;
}
Как я применяю поведение клиента
public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
{
clientRuntime.MessageInspectors.Add(new PasswordDigestMessageInspector(this.Username, this.Password));
}
Все в значительной степени там. Я не сижу, где тело вводится в заголовок. У какого тела есть идеи?
ОБНОВЛЕНИЕ: Отладка Я смотрю на фактический заголовок, который я вставляю в мыльное сообщение, и это то, что я вижу...
{<wsse:Security s:mustUnderstand="0" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<UsernameToken xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<Username>**********</Username>
<Password>************</Password>
</UsernameToken>} System.ServiceModel.Channels.MessageHeaderInfo {TestDistListApplication.Repository.WseHeader}
Просто глядя на это, нет одноразового номера, я мог бы построить его программно, но я не уверен, что это хорошая идея. Тем более, что в securityToken уже есть одноразовый номер и дата создания... Не уверен, почему они не отображаются в заголовке...
<wsse:Username xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">MedTrak_Dev</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">uncJUN132012</wsse:Password>
<wsse:Nonce xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">mvy9nUfF+rnT3oTasDBqxg==</wsse:Nonce>
<wsu:Created xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2012-08-28T13:30:42Z</wsu:Created>
Я остановил отладчик, и я наблюдаю обе эти переменные. Что может привести к тому, что в заголовке не будет этих вещей, а у WSEHeader они есть? Похоже, мне придется отлаживать это.
1 ответ
Без запуска вашего кода немного сложно понять, почему мой пример не работает в вашем сценарии. Тем не менее, в попытке отладить это, я бы попробовал следующее:
Укажите точку останова в этой строке:
XmlElement securityToken = token.GetXml(new XmlDocument());
И после прохождения этой строки посмотрите, как выглядит securityToken XML. Именно этот XML вводится в заголовок безопасности. Это не сложнее, чем это. Вы можете создать этот XML вручную, если хотите. Я использовал классы WSE 3.0, потому что не хотел сам писать код XML.
Я также заметил, что ваше определение токена безопасности немного отличается от моего. Мой пример был:
MessageHeader securityHeader = MessageHeader.CreateHeader("Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", securityToken, false);
С уважением:
MessageHeader securityHeader = MessageHeader.CreateHeader("Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken", securityToken, false);
Пространства имен разные. Есть причина для этого?
Если точка останова, добавленная на шаге выше, не достигнута, это может означать, что поведение на самом деле не применяется. В этом случае вам, вероятно, нужно будет дважды проверить ваши конфиги, чтобы убедиться, что поведение правильно применяется на клиенте. В качестве альтернативы (как показывает мой пример) вы можете программно добавить пользовательское поведение перед отправкой сообщения.
Я рекомендую всем, кто имеет дело с проблемами WCF, сначала включить подробное ведение журнала, а также использовать fiddler, чтобы увидеть, что на самом деле происходит по проводам.