我正在构建一个使用FormsAuthentication
的ASP.NET网站和一个标准的会话机制,其配置如下:
<authentication mode="Forms">
<forms cookieless="UseCookies" name=".MyAppAuth" loginUrl="~\Login.aspx" timeout="20"/>
</authentication>
...
<sessionState timeout="20" cookieless="UseCookies" />
认证cookie的生命周期似乎不等于用户Session的生命周期。 所以ASP.NET不保证
会话在用户退出时终止,
会话在用户注销前不会终止。
有没有办法自定义FormsAuthentication
或\以及会话状态机制来实现这些目标?
答案 0 :(得分:10)
我多次听过这个问题,我的回答通常是“你为什么要这个?”。一个不需要另一个,它们的到期时间应该使用不同的标准来确定。
会话状态不需要用户登录。应用程序甚至不需要使用身份验证来使用会话状态。即使在登录之前,您也可以拥有一个用户已经在使用会话状态的Web应用程序,并且在注销后仍然可以使用它。这里的“会话”是指客户端(Web浏览器)连接到站点,跳转几页并离开。用户是否登录是无关紧要的。如果您关闭浏览器,打开一个新浏览器,然后返回该站点,则会创建一个新会话。但服务器不知道您关闭了旧浏览器窗口,因此原始会话仍然存在。对于可伸缩性(主要是内存)目的,我们使会话到期并释放其内存和会话跟踪资源。如果客户端花费太长时间来发出新请求,则新请求将创建新会话。
另一方面,您可以使用身份验证,而根本不使用会话状态。我通常启动我的应用程序,会话状态和视图状态都被禁用,只有在真正需要时才会启用它们,并且逐页(或视频状态控制)。
会话到期时间应由每个会话使用的内存,Web服务器上可用的内存,并发用户数以及其他可伸缩性需求决定。它通常在几分钟到一个小时的范围内。
身份验证在客户端上作为cookie保留,并且基本上不会消耗服务器的任何资源。可伸缩性方面,登录到期通常可以比会话到期时间长。实际上,用户可以无限期地保持登录状态。当身份验证过期时间缩短时,通常是出于安全原因。如果您离开计算机15分钟,您不希望您的银行网站帐户可供其他人使用,对吗?您可以登录gmail或Facebook并选择“记住我”并在几天后返回并且仍然登录。但当然这将是一个新会话,因为没有Web应用程序应该保留会议数据几天。
现在,我看到很多人使用相同的时间进行身份验证和会话过期。当用户注销时,许多人还会放弃他们的会话。但是他们忘记了你仍然需要管理用户仍然登录但会话已经过期的情况(在下一个请求中创建一个新的空会话),或者用户的身份验证已过期但不是他们的会话(要求他们再次登录,但要携带旧的未过期会话,可能还有其他用户的敏感数据)。无论您最终为您的申请选择何种超时,处理这些案件都非常重要。
答案 1 :(得分:6)
没有内置机制,因为现实是您希望让用户登录的时间超过您想要保持其会话的时间。此外,会话并不意味着保证存储,您应该避免依赖会话中的数据。
当身份验证Cookie过期时,服务器上没有任何操作。没有跟踪状态。
您可以在处理程序Abandon
中使用“注销”链接,并在FormsAuthentication中使用SignOut
,但没有任何内容可以强制用户从网站注销。
有些人喜欢Session,但是大多数人讨厌或者讨厌它,因为它的使用被滥用了。主要原因是会话过度使用往往是服务器性能低下的原因,不正确的会话使用可能会创建无法扩展的网站。
如果可以,请避免使用Session,如果必须使用Session,请遵守MSDN文章Improving ASP.NET Performance中的建议。另请查看Understanding session state modes + FAQ,特别是问:为什么没有解雇Session_End?
答案 2 :(得分:4)
我有时会问自己这个问题的原因是为了防止访问“过期”的会话对象。 当会话在登录到期之前到期,并且用户请求使用来自会话的数据的页面时,会发生讨厌的空引用异常。
您可能会发现此article有用。它讨论了几种检测过期会话的解决方案,并告知用户。