ASP.NET:如何检测身份验证超时

时间:2021-03-30 03:33:47

I've seen multiple articles like this one that explain how to detect that a user's session has timed out. And for clarity's sake, these articles are referring to the timeout value defined by this web.config line:

我已经看过多篇像这样的文章解释了如何检测用户的会话已经超时。为清楚起见,这些文章指的是此web.config行定义的超时值:

<sessionState mode="InProc" cookieless="UseDeviceProfile" timeout="120" />

Not to get into that method too much, but this involves checking that Session.IsNewSession is true and that a session cookie already exists. But I haven't seen any articles on how to detect authentication timeout -- the one defined by this web.config line:

不要过多地使用该方法,但这涉及检查Session.IsNewSession是否为true以及会话cookie是否已存在。但我还没有看到任何关于如何检测身份验证超时的文章 - 这个web.config行定义的文章:

<authentication mode="Forms">
    <forms loginUrl="~/Home/Customer" timeout="60" name=".ASPXAUTH" requireSSL="false" slidingExpiration="true" defaultUrl="~/Home/Index" cookieless="UseDeviceProfile" enableCrossAppRedirects="false"/>
</authentication>

Multiple articles online, including this SO post, have said that your Session timeout value should generally be double your Authentication timeout value. So right now, as above, my Session is 120 and my Authentication is 60. This means that I'll never get in a situation where the Session has timed out, but the user is still Authenticated; if the user ever times out, it will be due to Authentication, not Session.

在线多篇文章,包括这篇SO帖子,都说你的会话超时值通常应该是你的身份验证超时值的两倍。所以现在,如上所述,我的会话是120,我的身份验证是60.这意味着我永远不会遇到会话超时的情况,但用户仍然是经过身份验证的;如果用户超时,那将是由于身份验证,而不是会话。

So, like everyone else, I'm interested in how to report to the user that their session has timed out (but really it'll be due to the Authentication timeout). Does anyone know of a way to accomplish this, or any resources online that can point me to a solution?

所以,和其他人一样,我对如何向用户报告他们的会话超时(但实际上这是由于身份验证超时)感兴趣。有没有人知道如何实现这一目标,或任何可以指向我解决方案的在线资源?

3 个解决方案

#1


1  

This is probably not the optimum approach, but here's something I thought of.

这可能不是最佳方法,但这是我想到的。

On login, record a timestamp in the session marking when the user logged in. On each subsequent request (maybe in the global.asax BeginRequest?), compare this timestamp to the current time, and match this up with the authentication timeout (Scott Hanselman explains how to read it here).

登录时,在用户登录时记录会话标记中的时间戳。在每个后续请求(可能在global.asax BeginRequest?中)中,将此时间戳与当前时间进行比较,并将其与身份验证超时相匹配(Scott Hanselman)解释如何在这里阅读)。

That's my "off top of my head" thought anyhow...

这无论如何都是我的“头脑中”的想法......

#2


1  

I would leverage the http pipeline early in the request and send an apporpriate response.
My source for answering such questions is:

我会在请求的早期利用http管道并发送一个适当的响应。我回答这些问题的来源是:

Professional ASP.NET 2.0 Security, Membership, and Role Management

专业的ASP.NET 2.0安全性,成员资格和角色管理

An HTTP module might do the trick:

HTTP模块可能会做到这一点:

Web.config:

<configuration>
  <system.web>
    <httpModules>
      <add name="MyAuthModule" type="MyAssembly.Security.MyAuthModule, MyAssembly"/>

...

The Actual HTTP Module:

实际HTTP模块:

/// <summary>
/// A module for detecting invalid authentication 
/// </summary>
/// <remarks>See "How To Implement IPrincipal" in MSDN</remarks>
public class MyAuthModule : IHttpModule
{
    #region IHttpModule Members
    void IHttpModule.Dispose() { }
    void IHttpModule.Init(HttpApplication context)
    {
        context.AuthenticateRequest += new EventHandler(context_AuthenticateRequest);
    }
    #endregion


