gpt4 book ai didi

Silverlight RIA 服务 - 如何最好地处理客户端身份验证 session 超时?

转载 作者:行者123 更新时间:2023-12-04 03:56:07 39 4
gpt4 key购买 nike

我使用 Silverlight4、RIA 服务构建了一个应用程序,并且我正在使用 ASP.NET Membership 进行身份验证/授权。

我的 web.config 有这个:

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

我已经阅读了许多关于如何在客户端处理身份验证/ session 超时的不同策略。也就是说:如果客户端空闲 x 分钟(此处为 20 分钟),然后他们对触发 RIA/WCF 调用的 UI 执行了某些操作,我想捕获该事件并进行适当处理(例如,将它们带回登录屏幕)——简而言之:我需要一种方法来区分真正的服务器端 DomainException 与身份验证失败,因为 session 超时。

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, 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 服务器。我在这里缺少一些晦涩的配置设置吗?一般来说,有没有更好的方法来做到这一点?

最佳答案

你现在可能已经明白了,但是 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 authenticated
if (!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 Silverlight RIA Template on CodePlex.

关于Silverlight RIA 服务 - 如何最好地处理客户端身份验证 session 超时?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7948685/

39 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com