如何同步表单身份验证 cookie 和 Asp.Net 会话的生命周期?
我正在构建一个 ASP.NET 网站,该网站使用 FormsAuthentication
和标准会话机制,其配置如下:
<authentication mode="Forms">
<forms cookieless="UseCookies" name=".MyAppAuth" loginUrl="~\Login.aspx" timeout="20"/>
</authentication>
...
<sessionState timeout="20" cookieless="UseCookies" />
看来身份验证 cookie 的生命周期不等于用户会话的生命周期。 因此 ASP.NET 不保证
Session 在用户注销时终止,
Session 在用户注销之前不会终止。
有没有办法自定义 FormsAuthentication
或\和会话状态机制来实现这些目标?
I am building an ASP.NET web site that uses FormsAuthentication
and a standard Session mechanism with configuration like:
<authentication mode="Forms">
<forms cookieless="UseCookies" name=".MyAppAuth" loginUrl="~\Login.aspx" timeout="20"/>
</authentication>
...
<sessionState timeout="20" cookieless="UseCookies" />
It seems that the lifetime of an authentication cookie is not equal to the lifetime of the user Session.
So ASP.NET doesn't guarantee that
Session terminates when user logout,
Session doesn't terminates before user logout.
Is there a way to customize FormsAuthentication
or\and the Session State mechanism to Reach these goals?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我多次听到这个问题,我的回答通常是“你为什么想要这个?”。 一个不需要另一个,并且它们的过期时间应使用不同的标准来确定。
会话状态不需要用户登录。应用程序甚至不需要使用身份验证来使用会话状态。 您可以拥有一个 Web 应用程序,其中用户甚至在登录之前就已经在使用会话状态,并且在注销后仍在使用它。 这里的“会话”是指客户端(网络浏览器)连接到站点、跳转几个页面然后离开。 用户是否登录无关紧要。 如果您关闭浏览器,打开一个新浏览器,然后返回该站点,则会创建一个新会话。 但服务器不知道您关闭了旧的浏览器窗口,因此原始会话仍然存在。 出于可扩展性(主要是内存)的目的,我们使会话过期并释放其内存和会话跟踪资源。 如果客户端花费太长时间来发出新请求,则新请求将创建一个新会话。
另一方面,您可以使用身份验证而不使用会话状态。 我通常在禁用会话状态和视图状态的情况下启动应用程序,并且仅在确实需要时逐页启用它们(或逐个控制视图状态)。
会话过期时间应根据每个会话使用的内存、Web 服务器上的可用内存、并发用户数以及其他可扩展性需求来确定。 它通常在几分钟到一个小时的范围内。
身份验证作为 cookie 保留在客户端上,基本上不会消耗服务器的任何资源。 从可扩展性角度来看,登录过期时间通常比会话过期时间长。 事实上,用户可以无限期地保持登录状态。 当身份验证过期时间较短时,通常是出于安全原因。 如果您离开计算机 15 分钟,您不希望其他人可以使用您的银行网站帐户,对吗? 您可以登录 gmail 或 facebook,然后选择“记住我”,几天后返回,您仍然处于登录状态。当然,这将是一个新会话,因为任何网络应用程序都不应保留几天的会话数据。
现在,我看到很多人使用相同的时间长度进行身份验证和会话过期。 当用户注销时,许多人还会 Abandon() 或 Clear() 他们的会话。 但他们忘记了,您仍然需要管理用户仍然登录但会话已过期的情况(这会在下一个请求时创建一个新的空会话),或者当用户的身份验证已过期,但其会话并未过期(要求他们再次登录,但会保留旧的未过期会话,其中可能包含其他用户的敏感数据)。 无论您最终为应用程序选择何种超时,处理这些情况都非常重要。
I've heard this question many times, my answer is usually "why would you want this?". One does not require the other and their expiration times should be determined using different criteria.
Session state does not require a user to be logged in. An app doesn't even need to use authentication to use session state. You can have a web app where a user is already using session state even before logging in, and still using it after logging out. A "session" here is when a client (web browser) connects to a site, jumps around a few pages, and leaves. Whether a user is logged in or not is irrelevant. If you close your browser, open a new one, and go back to the site, a new session is created. But the server doesn't know you closed your old browser window, so the original session still exists. For scalability (mainly memory) purposes, we expire our sessions and free its memory and session-tracking resources. If a client takes too long to make a new request, the new request will create a new session.
On the other hand, you can use authentication and not use session state at all. I usually start my apps with both session state and viewstate disabled and only enabled them if really needed and on a page-by-page basis (or control-by-control for viewstate).
Session expiration time should be determined by the memory used by each session, the memory available on the web server, number of concurrent users, and other scalability needs. It is usually in the range of a few minutes to an hour.
Authentication is persisted as a cookie on the client and basically doesn't consume any resources the server. Scalability-wise, login expiration can usually be longer than session expiration. In fact a user can stay logged in indefinitely. When authentication expiration is kept shorter, it is usually for security reasons. You don't want your bank web site account to be available to someones else if you move away from your computer for 15 mins, right? You can log into gmail or facebook and select "remember me" and return a few days later and you are still logged in. But of course this would be a new session because no web app should hold on to session data for a few days.
Now, I've seen lots of people use the same length of time for authentication and session expiration. And many also Abandon() or Clear() their session when a user logs out. But they forget however that you still need to manage the case where the user is still logged in but the session has expired (which creates a new empty session on the next request), or when a user's authentication expired but not their session (requiring them to log in again, but carrying around an old un-expired session, possibly with another user's sensitive data). Taking care of these cases is very important, no matter what timeouts you ultimately choose for your application.
没有内置机制,因为现实情况是您希望用户保持登录的时间比您希望保持他们的会话的时间长。 此外,会话并不意味着保证存储,您应该避免对会话中数据的任何依赖。
当身份验证 cookie 过期时,服务器上不会发生任何事情。 没有跟踪状态。
您可以有一个“注销”链接,并在处理程序中
放弃
会话并从 FormsAuthenticationSignOut
,但没有任何东西可以强制用户从网站注销。有些人喜欢 Session,但大多数人讨厌或开始讨厌它,因为它的使用被滥用。 主要原因是会话过度使用往往会导致服务器性能不佳,而错误的会话使用可能会创建无法扩展的网站。
如果可以,请避免使用 Session;如果必须使用它,请遵守 MSDN 文章 提高 ASP.NET 性能。 另请参阅了解会话状态模式 + 常见问题解答,特别是问:为什么 Session_End 没有被触发?
There's no inbuilt mechanism because the reality is you want to keep users logged in for longer than you want to keep their sessions around for. Also, sessions are not meant to be guaranteed storage, and you should avoid any reliance on data being in session.
Nothing happens on the server when an authentication cookie expires. There is no tracked state.
You could have a 'logout' link and in the handler
Abandon
the session andSignOut
from FormsAuthentication, but there's nothing that forces a user to log out from a website.Some people like Session, however most hate or come to hate it because its use is abused. Main reasons are Session overuse tends to be the cause of poorly performing servers, and incorrect Session use can create websites that won't scale.
Avoid the use of Session if you can, and if you must use it, observe the recommendations in the MSDN article Improving ASP.NET Performance. Also have a look at Understanding session state modes + FAQ and in particular Q: Why isn't Session_End fired?
我有时问自己这个问题的原因是为了防止访问“过期”会话对象。
当会话在登录过期之前过期,并且用户请求使用会话中的数据的页面时,会发生令人讨厌的空引用异常。
您可能会发现这个
The reason I sometimes ask myself this question, is to prevent accessing "expired" session objects.
When the session expires prior to login expiration, and the user requests a page that uses data from the session, a nasty null reference exception happens.
You may find this article helpful. It discusses several solutions to detect expired sessions and inform the user about that.