Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preventing FormsAuthentication expiry time from increasing

I have a relatively simple WebForms-based site using Forms Authentication:

<authentication mode="Forms">
  <forms loginUrl="login.aspx" defaultUrl="secure/home.aspx" name=".AdminSite" />
</authentication>

As it's not explicitly mentioned, slidingExpiration is set to true by default, and thus a user is not logged off as long as they're still navigating around the site.

However, I'd like a specific page to not increment the expiry time. Is this possible, either within web.config or in code? The only suggestions I've seen mention setting slidingExpiration to false, which would apply side-wide.

The authentication cookie is set using:

FormsAuthentication.RedirectFromLoginPage(username, False)

and therefore altering the authentication cookie itself isn't practical.

like image 469
Adrian Wragg Avatar asked Nov 10 '15 14:11

Adrian Wragg


1 Answers

The sliding expiration is achieved by the FormsAuthentication module by re-issuing the cookie when necessary. To prevent the sliding, you need to prevent the cookie renewal from happening.

This can be done by simply removing the FormsAuthentication cookie from the response.

Below is the code behind from a very simple web form. The aspx page has a div that shows the output from the Page_Load event.

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        testDiv.InnerHtml = "Hi, cookie is: " + HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName].Value;
        testDiv.InnerHtml += "<br />";
        var ticket = FormsAuthentication.Decrypt( HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName].Value);
        testDiv.InnerHtml += "Expires: " + ticket.Expiration.ToString("yyyy-MM-dd HH:mm:ss");

        if(Response.Cookies.AllKeys.Contains(FormsAuthentication.FormsCookieName))
            testDiv.InnerHtml += "<br />Forms auth is trying to update the cookie in this response";

    }
    protected void Page_Prerender(object sender, EventArgs e)
    {
        if (Response.Cookies.AllKeys.Contains(FormsAuthentication.FormsCookieName))
            Response.Cookies.Remove(FormsAuthentication.FormsCookieName);
    }
}

The Page_Prerender event removes the FormsAuthentication cookie from the response if it's present, thereby preventing the sliding.

I tested this by setting the timeout for the FormsAuthentication to two minutes. Then I start debug and log in. Then I keep refreshing the page in question.

Since FormsAuthentication doesn't update the cookie unless half the expiration time has gone, what happens is that for the first minute, the page will keep showing the same encrypted cookie and the same expires time. After a bit more than one minute, the page will be reporting that FormsAuthentication is trying to renew the cookie. But the Page_Prerender removes the cookie so it doesn't get sent. After another minute you will be redirected to the login page.

Testing the same but removing the Page_Prerender method show that the cookie is changed and the expires time updated after about one minute.

like image 173
user1429080 Avatar answered Oct 23 '22 11:10

user1429080