    /// <summary>
    /// Inspect the auth request...
    /// </summary>
    /// <remarks>See "How To Implement IPrincipal" in MSDN</remarks>
    private void context_AuthenticateRequest(object sender, EventArgs e)
    {
        HttpApplication a = (HttpApplication)sender;
        HttpContext context = a.Context;

        // Extract the forms authentication cookie
        string cookieName = FormsAuthentication.FormsCookieName;
        HttpCookie authCookie = context.Request.Cookies[cookieName];

        if (authCookie != null)
        {
            FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
            // check if previously authenticated session is now dead
            if (authTicket != null && authTicket.expired)
            {
               // send them a Response indicating that they've expired.
            }
        }
    }
}

Good luck!

#3


1  

When you log the user, you could drop a cookie on the user's machine indicating that they had a session. When the user reaches the login page (because if their session expired, their login must also have), check to see if the user has that cookie and if they have any of the session keys you expect them to have (if this proves difficult, just set a session variable when they log in). if they have the cookie, but none of the session keys, then their session expired.

当您记录用户时,您可以在用户的​​计算机上删除一个cookie,表明他们有会话。当用户到达登录页面时(因为如果他们的会话过期,他们的登录也必须有),检查用户是否有该cookie以及他们是否拥有您期望他们拥有的任何会话密钥(如果这证明很难,只需在登录时设置会话变量即可。如果他们有cookie,但没有会话密钥,那么他们的会话就会过期。

#1


1  

This is probably not the optimum approach, but here's something I thought of.

这可能不是最佳方法,但这是我想到的。

On login, record a timestamp in the session marking when the user logged in. On each subsequent request (maybe in the global.asax BeginRequest?), compare this timestamp to the current time, and match this up with the authentication timeout (Scott Hanselman explains how to read it here).

登录时,在用户登录时记录会话标记中的时间戳。在每个后续请求(可能在global.asax BeginRequest?中)中,将此时间戳与当前时间进行比较,并将其与身份验证超时相匹配(Scott Hanselman)解释如何在这里阅读)。

That's my "off top of my head" thought anyhow...

这无论如何都是我的“头脑中”的想法......

#2


1  

I would leverage the http pipeline early in the request and send an apporpriate response.
My source for answering such questions is:

我会在请求的早期利用http管道并发送一个适当的响应。我回答这些问题的来源是:

Professional ASP.NET 2.0 Security, Membership, and Role Management

专业的ASP.NET 2.0安全性,成员资格和角色管理

An HTTP module might do the trick:

HTTP模块可能会做到这一点:

Web.config:

<configuration>
  <system.web>
    <httpModules>
      <add name="MyAuthModule" type="MyAssembly.Security.MyAuthModule, MyAssembly"/>

...

The Actual HTTP Module:

实际HTTP模块:

/// <summary>
/// A module for detecting invalid authentication 
/// </summary>
/// <remarks>See "How To Implement IPrincipal" in MSDN</remarks>
public class MyAuthModule : IHttpModule
{
    #region IHttpModule Members
    void IHttpModule.Dispose() { }
    void IHttpModule.Init(HttpApplication context)
    {
        context.AuthenticateRequest += new EventHandler(context_AuthenticateRequest);
    }
    #endregion


    /// <summary>
    /// Inspect the auth request...
    /// </summary>
    /// <remarks>See "How To Implement IPrincipal" in MSDN</remarks>
    private void context_AuthenticateRequest(object sender, EventArgs e)
    {
        HttpApplication a = (HttpApplication)sender;
        HttpContext context = a.Context;

        // Extract the forms authentication cookie
        string cookieName = FormsAuthentication.FormsCookieName;
        HttpCookie authCookie = context.Request.Cookies[cookieName];

        if (authCookie != null)
        {
            FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
            // check if previously authenticated session is now dead
            if (authTicket != null && authTicket.expired)
            {
               // send them a Response indicating that they've expired.
            }
        }
    }
}

Good luck!

#3


1  

When you log the user, you could drop a cookie on the user's machine indicating that they had a session. When the user reaches the login page (because if their session expired, their login must also have), check to see if the user has that cookie and if they have any of the session keys you expect them to have (if this proves difficult, just set a session variable when they log in). if they have the cookie, but none of the session keys, then their session expired.

当您记录用户时,您可以在用户的​​计算机上删除一个cookie,表明他们有会话。当用户到达登录页面时(因为如果他们的会话过期,他们的登录也必须有),检查用户是否有该cookie以及他们是否拥有您期望他们拥有的任何会话密钥(如果这证明很难,只需在登录时设置会话变量即可。如果他们有cookie,但没有会话密钥,那么他们的会话就会过期。