How do I redirect to an "Access Denied" page in ASP.NET 2.0?

Discussion in 'ASP .Net Security' started by SkidMarks, Mar 8, 2006.

  1. SkidMarks

    SkidMarks Guest

    Hi Everyone,

    I'm probably just missing something simple, but in our Visual Studio 2003
    projects, we are using a custom HttpModule to handle the authentication for
    our applications against a central single signon server.

    By adding some code into our Global.asax.cs file, we are also able to send a
    user to an "Access Denied" page if they correctly authenticate, but are not
    authorized to view the application.

    I have been playing around with Visual Studio 2005 and can't figure out how
    to incorporate the same functionality. I have modified my Global.asax (in
    the script view since the codebehind window is gone) like so, but no luck...
    The problem I'm having with VS 2005 is that the Response.StatusCode is always
    302, even when they aren't authorized to view the page. In Visual Studio
    2003, it will give me the expected 401 when they are not authorized to view
    the page. Any thoughts / suggestions? Or, is there a better way to do this?

    Thanks!
    David

    *** Global.asax ***

    public override void Init()
    {
    this.EndRequest += new System.EventHandler(this.Global_EndRequest);
    }

    void Global_EndRequest(Object sender, EventArgs e)
    {
    //This checks to see if user is authenticated but not authorized
    //to view current page. If so, redirects to an access denied page.
    if (User.Identity.IsAuthenticated && Response.StatusCode == 401)
    {
    string destURL = Request.Url.GetLeftPart(UriPartial.Authority)
    + Request.ApplicationPath
    + "/AuthFailed.aspx?FailedPage="
    + Request.Url.ToString();

    Response.Redirect(destURL);
    }
    }

    *** End snippet ***
    SkidMarks, Mar 8, 2006
    #1
    1. Advertising

  2. Hi,

    in the default configuration of ASP.NET (regardless of which version) - you
    will never see a 401 in EndRequest in global.asax.

    The reason is:

    if UrlAuthorization thinks a use is not authorized he sets a 401 status code
    with formsauthentication in effect - the FormsAuthenticationModule subscribes
    to EndRequest

    In EndRequets FormsAuth checks if there is a 401 set, and changes it to a
    302 (redirect) that points to the login page.

    Since global.asax code always runs after HttpModules you cannot see the 401.

    You said you are using a custom auth module - did you maybe change the configuration
    of the HTTP Pipeline - maybe the custom auth module does some magic - maybe
    you remove FormsAuth ???

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

    > Hi Everyone,
    >
    > I'm probably just missing something simple, but in our Visual Studio
    > 2003 projects, we are using a custom HttpModule to handle the
    > authentication for our applications against a central single signon
    > server.
    >
    > By adding some code into our Global.asax.cs file, we are also able to
    > send a user to an "Access Denied" page if they correctly authenticate,
    > but are not authorized to view the application.
    >
    > I have been playing around with Visual Studio 2005 and can't figure
    > out how to incorporate the same functionality. I have modified my
    > Global.asax (in the script view since the codebehind window is gone)
    > like so, but no luck... The problem I'm having with VS 2005 is that
    > the Response.StatusCode is always 302, even when they aren't
    > authorized to view the page. In Visual Studio 2003, it will give me
    > the expected 401 when they are not authorized to view the page. Any
    > thoughts / suggestions? Or, is there a better way to do this?
    >
    > Thanks!
    > David
    > *** Global.asax ***
    >
    > public override void Init()
    > {
    > this.EndRequest += new
    > System.EventHandler(this.Global_EndRequest);
    > }
    > void Global_EndRequest(Object sender, EventArgs e)
    > {
    > //This checks to see if user is authenticated but not
    > authorized
    > //to view current page. If so, redirects to an access denied
    > page.
    > if (User.Identity.IsAuthenticated && Response.StatusCode ==
    > 401)
    > {
    > string destURL =
    > Request.Url.GetLeftPart(UriPartial.Authority)
    > + Request.ApplicationPath
    > + "/AuthFailed.aspx?FailedPage="
    > + Request.Url.ToString();
    > Response.Redirect(destURL);
    > }
    > }
    > *** End snippet ***
    >
    Dominick Baier [DevelopMentor], Mar 8, 2006
    #2
    1. Advertising

  3. that said you could easily write a HttpModule that handles EndRequest and
    wire it in the pipeline before FormsAuthenticationModule.

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

    > Hi,
    >
    > in the default configuration of ASP.NET (regardless of which version)
    > - you will never see a 401 in EndRequest in global.asax.
    >
    > The reason is:
    >
    > if UrlAuthorization thinks a use is not authorized he sets a 401
    > status code with formsauthentication in effect - the
    > FormsAuthenticationModule subscribes to EndRequest
    >
    > In EndRequets FormsAuth checks if there is a 401 set, and changes it
    > to a 302 (redirect) that points to the login page.
    >
    > Since global.asax code always runs after HttpModules you cannot see
    > the 401.
    >
    > You said you are using a custom auth module - did you maybe change the
    > configuration of the HTTP Pipeline - maybe the custom auth module does
    > some magic - maybe you remove FormsAuth ???
    >
    > ---------------------------------------
    > Dominick Baier - DevelopMentor
    > http://www.leastprivilege.com
    >> Hi Everyone,
    >>
    >> I'm probably just missing something simple, but in our Visual Studio
    >> 2003 projects, we are using a custom HttpModule to handle the
    >> authentication for our applications against a central single signon
    >> server.
    >>
    >> By adding some code into our Global.asax.cs file, we are also able to
    >> send a user to an "Access Denied" page if they correctly
    >> authenticate, but are not authorized to view the application.
    >>
    >> I have been playing around with Visual Studio 2005 and can't figure
    >> out how to incorporate the same functionality. I have modified my
    >> Global.asax (in the script view since the codebehind window is gone)
    >> like so, but no luck... The problem I'm having with VS 2005 is that
    >> the Response.StatusCode is always 302, even when they aren't
    >> authorized to view the page. In Visual Studio 2003, it will give me
    >> the expected 401 when they are not authorized to view the page. Any
    >> thoughts / suggestions? Or, is there a better way to do this?
    >>
    >> Thanks!
    >> David
    >> *** Global.asax ***
    >> public override void Init()
    >> {
    >> this.EndRequest += new
    >> System.EventHandler(this.Global_EndRequest);
    >> }
    >> void Global_EndRequest(Object sender, EventArgs e)
    >> {
    >> //This checks to see if user is authenticated but not
    >> authorized
    >> //to view current page. If so, redirects to an access denied
    >> page.
    >> if (User.Identity.IsAuthenticated && Response.StatusCode ==
    >> 401)
    >> {
    >> string destURL =
    >> Request.Url.GetLeftPart(UriPartial.Authority)
    >> + Request.ApplicationPath
    >> + "/AuthFailed.aspx?FailedPage="
    >> + Request.Url.ToString();
    >> Response.Redirect(destURL);
    >> }
    >> }
    >> *** End snippet ***
    Dominick Baier [DevelopMentor], Mar 8, 2006
    #3
  4. SkidMarks

    SkidMarks Guest

    Hi Dominick,

    Ok, well, I can tell you that I do see a 401 when I'm in Visual Studio 2003
    / ASP.NET 1.1 and use the code that I mentioned in my Global.asax.cs. So
    maybe it's a fluke, but it does work in VS 2003.

    I tried implementing the same code in my HttpModule as follows:

    public void Init(HttpApplication context)
    {
    context.AuthenticateRequest += new
    EventHandler(this.Application_AuthenticateRequest);

    context.EndRequest += new EventHandler(this.Application_EndRequest);
    }

    And in the Application_EndRequest:

    if ((HttpContext.Current.User.Identity.IsAuthenticated) &&
    (HttpContext.Current.Response.StatusCode == 401))
    {
    // code here...
    }


    But I still always get a 302 when checking the value of the
    Response.StatusCode there as well. So, I guess my question is, how can I
    tell that a user was authenticated, but not authorized, and where can I place
    code to handle that situation?

    Thanks!
    David

    "Dominick Baier [DevelopMentor]" wrote:

    > that said you could easily write a HttpModule that handles EndRequest and
    > wire it in the pipeline before FormsAuthenticationModule.
    >
    > ---------------------------------------
    > Dominick Baier - DevelopMentor
    > http://www.leastprivilege.com
    >
    > > Hi,
    > >
    > > in the default configuration of ASP.NET (regardless of which version)
    > > - you will never see a 401 in EndRequest in global.asax.
    > >
    > > The reason is:
    > >
    > > if UrlAuthorization thinks a use is not authorized he sets a 401
    > > status code with formsauthentication in effect - the
    > > FormsAuthenticationModule subscribes to EndRequest
    > >
    > > In EndRequets FormsAuth checks if there is a 401 set, and changes it
    > > to a 302 (redirect) that points to the login page.
    > >
    > > Since global.asax code always runs after HttpModules you cannot see
    > > the 401.
    > >
    > > You said you are using a custom auth module - did you maybe change the
    > > configuration of the HTTP Pipeline - maybe the custom auth module does
    > > some magic - maybe you remove FormsAuth ???
    > >
    > > ---------------------------------------
    > > Dominick Baier - DevelopMentor
    > > http://www.leastprivilege.com
    > >> Hi Everyone,
    > >>
    > >> I'm probably just missing something simple, but in our Visual Studio
    > >> 2003 projects, we are using a custom HttpModule to handle the
    > >> authentication for our applications against a central single signon
    > >> server.
    > >>
    > >> By adding some code into our Global.asax.cs file, we are also able to
    > >> send a user to an "Access Denied" page if they correctly
    > >> authenticate, but are not authorized to view the application.
    > >>
    > >> I have been playing around with Visual Studio 2005 and can't figure
    > >> out how to incorporate the same functionality. I have modified my
    > >> Global.asax (in the script view since the codebehind window is gone)
    > >> like so, but no luck... The problem I'm having with VS 2005 is that
    > >> the Response.StatusCode is always 302, even when they aren't
    > >> authorized to view the page. In Visual Studio 2003, it will give me
    > >> the expected 401 when they are not authorized to view the page. Any
    > >> thoughts / suggestions? Or, is there a better way to do this?
    > >>
    > >> Thanks!
    > >> David
    > >> *** Global.asax ***
    > >> public override void Init()
    > >> {
    > >> this.EndRequest += new
    > >> System.EventHandler(this.Global_EndRequest);
    > >> }
    > >> void Global_EndRequest(Object sender, EventArgs e)
    > >> {
    > >> //This checks to see if user is authenticated but not
    > >> authorized
    > >> //to view current page. If so, redirects to an access denied
    > >> page.
    > >> if (User.Identity.IsAuthenticated && Response.StatusCode ==
    > >> 401)
    > >> {
    > >> string destURL =
    > >> Request.Url.GetLeftPart(UriPartial.Authority)
    > >> + Request.ApplicationPath
    > >> + "/AuthFailed.aspx?FailedPage="
    > >> + Request.Url.ToString();
    > >> Response.Redirect(destURL);
    > >> }
    > >> }
    > >> *** End snippet ***

    >
    >
    >
    SkidMarks, Mar 9, 2006
    #4
  5. How have you registered the module??

    just by adding a <httpModules> element in web.config - if yes - this code
    is also running after FormsAuth

    do the following:

    <httpModules>
    <clear />

    ... copy the modules from machine web.config

    add your module *before* FormsAuthenticationModule

    this guarantees that your code will run before FormsAuth changes the 401
    to a 302

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

    > Hi Dominick,
    >
    > Ok, well, I can tell you that I do see a 401 when I'm in Visual Studio
    > 2003 / ASP.NET 1.1 and use the code that I mentioned in my
    > Global.asax.cs. So maybe it's a fluke, but it does work in VS 2003.
    >
    > I tried implementing the same code in my HttpModule as follows:
    >
    > public void Init(HttpApplication context)
    > {
    > context.AuthenticateRequest += new
    > EventHandler(this.Application_AuthenticateRequest);
    > context.EndRequest += new
    > EventHandler(this.Application_EndRequest); }
    >
    > And in the Application_EndRequest:
    >
    > if ((HttpContext.Current.User.Identity.IsAuthenticated) &&
    > (HttpContext.Current.Response.StatusCode == 401))
    > {
    > // code here...
    > }
    > But I still always get a 302 when checking the value of the
    > Response.StatusCode there as well. So, I guess my question is, how
    > can I tell that a user was authenticated, but not authorized, and
    > where can I place code to handle that situation?
    >
    > Thanks!
    > David
    > "Dominick Baier [DevelopMentor]" wrote:
    >
    >> that said you could easily write a HttpModule that handles EndRequest
    >> and wire it in the pipeline before FormsAuthenticationModule.
    >>
    >> ---------------------------------------
    >> Dominick Baier - DevelopMentor
    >> http://www.leastprivilege.com
    >>> Hi,
    >>>
    >>> in the default configuration of ASP.NET (regardless of which
    >>> version) - you will never see a 401 in EndRequest in global.asax.
    >>>
    >>> The reason is:
    >>>
    >>> if UrlAuthorization thinks a use is not authorized he sets a 401
    >>> status code with formsauthentication in effect - the
    >>> FormsAuthenticationModule subscribes to EndRequest
    >>>
    >>> In EndRequets FormsAuth checks if there is a 401 set, and changes it
    >>> to a 302 (redirect) that points to the login page.
    >>>
    >>> Since global.asax code always runs after HttpModules you cannot see
    >>> the 401.
    >>>
    >>> You said you are using a custom auth module - did you maybe change
    >>> the configuration of the HTTP Pipeline - maybe the custom auth
    >>> module does some magic - maybe you remove FormsAuth ???
    >>>
    >>> ---------------------------------------
    >>> Dominick Baier - DevelopMentor
    >>> http://www.leastprivilege.com
    >>>> Hi Everyone,
    >>>>
    >>>> I'm probably just missing something simple, but in our Visual
    >>>> Studio 2003 projects, we are using a custom HttpModule to handle
    >>>> the authentication for our applications against a central single
    >>>> signon server.
    >>>>
    >>>> By adding some code into our Global.asax.cs file, we are also able
    >>>> to send a user to an "Access Denied" page if they correctly
    >>>> authenticate, but are not authorized to view the application.
    >>>>
    >>>> I have been playing around with Visual Studio 2005 and can't figure
    >>>> out how to incorporate the same functionality. I have modified my
    >>>> Global.asax (in the script view since the codebehind window is
    >>>> gone) like so, but no luck... The problem I'm having with VS 2005
    >>>> is that the Response.StatusCode is always 302, even when they
    >>>> aren't authorized to view the page. In Visual Studio 2003, it will
    >>>> give me the expected 401 when they are not authorized to view the
    >>>> page. Any thoughts / suggestions? Or, is there a better way to do
    >>>> this?
    >>>>
    >>>> Thanks!
    >>>> David
    >>>> *** Global.asax ***
    >>>> public override void Init()
    >>>> {
    >>>> this.EndRequest += new
    >>>> System.EventHandler(this.Global_EndRequest);
    >>>> }
    >>>> void Global_EndRequest(Object sender, EventArgs e)
    >>>> {
    >>>> //This checks to see if user is authenticated but not
    >>>> authorized
    >>>> //to view current page. If so, redirects to an access denied
    >>>> page.
    >>>> if (User.Identity.IsAuthenticated && Response.StatusCode ==
    >>>> 401)
    >>>> {
    >>>> string destURL =
    >>>> Request.Url.GetLeftPart(UriPartial.Authority)
    >>>> + Request.ApplicationPath
    >>>> + "/AuthFailed.aspx?FailedPage="
    >>>> + Request.Url.ToString();
    >>>> Response.Redirect(destURL);
    >>>> }
    >>>> }
    >>>> *** End snippet ***
    Dominick Baier [DevelopMentor], Mar 9, 2006
    #5
    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. Ros@
    Replies:
    3
    Views:
    623
  2. rote
    Replies:
    4
    Views:
    1,728
    Alexey Smirnov
    Aug 4, 2008
  3. Brad
    Replies:
    6
    Views:
    136
  4. Oliver
    Replies:
    0
    Views:
    135
    Oliver
    Sep 14, 2004
  5. Sal
    Replies:
    1
    Views:
    409
Loading...

Share This Page