views:

685

answers:

1

(See question below for more context):

Are there any situations in which

<machineKey
      validationKey="AutoGenerate,IsolateApps"
      decryptionKey="AutoGenerate,IsolateApps"/>

in web.config would fail to AutoGenerate a new machineKey on App Pool recycle? This is the behavior I'm seeing...


I'm using standard ASP.NET FormsAuthentication in an MVC app. If I log a user in using FormsAuthentication.GetAuthCookie and don't use a persistent cookie (relying on the browser's session to remember my authorized state), I would expect recycling the IIS App Pool to invalidate the session's knowledge of this cookie...and thus logout all users who don't have persistent cookies.

This DOES happen on one of my IIS installs (XP), but on a different IIS configuration (Server 2K3) the FormsAuthentication cookie (under the standard name ".ASPXAUTH") remains valid and continues to authorize the user.

Does anyone know why this is happening or what configuration controls this behavior?

Obviously recycling the app pool has no control over whether or not the browser still sends the .ASPXAUTH cookie (as long as I haven't closed my browser and the cookie hasn't expired).

In the case of the IIS install that properly denies authentication after a recycle, I can see the incoming cookie in Request.Cookies during the Application_BeginRequest event...but once control moves to the next event available in Global.asax.cs (Application_AuthenticateRequest), the cookie has been removed from the Request.Cookies collection.

Why does this not happen for both IIS/ASP.NET configurations?


In case this isn't clear, a simpler way of forming the question is:

Why does HttpContext.Current.Request.Cookies[".ASPXAUTH"] change from {System.Web.HttpCookie} to null when I step, in a single request, from Application_BeginRequest to Application_AuthenticateRequest?


More debugging information:

If I attach the following code to Global.asax.cs's FormsAuthentication_OnAuthenticate event...

var cookie = Request.Cookies[FormsAuthentication.FormsCookieName];
if (cookie != null)
{
    var val = cookie.Value;
    try
    {
        FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(val);
    }
    catch (Exception)
    {
    }
}

...then during a request before I recycle the IIS App Pool, no exception will be caught. After recycling the IIS App Pool, when the exact same .ASPXAUTH cookie is sent from the browser, a Cryptographic exception is caught ("Padding is invalid and cannot be removed.")

Why is this?

A: 

Forms Authentication cookies have nothing to do with Session state.

John Saunders
1) Recycling your app pool does recycle your session (if you're using InProc session management), and this apparently *does* sometimes manipulate the ASPXAUTH cookie (as seen when it is removed after the BeginRequest event).2) I'll make my question more clear by indicating "browser session." From MS documentation:createPersistentCookieType: System.Booleantrue to create a durable cookie (one that is saved across browser sessions); otherwise, false.
kamens
Nonsense. Cookies reside on clients. Nothing you can do to the server will remove the cookies stored on the clients.
John Saunders
You'd think so, right? The cookie is not being removed from the server until Application_BeginRequest is finished. I know how ridiculous this sounds, which is why I'm posting this question. I have a debugger up, and when I step from Application_BeginRequest to Application_AuthenticateRequest, the value of HttpContext.Current.Request.Cookies[".ASPXAUTH"] changes from {System.Web.HttpCookie} to null.
kamens
...the client obviously still sends the cookie. It's always in the browser and in the request. But it's hidden from the majority of the server-side processing of the request due to this removal.
kamens
Ok, you're confused between HttpContext.Current.Request.Cookies[".ASPXAUTH"], and what's on the client. It doesn't matter about this collection on the server. The client is going to send you that cookie on the next request.
John Saunders
No, I'm really not. The question is simply this: why does HttpContext.Current.Request.Cookies[".ASPXAUTH"] changes from {System.Web.HttpCookie} to null when I step, in a single request, from Application_BeginRequest to Application_AuthenticateRequest?
kamens
Ok, I see now that you've cleared it up. Are you sure the cookies are available so early in the pipeline?Maybe check before Authenticate event to see if cookies are present at that time.
John Saunders
I just added the "More debugging information" to the question above which somewhat answers this question. The cookie is still visible in Request.Cookies during FormsAuthenticate_OnAuthenticate...but if the App Pool has been recycled since the cookie was handed out, it is removed from .Cookies after this event is finished.
kamens
You also got an exception after the recycle, so it's not unexpected for it to be removed. More importantly, your exception is no doubt due to the cookie being signed with a per-AppDomain value. If that changes (as it will on a recycle), then it will be impossible for the new AppDomain to decipher the old AppDomain's encrypted cookie.
John Saunders
Yeah, exactly! I agree. So my only question is: why doesn't this happen for one of my IIS configurations? I want it to happen everywhere, because it makes total sense to me. It seems as though in the 2K3 IIS, it's either not using a per-AppDomain value when signing, or is somehow restoring it after App Pool recycle...not sure.
kamens
I don't know. Maybe this depends on the timing. Check the machine.config for the setting of machineKey.
John Saunders
Unfortunately, even w/ a setting of machineKey.validationKey="AutoGenerate,IsolateApps" and machineKey.decryptionKey="AutoGenerate,IsolateApps", this behavior continues.
kamens
Sorry, my question was are these settings the same across all the servers.
John Saunders
As far as I can tell, yes. Identical web.configs. Is there any way to tell what machineKey value is _actually_ being used, in case it's being overridden somewhere that I don't know about? It sure is behaving like AutoGenerate isn't on or isn't working.
kamens