powered by simpleCommunicator - 2.0.40     © 2025 Programmizd 02
Форумы / WCF, Web Services, Remoting [игнор отключен] [закрыт для гостей] / Перехват SOAP ответа от сервера в клиенте.
8 сообщений из 8, страница 1 из 1
Перехват SOAP ответа от сервера в клиенте.
    #39291853
DIM@
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день!!!

Есть wcf клиент, который перестал принимать (вернее вываливается в exception => Не удалось проверить безопасность сообщения. InnerException => Неподдерживаемое преобразование или алгоритм канонизации.") сообщения от сервиса, администрация сервиса говорит, что у них всё работает и проблема у меня.
Как перехватить SOAP сообщение от сервера до его десериализации клиентом, все предлагаемые интерфейсы в инспекторе сообщений реализованы:

Код: c#
1.
2.
3.
4.
public class MCSoapInspecotor : IClientMessageInspector, IDispatchMessageInspector, IParameterInspector 
{
    ...
}



Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
public class MCInterceptorBehavior : IEndpointBehavior
{

        public MCSoapInspecotor Inspector { get; set; }
        public MCInterceptorBehavior(MCSoapInspecotor inspector)
        {
            Inspector = inspector;
        }

        public void ApplyClientBehavior(ServiceEndpoint serviceEndpoint, System.ServiceModel.Dispatcher.ClientRuntime behavior)
        {
            behavior.MessageInspectors.Add(Inspector);
            foreach (ClientOperation op in behavior.Operations)
                op.ParameterInspectors.Add(Inspector);
        }

        public void ApplyDispatchBehavior(ServiceEndpoint serviceEndpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
        {
            endpointDispatcher.DispatchRuntime.MessageInspectors.Add(Inspector);
            foreach (DispatchOperation op in endpointDispatcher.DispatchRuntime.Operations)
                op.ParameterInspectors.Add(Inspector);
        }
        ...
}



Код: c#
1.
2.
3.
4.
5.
...
            ServiceEndpoint endpoint = new ServiceEndpoint(contract);
            endpoint.Behaviors.Add(new MCInterceptorBehavior(new MCSoapInspecotor()));
            ChannelFactory<misInterface> factory = new ChannelFactory<misInterface>(endpoint);
...



но, при получении ответа до инспектора дело не доходит. Что и где надо ещё дореализовать, чтобы перехватить ответ на клиенте, после ответа сервера?
...
Рейтинг: 0 / 0
Перехват SOAP ответа от сервера в клиенте.
    #39291865
Фотография Axeleron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DIM@, примерно так.
1. Инициализация и вызов самого сревиса клиентом:
Код: c#
1.
2.
3.
4.
5.
6.
                    using (var behavior = new MyServiceBehavior())
                    {
                        var client = new MyServiceClient();
                        client.Endpoint.Behaviors.Add(behavior);
                        return myService.SomeAction(request, client);
                    }


Имплементация класса MyServiceBehavior:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
    public class MyServiceBehavior : IEndpointBehavior, IDisposable
    {
        private MyServiceMessageInspector _inspector;

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            _inspector = new MyServiceMessageInspector();
            clientRuntime.MessageInspectors.Add(_inspector);
        }

        public void Validate(ServiceEndpoint endpoint)
        {            
        }

        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {            
        }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {            
        }

        public void Dispose()
        {
            _inspector.Dispose();
        }
    }


Имплементация MyServiceMessageInspector:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
    public class MyServiceMessageInspector : IClientMessageInspector
    {
        public object BeforeSendRequest(ref Message request, IClientChannel channel)
        { 
// тут отлавливаем сообщение до сериализации перед отправкой запроса к сервису.
        }

        public void AfterReceiveReply(ref Message reply, object correlationState)
        {
// тут отлавливаем сообщение до сериализации после получения ответа от сервиса. 
        }

        public void Dispose()
        {

        }
    }
...
Рейтинг: 0 / 0
Перехват SOAP ответа от сервера в клиенте.
    #39291877
DIM@
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Это всё сделано, но при получении ответа от сервера функция public void AfterReceiveReply(ref Message reply, object correlationState) не выполняется, такое впечатление, что ошибка происходит раньше


Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
        private void InitWCF()
        {
            ServiceEndpoint endpoint = CreateServiceEndpoint();
            ChannelFactory<misInterface> factory = new ChannelFactory<misInterface>(endpoint);
            factory.Credentials.ClientCertificate.Certificate = Vars.ClientCertificate;
            factory.Credentials.ServiceCertificate.DefaultCertificate = Vars.ServiceCertificate;
            factory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
            factory.Credentials.ServiceCertificate.Authentication.RevocationMode = X509RevocationMode.NoCheck;
            _client = factory.CreateChannel();

            _transportHeader = new transportHeader { authInfo = new authInfo { clientEntityId = Vars.ClientEntityId } };
            Message = new Send { MessageData = new MessageDataSendRequest { AppData = new AppDataSendRequest { messageSourceToken = _hospitalFederalToken } } };
            Command = Message.MessageData.AppData;
        }

        /// <summary>
        /// Возвращает конечную точку сервиса 
        /// </summary>
        /// <returns></returns>
        private ServiceEndpoint CreateServiceEndpoint()
        {
            ContractDescription constract = ContractDescription.GetContract(typeof(misInterface));

            string serverCommonName = Vars.ServiceCertificate.GetNameInfo(X509NameType.SimpleName, false);
            /// DNS имя не совпадает с CommonName из сертификата сервера. Поэтому явно задаем доверие.
            EndpointAddress endpointAddress = new EndpointAddress(new Uri(Vars.EnvironmentAddress), EndpointIdentity.CreateDnsIdentity(serverCommonName));
            ServiceEndpoint endpoint = new ServiceEndpoint(constract);
            endpoint.Behaviors.Add(new MCInterceptorBehavior(new MCSoapInspecotor()));
            endpoint.Address = endpointAddress;
            endpoint.Binding = CreateBinding();
            endpoint.Contract.ProtectionLevel = ProtectionLevel.Sign;

            return endpoint;
        }

        /// <summary>
        /// Сформировать привязку конечной точки
        /// </summary>
        /// <returns></returns>
        private Binding CreateBinding()
        {
            /// Создаём болванку привязки
            BasicHttpBinding basicBinding = new BasicHttpBinding();
            basicBinding.Security.Mode = BasicHttpSecurityMode.Message;
            basicBinding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.Certificate;
            basicBinding.Security.Message.AlgorithmSuite = GostAlgorithmSuite.BasicGostObsolete;
            basicBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
            basicBinding.MaxReceivedMessageSize = 2147483647;
            CustomBinding binding = new CustomBinding(basicBinding);
            binding.Elements.Remove<TextMessageEncodingBindingElement>();
            binding.Elements.Remove<HttpTransportBindingElement>();
            /// Не включаем метку времени в заголовок Security
            binding.Elements.Find<AsymmetricSecurityBindingElement>().IncludeTimestamp = false;
            /// Говорим WCF, что в сообщении не нужно искать метку времени и nonce.
            binding.Elements.Find<AsymmetricSecurityBindingElement>().LocalClientSettings.DetectReplays = false;
            binding.Elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap12WSAddressing10, Encoding.UTF8));
            binding.Elements.Add(HttpsTransportBindingElement());
            binding.Elements.Find<TransportBindingElement>().MaxReceivedMessageSize = int.MaxValue;
            return binding;
        }
