我的web.config有这个:
<system.web> <sessionState timeout="20"/> <authentication mode="Forms"> <forms name="_ASPXAUTH" timeout="20"/> </authentication>
关于如何在客户端处理auth / session timeout,我已经阅读了很多不同的策略.也就是说:如果客户端空闲x分钟(这里是20),然后他们用触发RIA / WCF调用的UI做一些事情,我想要捕获该事件并适当处理(例如将它们带回到登录屏幕) – 简而言之:我需要一种方法来区分真正的服务器端DomainException与auth失败,因为会话超时.
AFAIK:没有可以确定此问题的类型异常或属性.我能够确定这一点的唯一方法 – 这似乎是一个黑客攻击:是检查错误的消息字符串并查找“拒绝访问”或“拒绝”之类的内容.例如:这样的事情:
if (ex.Message.Contains("denIEd")) // this is probably an auth failure b/c of a session timeout
所以,这就是我目前正在做的事情,如果我使用VS2010的内置服务器运行和调试,或者我在localhost 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,PublicKeyToken=b77a5c561934e089</ExceptionType> <Message></Message> <StackTrace> at System.ServiceModel.domainservices.Hosting.queryOperationBehavior`1.queryOperationInvoker.InvokeCore(Object instance,Object[] inputs,Object[]& outputs) at System.ServiceModel.domainservices.Hosting.DomainoperationInvoker.Invoke(Object instance,Object[]& outputs) at System.ServiceModel.dispatcher.dispatchOperationRuntime.InvokeBegin(MessageRpc& rpc) at System.ServiceModel.dispatcher.ImmutabledispatchRuntime.ProcessMessage5(MessageRpc& rpc) at System.ServiceModel.dispatcher.ImmutabledispatchRuntime.ProcessMessage31(MessageRpc& 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服务器中无效.我在这里缺少一些不起眼的配置设置吗?有没有更好的方法来做到这一点?
解决方法 您现在可能已经知道了,但 this article描述了使用DomainoperationException并检查错误代码.dex.ErrorCode == ErrorCodes.NotAuthenticated || dex.ErrorCode == ErrorCodes.Unauthorized
为方便访问(如果我们无法访问博客),这里是Josh Eastburn撰写的博客文章:
A question that comes up often from developers who are working with Silverlight and WCF RIA Services: why does my Silverlight application throw an exception when it has been IDle for a period of time? As you might expect,it is due to the authenticated session timing out. But it isn’t quite that straightforward. Because Silverlight uses a clIEnt/server architecture,the clIEnt can operate independent of the server for an indefinite period of time. It is only when the Silverlight clIEnt makes a call to the server that the server-sIDe timeout is realized. There are a few options to handle the clIEnt-server timeout issue (and you may be able to come up with a few more): If you aren’t concerned with the security implications of removing a session timeout,you can either increase the timeout setting in web.config,or create a dispatcherTimer in the Silverlight clIEnt that calls a simple method on the server to act as a “Keep Alive.” Add a dispatcherTimer to the Silverlight clIEnt that stays in sync with the server-sIDe timeout and warn/prompt the user keep the session active before the time expires or have them re-authenticate if it has already expired. However,this requires extra effort to keep the timers in sync when new server requests are made. Allow the server to handle the timeout as it normally would and handle the timeout gracefully on the Silverlight clIEnt. This means that the timeout is determined by server call activity,NOT activity confined the Silverlight clIEnt (i.e. accessing clIEnt-sIDe data in the context). Of these three options,I find the third to be the best balance of security and usability while at the same time not adding unnecessary complexity to the application. In order to handle these server-sIDe timeouts globally,you can add the following logic in either the Application_UnhandledException method in App.xaml.cs or in your global viewmodel loading construct if you have one:
// 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; }
The following constants are defined within the ErrorCodes class:
public static class ErrorCodes { public const int NotAuthenticated = 0xA01; public const int Unauthorized = 401; }
When the server-sIDe session times out,any subsequent calls will return a DomainoperationException. By inspecting the returned ErrorCode,you can determine if it is an authentication error and handle it accordingly. In my example,I am calling WebContext.Current.Authentication.LoadUser() which will attempt to re-authenticate the user if possible. Even if the user can not be automatically re-authenticated,it will call back to my Application_UserLoaded method. There I can check WebContext.Current.User.IsAuthenticated to determine whether to proceed with the prevIoUs operation or if I need to redirect back to the home page and reprompt for login. Here is an example of some code in the Appliation_UserLoaded callback that shows a login dialog if the user is not authenticated:
// Determine if the user is authenticatedif (!WebContext.Current.User.IsAuthenticated) { // Show login dialog automatically LoginRegistrationWindow loginWindow = new LoginRegistrationWindow(); loginWindow.Show(); }
To test your code,you can set your timeout value in web.config to a
small value so timeouts occur quickly:
<authentication mode="Forms"> <forms name=".Falafel_ASPXAUTH" timeout="1" /> </authentication>
总结If you’d like to see all of this code in a working solution,check out our 07001.
以上是内存溢出为你收集整理的Silverlight RIA服务 – 如何最好地处理客户端身份验证会话超时?全部内容,希望文章能够帮你解决Silverlight RIA服务 – 如何最好地处理客户端身份验证会话超时?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)