Silverlight RIA服务–如何最好地处理客户授权会话超时?

 2023-02-16    447  

问题描述

我用Silverlight4,RIA服务建立了一个应用程序,我正在使用ASP.NET成员资格进行身份验证/授权.

我的web.config有这个:

Silverlight RIA服务–如何最好地处理客户授权会话超时?

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

我已经阅读了许多不同的策略,了解如何处理客户端的验证/会话超时.那是:如果客户端空闲X分钟(这里20的20),那么他们就会使用触发RIA/WCF呼叫的UI做点什么,我想陷入该事件并适当地处理(例如,将它们送回登录屏幕) – 以简而言之

afaik:没有可以确定这一点的键入异常或属性.我能够确定这一点的唯一方法 – 这似乎是一个黑客:是检查错误的消息字符串,并寻找”访问被拒绝”或”被拒绝”的内容.例如:如下所示:

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

所以,这就是我目前正在做的,如果我使用从VS2010的内置服务器运行和调试,或者我在localhost IIS中运行.如果我将超时设置为1分钟,登录,等待一分钟并触发另一个呼叫,我在异常上断开,然后输入上面的代码块,一切都很好.

然后我将应用程序部署到远程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>

问题是我在错误消息中没有字符串,指示”拒绝”或”拒绝” – 而且我不确定为什么此解决方案在localhost IIS或VS2010主机中工作但不在远程中IIS7服务器.我错过了一些模糊的配置设置吗?有没有更好的方法来做到这一点?

推荐答案

您可能现在已经通过此目的,但是本文使用DomainEperationException描述并检查错误代码.

dex.ErrorCode == ErrorCodes.NotAuthenticated || dex.ErrorCode == ErrorCodes.Unauthorized

方便访问(如果我们放松访问博客)这里的博客文章由Josh Eastburn:

往往来自正在使用Silverlight和WCF RIA服务的开发人员出现的问题:为什么我的Silverlight应用程序在闲置一段时间后抛出异常?正如您可能期望的那样,它是由于经过身份验证的会话时机.但这并不是那么简单.由于Silverlight使用客户端/服务器架构,因此客户端可以独立于服务器运行,以实现无限期的时间.只有当Silverlight客户端拨打到服务器端时,才能实现服务器端超时.有一些选项来处理客户端 – 服务器超时问题(并且您可能会更多地提出更多信息):如果您不关心删除会话超时的安全含义,则可以增加超时在Web.config中设置,或在Silverlight客户端中创建调度值,该客户端在服务器上调用一个简单的方法,以充当”保持活力”.向Silverlight客户端添加DIMALLERTIMER,与服务器端超时并警告/提示用户在时间过期之前保持会话活动,或者如果已过期,则会重新验证.但是,这需要额外的努力来在进行新的服务器请求时保持同步中的计时器.允许服务器处理超时,因为它通常会在Silverlight客户端上优雅地处理超时.这意味着超时由服务器调用活动确定,而不是活动将Silverlight客户端限制(即,访问上下文中的客户端数据).在这三个选项中,我发现第三个是安全性和可用性的最佳平衡,同时不会向应用程序增加不必要的复杂性.为了在全局处理这些服务器端超时,您可以在App.xaml.cs中的Application_unhandleDException方法中添加以下逻辑,或者如果您有一个:

,则在全局视图中加载构造

// Check for Server-Side Session Timeout Exception
 var dex = e.ExceptionObject as DomainOperationException; 
 if ((dex != null) && (dex.ErrorCode == ErrorCodes.NotAuthenticated || dex.ErrorCode == ErrorCodes.Unauthorized) && WebContext.Current.User.IsAuthenticated) 
 {
    // A server-side timeout has occurred.  Call LoadUser which will automatically
    //   authenticate if "Remember Me" was checked, or prompt for the user to log on again
    WebContext.Current.Authentication.LoadUser(Application_UserLoaded, null);
    e.Handled = true; 
 }

以下常量在errorcodes类中定义:

public static class ErrorCodes 
{
     public const int NotAuthenticated = 0xA01;
     public const int Unauthorized = 401; 
}

当服务器端会话超时时,任何后续调用都将返回domainoperationException.通过检查返回的错误代码,您可以确定是否是身份验证错误并相应地处理.在我的示例中,我正在调用webcontext.current.authentication.loaduser(),它可以尝试在可能的情况下重新验证​​用户.即使用户无法自动重新认证,它也会调用回我的application_userloaded方法.我可以检查webcontext.current.user.isauthenticated以确定是否使用先前的操作继续或者我需要重定向到主页并重新调用登录.以下是Appliation_Userloaded回调中某些代码的示例,该回调显示登录对话框如果用户未被验证:

// Determine if the user is authenticated
if (!WebContext.Current.User.IsAuthenticated) 
{
    // Show login dialog automatically
    LoginRegistrationWindow loginWindow = new LoginRegistrationWindow();
    loginWindow.Show(); 
}

要测试代码,您可以将Web.config中的超时值设置为a
小值,因此超时快速发生:

<authentication mode="Forms">   
     <forms name=".Falafel_ASPXAUTH" timeout="1" /> 
</authentication>

如果您想在工作解决方案中看到所有此类代码,请查看我们的 Silverlight RIA模板上的Codeplex .

以上所述是小编给大家介绍的Silverlight RIA服务–如何最好地处理客户授权会话超时?,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!

原文链接:https://77isp.com/post/33930.html

=========================================

https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。