...
Рейтинг: 0 / 0
Перехват SOAP ответа от сервера в клиенте.
    #39291879
Фотография Axeleron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DIM@, значит сервис валится на стороне сервера или при получении сообщения. Включите логи и смотрите там. Еще Fiddler в помощь.
...
Рейтинг: 0 / 0
Перехват SOAP ответа от сервера в клиенте.
    #39291891
DIM@
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
При передаче подготовленного клиентом сообщения через SoapUI ответ возвращается :( правда в ответе присутствуют разрывы строк \r\n , а вот должны они быть или нет, если сообщение канонизировано http://www.w3.org/2001/10/xml-exc-c14n# я не знаю, т.к. до этого не придавал ответу значения
...
Рейтинг: 0 / 0
Перехват SOAP ответа от сервера в клиенте.
    #39291913
DIM@
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Может стек ошибки, что нить прояснит:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
Server stack trace: 
   в System.ServiceModel.Security.MessageSecurityProtocol.VerifyIncomingMessage(Message& message, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates)
   в System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.ProcessReply(Message reply, SecurityProtocolCorrelationState correlationState, TimeSpan timeout)
   в System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.Request(Message message, TimeSpan timeout)
   в System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
   в System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
   в System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   в System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
...
Рейтинг: 0 / 0
Перехват SOAP ответа от сервера в клиенте.
    #39291927
Фотография Axeleron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DIM@, этот стек мало информативен. Очевидно, проблема в десериализации. Странно, что не получается перехватывать сообщение.
...
Рейтинг: 0 / 0
Перехват SOAP ответа от сервера в клиенте.
    #39297348
ProBiotek
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fiddler прекрасно отлавливает SOAP запросы и ответы
http://www.telerik.com/fiddler

Нужно только в конфиге программы добавить секцию
Код: c#
1.
2.
3.
4.
5.
  <system.net>
    <defaultProxy>
      <proxy autoDetect="False" bypassonlocal="False" usesystemdefault="True" proxyaddress="http://127.0.0.1:8888" />
    </defaultProxy>
  </system.net>


Важно писать именно "127.0.0.1" а не "localhost". Насколько я помню суть проблему, во втором случае пакеты не отправляются на сетевую карту, и поэтому не будут перехвачены фиддлером.

Может быть у них там на сервере сертификат истек, может быть он попал в список отзыва, или нет доверия УЦ, который его выдал ?
Входящее сообщение перехваченное фиддлером содержит открытую часть сертификата. Его можно выдернуть и посмотреть свойства.
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / WCF, Web Services, Remoting [игнор отключен] [закрыт для гостей] / Перехват SOAP ответа от сервера в клиенте.
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]