Revoke authentication and redirect to login page after FormsAuthentication authenticated user

I need to revoke the authentication cookie if the user no longer exists (or some other condition) after the forms authentication engine has already received the authentication cookie from the browser and confirmed it. That is, here is the use case:

  • The user is authenticated and received a non-expiring auth cookie.
  • A few days later, the user will try to access my web application again, and since the cookie is valid, the forms authentication mechanism will grant access.

  • Now I want to do a second check (whatever condition I want) and decide if I want to let the user continue or de-authenticate.

The question is, is there an official automatic way to do this? So far, I have some possibilities, but I don't know which one is better. I can grab the Authenticate event in global.asax, check whatever I want and cancel I clear the cookie and then one of these:

  • Redirect again to the same url - this should work as this time the forms authentication will fail and will redirect to the login page.

  • Throw some kind of exception ??? which one to do a redirect if I don't elaborate on anything?

  • Somehow get the url of the login page in the config file (any ideas on how / which config descriptor to use) and redirect directly?

  • Some FormsAuthentication class / method that I missed that is for this?

  • Any other idea?

+1


source to share


2 answers


I don't think there is an automated way to achieve this. I think the best way is to add the date to the cookie, which will be the last time you checked if the user exists. Therefore, when a user logs in, you will:

FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
                1, // Ticket version
                name, // Username associated with ticket
                DateTime.Now, // Date/time issued
                DateTime.Now.AddMonths(1), // Date/time to expire
                true, // "true" for a persistent user cookie
                DateTime.Now.ToUniversalTime(), // last time the users was checked
                FormsAuthentication.FormsCookiePath);// Path cookie valid for

        // Encrypt the cookie using the machine key for secure transport
        string hash = FormsAuthentication.Encrypt(ticket);
        HttpCookie cookie = new HttpCookie(
            FormsAuthentication.FormsCookieName, // Name of auth cookie
            hash); // Hashed ticket

        cookie.HttpOnly = true;

        // Set the cookie expiration time to the tickets expiration time
        if (ticket.IsPersistent) cookie.Expires = ticket.Expiration;
        //cookie.Secure = FormsAuthentication.RequireSSL;
        Response.Cookies.Add(cookie);

      

Then, every time the user authenticates, you can check the additional date you passed into the authentication ticket and, at 10 minute intervals or less, double check against the database if the user exists. The code might look something like this:



public void FormsAuthentication_OnAuthenticate(object sender, 
                           FormsAuthenticationEventArgs args)
    {
        if (FormsAuthentication.CookiesSupported)
        {
            if (Request.Cookies[FormsAuthentication.FormsCookieName] != null)
            {
                try
                {
                    FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(
                      Request.Cookies[FormsAuthentication.FormsCookieName].Value);

                    DateTime lastCheckedTime = DateTime.TryParse(ticket.UserData);
                    TimeSpan elapsed = DateTime.Now - lastCheckedTime;
                    if (elapsed.TotalMinutes > 10)//Get 10 from the config
                    {
                        //Check if user exists in the database. 
                        if (CheckIfUserIsValid())
                        {
                            //Reset the last checked time
                            // and set the authentication cookie again
                        }
                        else
                        {
                            FormsAuthentication.SignOut();
                            FormsAuthentication.RedirectToLoginPage();
                            return;
                        }
                    }

                }
                catch (Exception e)
                {
                    // Decrypt method failed.
                }
            }
        }
    }

      

You can even cache users who have been deleted in the last 10 minutes and check them against this collection.

Hope it helps.

+3


source


If you are rejecting the cookie for any other reason other than an expired session, then I think you should redirect the user to a page that describes what they need to do to gain access. If logging back in is enough, then the login page is sufficient. It sounds, however, like there are conditions under which it is impossible to simply log in again. In these cases, it would be better to redirect the user to a suitable error page that describes why they cannot access the site and explains how to access the site again (if possible).



0


source







All Articles