Silverlight RIA Services - How To Best Handle Client Auth Session Timeout?

Я создал приложение с Silverlight4, RIA Services и использую ASP.NET Membership для аутентификации/авторизации.

В моем web.config есть следующее:

<system.web>
 <sessionState timeout="20"/>
 <authentication mode="Forms">
  <forms name="_ASPXAUTH" timeout="20"/>
 </authentication>

Я читал несколько различных стратегий о том, как справиться с таймаутом аутентификации/сеанса на стороне клиента. То есть: если клиент бездействует в течение x минут (здесь 20), а затем он делает что-то с UI, что вызывает вызов RIA/WCF, я хочу поймать это событие и обработать соответствующим образом (например, вернуть его на экран входа) - в двух словах: Мне нужен способ отличить добросовестное DomainException на стороне сервера от сбоя авторизации из-за того, что сессия завершилась.

AFAIK: не существует типизированного исключения или свойства, которое может определить это. Единственный способ, которым я смог определить это - что кажется мне хаком - это просмотреть строку сообщения ошибки и найти что-то вроде "Access denied" или "denied". Например: что-то вроде этого:

if (ex.Message.Contains("denied"))
  // this is probably an auth failure b/c of a session timeout

Итак, вот что я сейчас делаю, и это работает, если я запускаю и отлаживаю либо встроенный сервер из VS2010, либо если я запускаю на локальном хосте IIS. Если я устанавливаю тайм-аут на 1 минуту, вхожу в систему, жду больше минуты и вызываю другой вызов, я ставлю точку останова на исключении и ввожу приведенный выше блок кода if, и все в порядке.

Затем я развертываю приложение на удаленном сервере IIS7 и пытаюсь выполнить тот же тест, но он не работает. Поэтому я добавил трассировку журнала, и вот событие, в котором произошло исключение:

<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
 <System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
  <EventID>131076</EventID>
  <Type>3</Type>
  <SubType Name="Error">0</SubType>
  <Level>2</Level>
  <TimeCreated SystemTime="2011-10-30T22:13:54.6425781Z" />
  <Source Name="System.ServiceModel" />
  <Correlation ActivityID="{20c26991-372f-430f-913b-1b72a261863d}" />
  <Execution ProcessName="w3wp" ProcessID="4316" ThreadID="24" />
  <Channel />
  <Computer>TESTPROD-HOST</Computer>
 </System>
 <ApplicationData>
  <TraceData>
   <DataItem>
    <TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Error">
     <TraceIdentifier>http://msdn.microsoft.com/en-US/library/System.ServiceModel.Diagnostics.TraceHandledException.aspx</TraceIdentifier>
     <Description>Handling an exception.</Description>
     <AppDomain>/LM/W3SVC/1/ROOT/sla-2-129644844652558594</AppDomain>
     <Exception>
      <ExceptionType>System.ServiceModel.FaultException`1[[System.ServiceModel.DomainServices.Hosting.DomainServiceFault, System.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]], System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
      <Message></Message>
       <StackTrace>
        at System.ServiceModel.DomainServices.Hosting.QueryOperationBehavior`1.QueryOperationInvoker.InvokeCore(Object instance, Object[] inputs, Object[]&amp; outputs)
        at System.ServiceModel.DomainServices.Hosting.DomainOperationInvoker.Invoke(Object instance, Object[] inputs, Object[]&amp; outputs)
        at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&amp; rpc)
        at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&amp; rpc)
        at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc&amp; rpc)
        at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
     </StackTrace>
     <ExceptionString>System.ServiceModel.FaultException`1[System.ServiceModel.DomainServices.Hosting.DomainServiceFault]:  (Fault Detail is equal to System.ServiceModel.DomainServices.Hosting.DomainServiceFault).</ExceptionString>
  </Exception>
 </TraceRecord>
</DataItem>
</TraceData>
</ApplicationData>
</E2ETraceEvent>

Проблема в том, что у меня нет строки в сообщении об ошибке, которая указывает на "Отказано" или "Доступ запрещен" - и я не знаю, почему это решение работает на локальном хосте IIS или хосте VS2010, но не на удаленном сервере IIS7. Может быть, я упускаю какой-то непонятный параметр конфигурации? Есть ли лучший способ сделать это в целом?

8
задан zenocon 3 November 2011 в 14:07
поделиться