AuthenticateRequest Before or After User has been Authenticated?

Discussion in 'ASP .Net Security' started by Tyler Carver, Feb 28, 2006.

  1. Tyler Carver

    Tyler Carver Guest

    I'm implementing an HttpModule for authorization. I want to authorize the
    user after I know they have been authenticated. The documentation for the
    HttpApplication AuthenticateRequest event states:

    The AuthenticateRequest event signals that the configured authentication
    mechanism has authenticated the current request. Subscribing to the
    AuthenticateRequest event ensures that the request will be authenticated
    prior to processing the attached module or event handler.

    This leads me to believe that a user would be authenticated before the
    AuthenticationRequest event is fired. However, this is not the case when I
    run the code. If I set a location as <deny users="?"/> and then set a
    handler for the AuthenticateRequest event, my handler gets called with the
    URL before the login screen allows the user to authenticate. If I set the
    event in the AuthorizeRequest handler then it works as I want, the user is
    first redirected to the login page and then after he authenticates I get the
    URL in my handler.

    Is the documentation wrong? Shouldn't forms authentication route the user
    to the loginUrl page before the AuthorizationRequest event occurs if the user
    is not authorized?

    Thanks,
    Tyler


    --
    ------------------
    Tyler Carver
    tylercarver.com
    Tyler Carver, Feb 28, 2006
    #1
    1. Advertising

  2. Hi,

    events in the http pipeline get always fired - if you subscribe to one, you
    get called. The AuthenticateRequest event is always handled by the built
    in authentication module (FormsAuthenticationModule in your case) - and if
    you have not reordered the pipeline your code (either in global.asax or a
    HttpModule) runs after the built-in one.

    You will be called regardless of authentication has taken place (e.g. in
    the case of an anonymous request) so if you have to do any work that relies
    on an authenticated user, do a

    if (Request.IsAuthenticated)
    {}

    The first request to an app and the redirect (up to where the formsauth ticket
    is placed) are anonymous request - thats why you have to check that.

    at the beginning of your code.

    The same applies also for AuthorizeRequest - you get called on every request,
    but you can be sure the the File and UrlAuthorizationModule already did their
    work.

    ---------------------------------------
    Dominick Baier - DevelopMentor
    http://www.leastprivilege.com

    > I'm implementing an HttpModule for authorization. I want to authorize
    > the user after I know they have been authenticated. The documentation
    > for the HttpApplication AuthenticateRequest event states:
    >
    > The AuthenticateRequest event signals that the configured
    > authentication mechanism has authenticated the current request.
    > Subscribing to the AuthenticateRequest event ensures that the request
    > will be authenticated prior to processing the attached module or event
    > handler.
    >
    > This leads me to believe that a user would be authenticated before the
    > AuthenticationRequest event is fired. However, this is not the case
    > when I run the code. If I set a location as <deny users="?"/> and
    > then set a handler for the AuthenticateRequest event, my handler gets
    > called with the URL before the login screen allows the user to
    > authenticate. If I set the event in the AuthorizeRequest handler then
    > it works as I want, the user is first redirected to the login page and
    > then after he authenticates I get the URL in my handler.
    >
    > Is the documentation wrong? Shouldn't forms authentication route the
    > user to the loginUrl page before the AuthorizationRequest event occurs
    > if the user is not authorized?
    >
    > Thanks,
    > Tyler
    Dominick Baier [DevelopMentor], Feb 28, 2006
    #2
    1. Advertising

  3. Tyler Carver

    Tyler Carver Guest

    Re: AuthenticateRequest Before or After User has been Authenticate

    Hi, Dominick, thanks for the response.

    "Dominick Baier [DevelopMentor]" wrote:
    > You will be called regardless of authentication has taken place (e.g. in
    > the case of an anonymous request) so if you have to do any work that relies
    > on an authenticated user, do a
    > ...
    > The same applies also for AuthorizeRequest - you get called on every request,
    > but you can be sure the the File and UrlAuthorizationModule already did their
    > work.


    I think you are right. I think what I was expecting was for the redirect to
    happen before the AuthenticateRequest was called. I guess what the
    documentation is saying is that the user has been tested for Authentication
    before the Authentication Request event but he may have failed. The redirect
    to the login URL must happen after the PostAuthenticateRequest event and
    before the AuthorizeRequest event.

    You can easily test this. Create a web app with one login page login.aspx
    and a default page default.aspx, then set the default.aspx to deny users=?,
    finally add an HttpModule and catch the AuthenticateRequest event. You will
    see to URL's called in your handler, the default.aspx and then the
    login.aspx. The user is not authenticated before the AuthenticateRequest is
    called for default.aspx, the authentication has taken place and the user has
    failed.

    Now change the handler in the module to catch the AuthorizeRequest event.
    You will see that on the same call you will not get the default.aspx in you
    handler, only the login.aspx. After the user logs in and is authenticated
    then you will see the default.aspx in the event handler and at this time the
    user's authentication has succeeded.

    So I guess if you want to make sure that the form authentication process of
    redirecting has taken place you should hook the AuthorizeRequest event.

    Tyler
    Tyler Carver, Mar 1, 2006
    #3
  4. Re: AuthenticateRequest Before or After User has been Authenticate

    Hi,

    ok - let me give you more background....

    think of ASP.NET as a real generic engine for processing HTTP requests -
    there are events where extensibility code can subscribe to. By default there
    is only MS extensibility code - the default HttpModules -

    there are some modules that subscribe to AuthenticateRequest (Windows/Forms
    Authentication - well - technically also Passport auth) -

    these modules ultimate job is to populate Context.User in some way or another
    -

    if a request comes in (using IIS anon/forms auth) the user is typically not
    authenticated -

    FormsAuth looks for a ticket - if none is found - no actions are taken place
    - Context.User is anonymous - Request.IsAuthenticated = false.

    Now the UrlAuthorization module runs - this checks for <authorization> settings
    - if no authZ is required the pipeline continues

    if authZ is required (maybe by denying anon requests) - the authZ module
    places a 401 status code and calls HttpApplication.CompleteRequest which
    short circuits the pipeline directly to EndRequest -

    FormsAuth also subscribed to EndRequest and check the status code - if a
    401 is found - it is converted into a 302 (redirect) to the login page -

    Now a new request starts - for login.aspx - same eventing occurs - but login.aspx
    is handled differently - and requests are allowed regardless of authZ settings.

    When you click "login" on your login.aspx - the auth ticket is places - a
    new roundtrip occurs - this time FormsAuth finds a ticket - checks it - and
    populates Context.User.

    this is the behaviour you see -


    so for your own extensibility code - the moral of the story is:

    if you handle AuthenticateRequest you can be sure the builtin Auth has already
    run - which means the user is either anonymous or a specific IPrincipal -
    if you handle AuthorizeRequest you can be sure that the user is authorized
    by the builtin AuthZ modules. Thats really the point - code put there (and
    later in the pipeline) only runs if the user is authorized.

    needless to say that you can also remove the builtin modules and roll your
    own...

    ---------------------------------------
    Dominick Baier - DevelopMentor
    http://www.leastprivilege.com

    > Hi, Dominick, thanks for the response.
    >
    > "Dominick Baier [DevelopMentor]" wrote:
    >
    >> You will be called regardless of authentication has taken place (e.g.
    >> in
    >> the case of an anonymous request) so if you have to do any work that
    >> relies
    >> on an authenticated user, do a
    >> ...
    >> The same applies also for AuthorizeRequest - you get called on every
    >> request,
    >> but you can be sure the the File and UrlAuthorizationModule already
    >> did their
    >> work.

    > I think you are right. I think what I was expecting was for the
    > redirect to happen before the AuthenticateRequest was called. I guess
    > what the documentation is saying is that the user has been tested for
    > Authentication before the Authentication Request event but he may have
    > failed. The redirect to the login URL must happen after the
    > PostAuthenticateRequest event and before the AuthorizeRequest event.
    >
    > You can easily test this. Create a web app with one login page
    > login.aspx and a default page default.aspx, then set the default.aspx
    > to deny users=?, finally add an HttpModule and catch the
    > AuthenticateRequest event. You will see to URL's called in your
    > handler, the default.aspx and then the login.aspx. The user is not
    > authenticated before the AuthenticateRequest is called for
    > default.aspx, the authentication has taken place and the user has
    > failed.
    >
    > Now change the handler in the module to catch the AuthorizeRequest
    > event. You will see that on the same call you will not get the
    > default.aspx in you handler, only the login.aspx. After the user logs
    > in and is authenticated then you will see the default.aspx in the
    > event handler and at this time the user's authentication has
    > succeeded.
    >
    > So I guess if you want to make sure that the form authentication
    > process of redirecting has taken place you should hook the
    > AuthorizeRequest event.
    >
    > Tyler
    >
    Dominick Baier [DevelopMentor], Mar 1, 2006
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. David Krussow
    Replies:
    2
    Views:
    622
    Richard
    Jan 17, 2005
  2. asimhg
    Replies:
    0
    Views:
    874
    asimhg
    Feb 4, 2010
  3. Sergio Lera via .NET 247
    Replies:
    1
    Views:
    216
    Joe Kaplan \(MVP - ADSI\)
    Apr 6, 2005
  4. Replies:
    1
    Views:
    184
    Joe Kaplan
    Sep 22, 2006
  5. Abhijit
    Replies:
    0
    Views:
    141
    Abhijit
    Apr 12, 2004
Loading...

Share This Page