Re: Forms Authentication - Not timing out, not redirecting.
From: AVance (Aaron_at_noemail.nospam)
Date: 07/28/04
- Next message: Mike Preradovic: "Can't access COM+ Server in ASP.NET Page"
- Previous message: Joe Kaplan \(MVP - ADSI\): "Re: Query AD using Integrated Authentication?"
- In reply to: AVance: "Forms Authentication - Not timing out, not redirecting."
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
Date: Wed, 28 Jul 2004 15:23:22 -0500
Am I supposed to be hearing back from a Microsoft person on this within 2
business days using the MSDN Universal newsgroup MSDN stuff?
"AVance" <Aaron@noemail.nospam> wrote in message
news:%23vh0W8bcEHA.2944@TK2MSFTNGP11.phx.gbl...
> Hi,
> I've come across this scenario in ASP.NET 1.1 with forms
authentication
> where the forms auth doesn't seem to timeout correctly, nor redirect to
the
> login page.
>
> I have done some testing, and I believe I've found a solution, but I
> would like some insight from Microsoft on whether the code I've
implemented
> is correct, and why it is even working.
>
> Here is my scenario:
>
> I initially implemented forms auth using the standard forms auth
> declaration in web.config and it worked fine, and redirected alright.
Then,
> as I began going through my code during my security reviews I implemented
> the encrypted auth ticket as described in the "Building Secure ASP.NET
> Applications" on page 378 (document page number, not the PDF page number).
> In this scenario, it describes how to build the login event from the login
> page, as well as implementing the "Application_AuthenticateRequest" event
in
> the global.asax code.
>
> Once I implemented that code, my forms auth stopped working. The
ticket
> was still valid after my timeout, and I was never redirected to the
> specified login page. I was implementing SessionState with the same
timeout
> as the formsauth, and my session was timing out properly! I was also
using
> a non-persistent formsauth cookie. After going back over the
documentation
> several many times, and making sure I was implementing it as described, I
> believe I found a problem with the code in the document. However, I don't
> want to go as far as saying the code is wrong, but I've come up with a fix
> that makes it work - but now I don't understand exactly why it fixes it.
>
> Basically in Application_AuthenticateRequest, once the ticket is
> decrypted from the cookie the code checks whether the ticket is null to
> determine if there was one available. If it is, return. After that, it
> extracts the roles, and sets up the HttpContext user identity information.
> All fine and dandy. However, nobody checks whether the authTicket has
> actually expired yet! So, immediately after the null=authTicket check, I
> inserted a check whether the authTicket had expired, and it now works.
>
> I understand sort-of why this works, but then I decided to go in with
> Reflector and look at the FormsAuthenticationModule class and look at it's
> "OnAuthenticate" event. In there, the framework checks whether it is
> expired, et. al., exactly like I made my code do in Global.asax.
>
> After doing some further research on the ASP.NET HTTP Pipeline, I see
> that the application gets the pipeline call first, and passes it on to
it's
> modules. Then I read that global.asax's Authenticate_Request is called by
> the security module that is in place - which in this case is the
> FormsAuthenticationModule. Now if the FormsAuthenticationModule is doing
> it's check, and then passing it onto my global.asax Authenticate_Request
> code - wouldn't FormsAuthModule already have figured out the ticket was
> expired and done something about it?
>
> Or is it the fact that since I have implemented
> Application_AuthenticateRequest - that my code then has some sort of
> precedence?
>
> My guess is this: Since the COOKIE is actually a non-persistent
cookie,
> it is valid while the browser is open. Thus, this entire time the cookie
is
> actually there, just not expired. Then in the
> Application_AuthenticateRequest code, the authTicket is always extracted
> (because we have a browser cookie full of encrypted data). But at the
> FormsAuthentication level, which we're really concerned about, the
> authTicket has expired - which is a separate expiration from the actual
> cookie expiration. But nobody is checking for that. Thus, I get the
> authTicket out of the cookie every time, and then fill the Identity object
> on the current HttpContext every time. Even if it has really expired. So
> when I place the additional check for expiration in there, it works as it
is
> supposed to.
>
> I am glad the code works - but I'm primarily confused as to the why.
> Was there a reason that the "Building Secure ASP.NET Applications" article
> presented the code as it did? Or did I really find a bug in that code? I
> guess I'm fairly concerned if the code is incomplete - the document has
been
> out for some time? Am I the first to run across this?
>
> Additional question: Do I also need to conditionally update my
> slidingTimeout in this code as well to match the FormsAuthenticationModule
> "OnAuthenticate" code? Or will something else do this for me? From my
> testing, it appears to be renewed for me, but I wanted to make sure this
> wasn't some sort of fluke as well.
>
> Here is my Application_AuthenticateRequest code:
>
> protected void Application_AuthenticateRequest(Object sender, EventArgs e)
> {
>
> string cookieName = FormsAuthentication.FormsCookieName;
>
> HttpCookie authCookie = Context.Request.Cookies[ cookieName ];
>
> if( null == authCookie ) {
>
> return;
>
> }
>
> FormsAuthenticationTicket authTicket = null;
>
> try {
>
> authTicket = FormsAuthentication.Decrypt( authCookie.Value );
>
> }
>
> catch( Exception ex ) {
>
> AppHelper.LogEvent( ex.ToString(), 3 );
>
> return;
>
> }
>
> if( (null == authTicket) || authTicket.Expired ) {
>
> return;
>
> }
>
> string[] roles = authTicket.UserData.Split( new char[]{'|'} );
>
> FormsIdentity id = new FormsIdentity( authTicket );
>
> GenericPrincipal principal = new GenericPrincipal( id, roles );
>
> Context.User = principal;
>
> }
>
>
- Next message: Mike Preradovic: "Can't access COM+ Server in ASP.NET Page"
- Previous message: Joe Kaplan \(MVP - ADSI\): "Re: Query AD using Integrated Authentication?"
- In reply to: AVance: "Forms Authentication - Not timing out, not redirecting."
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
Relevant Pages
|