Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Распределённые приложения и сеть > Обрыв защищенной WCF session


Автор: AleXGray 19.5.2011, 16:31
Написал я защищенный сервис WCF, на локальном компе работал.
Проблемы возникли, когда выложил на сервер в IIS 7.5
При объеме данных, который передается меньше чем за 4 минуты, сервис отрабатывает правильно.
При увеличении объема данных, либо при ухудшении интернета данные передаются больше 4 минут и сервис вылетает с ошибкой.
При отключении секьюрити (Message Mode="None"), при длительной передаче данных ошибки не возникает.
текст ошибки
Код

<Exception><ExceptionType>System.ServiceModel.EndpointNotFoundException, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
<Message>There was no channel that could accept the message with action 'EmailWorker/IService1/SaveData'.</Message>
<StackTrace>   at System.ServiceModel.Dispatcher.ErrorBehavior.ThrowAndCatch(Exception e, Message message)
02.at System.ServiceModel.Channels.DatagramChannelDemuxer`2.ProcessItem(TInnerItem item)
03.at System.ServiceModel.Channels.DatagramChannelDemuxer`2.HandleReceiveResult(IAsyncResult result)
04.at System.ServiceModel.Channels.DatagramChannelDemuxer`2.OnReceiveComplete(IAsyncResult result)
05.at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
06.at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
07.at System.ServiceModel.Channels.ReplyChannel.HelpReceiveRequestAsyncResult.OnReceiveRequest(IAsyncResult result)
08.at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
09.at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
10.at System.Runtime.InputQueue`1.AsyncQueueReader.Set(Item item)
11.at System.Runtime.InputQueue`1.EnqueueAndDispatch(Item item, Boolean canDispatchOnThisThread)
12.at System.Runtime.InputQueue`1.EnqueueAndDispatch(T item, Action dequeuedCallback, Boolean canDispatchOnThisThread)
13.at System.ServiceModel.Channels.SingletonChannelAcceptor`3.Enqueue(QueueItemType item, Action dequeuedCallback, Boolean canDispatchOnThisThread)
14.at System.ServiceModel.Channels.HttpChannelListener.HttpContextReceived(HttpRequestContext context, Action callback)
15.at System.ServiceModel.Activation.HostedHttpTransportManager.HttpContextReceived(HostedHttpRequestAsyncResult result)
16.at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.HandleRequest()
17.at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.BeginRequest()
18.at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequest(Object state)
19.at System.Runtime.IOThreadScheduler.ScheduledOverlapped.IOCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
20.at System.Runtime.Fx.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped)
21.at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
22.</StackTrace>
<ExceptionString>System.ServiceModel.EndpointNotFoundException: 
There was no channel that could accept the message with action 'EmailWorker/IService1/SaveData'.
</ExceptionString></Exception>


+
Код

<Description>The incoming message is not part of an existing security session.</Description>


все таймауты, которые в binding накручивал. В любом случае ни один из них и близко не равняется 4 минутам.
Повторюсь, без секьюрити все работает.
Если я правильно понял, причина в том, что сессия устаревает пока после ее установления данные наконец загрузятся и потом эти данные просто не признаются за подлинные. 
Вопрос в том, как это поправить?

Автор: jonie 21.5.2011, 11:51
1) зачем защищать сами сообщения, если можно защитить весь канал  (SSL\TLS) ? Это быстрее (cpu не так кушается) и проще (тем более в IIS - два тыка мышкой чтобы применить сертификат).
2) что в логах WCF на сервере? (http://msdn.microsoft.com/en-us/library/ms730064.aspx)
3) прочтите тут: http://stackoverflow.com/questions/968939/wcf-session-timeout

Автор: AleXGray 21.5.2011, 12:17
Я не знаю ни одного timeout, ни в wcf ни в httpRuntime где 4 минуты выставлено по умолчанию. Эти 4 минуты разрешения на передачу защищенного контекста работают как часы.

1. Transport несовместим с UserName аутентификацией. Поэтому было выбрано Message. Быстродействие и нагрузка на процессор меня вполне удовлетворяют на данном этапе. TransportWithMessage буду пробовать, но если я правильно понимаю вопрос, ничего ровным счетом от этого измениться не должно.
Я так понимаю что должно работать и при Message, она ж для чего то да сделана.

2. Логи сервера я как раз и привел.

3. reliable я не использую вообще. Наверное приведу конфиги, чтобы не было лишних вопросов

Клиент:
Код

<system.serviceModel>
        <bindings>
            <wsHttpBinding>
                <binding name="WSHttpBinding_IService1" closeTimeout="00:05:00"
                    openTimeout="00:05:00" receiveTimeout="00:30:00" sendTimeout="00:30:00"
                    bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferPoolSize="52428800" maxReceivedMessageSize="655360000"
                    messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                    allowCookies="false">
                    <readerQuotas maxDepth="32" maxStringContentLength="819200000" maxArrayLength="163840000"
                        maxBytesPerRead="40960" maxNameTableCharCount="163840000" />
                    <reliableSession ordered="true" inactivityTimeout="00:10:00"
                        enabled="false" />
                    <security mode="Message">
                        <message clientCredentialType="UserName" negotiateServiceCredential="true" />
                    </security>
                </binding>
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://manor-medical.info/service/Service1.svc/Service1"
                binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService1"
                contract="ServiceReference1.IService1" name="WSHttpBinding_IService1" behaviorConfiguration="Service1Behavior" >
            </endpoint>
        </client>
        <behaviors>
            <endpointBehaviors>
                <behavior name="Service1Behavior">
                    <clientCredentials>                       
                        <serviceCertificate>
                            <authentication certificateValidationMode="None" revocationMode="NoCheck"/>
                        </serviceCertificate>
                    </clientCredentials>
                </behavior>
            </endpointBehaviors>
        </behaviors>
    </system.serviceModel>


Сервер: 
Код

<system.web>
      <compilation debug="true" targetFramework="4.0"></compilation>
      <httpRuntime maxRequestLength="999999999"  />
      <sessionState stateNetworkTimeout="40"></sessionState>
  </system.web>
  <system.serviceModel>
      <services>
          <service name="WcfService1.Service1" behaviorConfiguration="Service1Behavior">
              <endpoint address="Service1" contract="WcfService1.IService1" binding="wsHttpBinding" bindingConfiguration="Service1Binding"  />
          </service>
      </services>
      <bindings>
          <wsHttpBinding>
              <binding name="Service1Binding" closeTimeout="00:02:00"
                    openTimeout="00:02:00" receiveTimeout="00:20:00" sendTimeout="00:20:00"
                    bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferPoolSize="52428800" maxReceivedMessageSize="655360000"
                    messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                    allowCookies="false">
                  <readerQuotas maxDepth="32" maxStringContentLength="8192000" maxArrayLength="163840000"
                      maxBytesPerRead="40960" maxNameTableCharCount="1638400" />
                  <reliableSession ordered="true" inactivityTimeout="00:10:00"
                      enabled="false" />
                  <security mode="Message">
                      <message clientCredentialType="UserName" negotiateServiceCredential="true" ></message>
                  </security>
                  
              </binding>
          </wsHttpBinding>
      </bindings>
      
      <behaviors>
      <serviceBehaviors>
        <behavior name="Service1Behavior">
            <serviceCredentials>
                <serviceCertificate findValue="CN=localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectDistinguishedName"/>
                <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WcfService1.MyUserNamePaswordValidator, WcfService1"/>
            </serviceCredentials>
            <dataContractSerializer maxItemsInObjectGraph="65536000" />

          <serviceMetadata httpGetEnabled="true" />

          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>

Автор: jonie 21.5.2011, 12:56
Цитата(AleXGray @  21.5.2011,  12:17 Найти цитируемый пост)
1. Transport несовместим с UserName аутентификацией. Поэтому было выбрано Message. Быстродействие и нагрузка на процессор меня вполне удовлетворяют на данном этапе. TransportWithMessage буду пробовать, но если я правильно понимаю вопрос, ничего ровным счетом от этого измениться не должно.
Я так понимаю что должно работать и при Message, она ж для чего то да сделана.

почему это несовместим?
http://msdn.microsoft.com/en-us/library/ff649647.aspx
http://www.leastprivilege.com/FinallyUsernamesOverTransportAuthenticationInWCF.aspx

Автор: AleXGray 21.5.2011, 13:13
несовместим при wsHttp, наверное нужно было сказать.
Но Вы правы, в принципе на ws свет клином не сошелся, попробую настроить по Вашим ссылкам.

Автор: AleXGray 22.5.2011, 17:35
The HTTP request is unauthorized with client authentication scheme 'Basic'. The authentication header received from the server was 'Basic realm="manor-medical.info"'.
Если же ставить TransportWithMessageSecurity и message UserName, то получается странная вещь: логин пароль не проверяется вообще. Подходит любой.

Автор: AleXGray 22.5.2011, 20:35
Все таки пришлось использовать TransportWithMessageCredential, но с basicHttpBinding. Идея отойти от ws была верной. Спасибо.
Хотя первоначальный вопрос и остался, но теперь он теоретический а не "горящий".

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)