views:

241

answers:

1

I have a site that works as expected on my development box. That is, the formsauthentication ticket expires after 30 days. This is achieved through the following code

string roles = UserManager.getAuthenticationRoleString(txtUsername.Text);

HttpCookie formscookie = FormsAuthentication.GetAuthCookie(txtUsername.Text, true);

FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(formscookie.Value);

FormsAuthenticationTicket newticket = new FormsAuthenticationTicket(1, ticket.Name, DateTime.Now, DateTime.Now.AddDays(30), true, roles, ticket.CookiePath);

HttpCookie newCookie = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(newticket));
newCookie.Expires = DateTime.Now.AddDays(30);
Response.Cookies.Add(newCookie);

I used fiddler to check that the expiration is set properly and I get this

.ASPXAUTH=84AB5430CF4B1C5F9B59C9285288B41F156FCAFA2A169EACE17A7778A392FA69F66770FD8A08FFD06064B00F0BD788FEEC4A5894B7089239D6288027170A642B3B7EB7DB4806F2EBBCF2A82EE20FD944A38D2FE253B9D3FD7EFA178307464AAB4BCB35181CD82F6697D5267DB3B62BAD; expires=Thu, 21-Jan-2010 18:33:20 GMT; path=/; HttpOnly

So I would expect it to expire in 30 days...But it only makes it about 30 minutes.

I have 3 other interesting tidbits about my environment / code

  1. On the production box there are two sites pointing at the same code one for external access and one for internal access

  2. When the I do get the login page because of premature expiration, the .ASPAUTH cookie is still there and sent to the browser

  3. There is some role checking in the global.asax that looks like this

-

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
    {

        if (HttpContext.Current.User != null)
        {
            if (HttpContext.Current.User.Identity.IsAuthenticated)
            {
                if (HttpContext.Current.User.Identity is FormsIdentity)
                {
                    FormsIdentity id = (FormsIdentity)HttpContext.Current.User.Identity;
                    FormsAuthenticationTicket ticket = id.Ticket;

                    // Get the stored user-data, in this case, our roles
                    string userData = ticket.UserData;
                    string[] roles = userData.Split('|');
                    HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(id, roles);
                }
            }
        }
    }
A: 

If the problem is that the user on the production box is kicked and has to log in again via FormsAuthentication, it's possible that the problem is IIS related and not .NET.

I've run into issues before where all the timeout settings in the world within the app didn't make a difference and the user was booted far too early.

Check your IIS settings for both the website and the application pool. There are settings in both related to timeouts, etc.

If II6:

  • Under website properties -> Home Directory tab -> Configuration Button -> Options Tab -> there is session state/length info here
  • Under application pool for your site -> Performance and Health tabs -> both have several settings that may recycle your pool (and essentially force a re-logon)

To debug, you could disable all health and performance checks on the pool, however be very careful as this could throttle your server if the app gets out of control.

You could also try putting the timeout settings in the web.config:

<system.web>
    <authentication mode="Forms">
          <forms timeout="XXXXX"/>
    </authentication>
</system.web>

Anyway just some ideas from personal experience of similar issues. Hope it might help!

KP
It's IIS 7 and it is running in classic mode.I have this in Web.config...But I think it's moot since I am setting it specifically through code<authentication mode="Forms"> <forms loginUrl="login.aspx" timeout="1000000" /> </authentication>
Paul