ASP.NET: Why is FormsAuthenticationTicket null aft

2020-04-17 06:18发布

问题:

I'm implementing an authentication timeout detection mechanism per a previous question and answer of mine here. I've implemented an HTTP module that uses the AuthenticateRequest event to run code to capture whether the authentication period has expired. The code to do this is below:

public class AuthenticationModule : IHttpModule
{
    #region IHttpModule Members
    void IHttpModule.Dispose() { }
    void IHttpModule.Init(HttpApplication application)
    {
        application.AuthenticateRequest += new EventHandler(this.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]; // no longer a forms cookie in this array once timeout has expired

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

The problem is that, once the authentication period has expired (I set it to 1 min to test), there is no longer a forms cookie (see comment in code). This means that the authentication cookie will be null, and I won't make it past the null check in my code. But there's a convenient "Expired" property for a FormsAuthenticationTicket that I feel like I should be checking to see if the period is expired. But how do I get that far if the cookie is no longer there? Is it reasonable to assume the authentication period has expired if there's no longer a forms cookie?

Any help would be appreciated on this.

回答1:

You might want to try something like this:

if (User != null)
        {
            FormsIdentity id = (FormsIdentity)User.Identity;
            FormsAuthenticationTicket ticket = id.Ticket;
            if (ticket.Expired)
            {
               //do something
            }
        }

More info

Edit:

1: I see the User will be null. So using User.Identity is out of question.

2: How about trying the code you have in your original question in the BeginRequest event instead of AuthenticateRequest.



回答2:

If If isPersistent is set to false on the FormsAuthenticationTicket then a persistent cookie is not set. When the ticket expires the cookie is not sent with the request, therefore you cannot access it.



回答3:

This behavior is controlled by the System.Web.Security.FormsAuthenticationModule. This module checks if the ticket is expired and in this case remove the cookie.

Note also that this module checks slidingExpiration option and if required renew the ticket.

So back to your question:

Is it reasonable to assume the authentication period has expired if there's no longer a forms cookie?

The response I think is yes.