Handling UnauthorizedAccessException

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • imukai
    New Member
    • Jan 2009
    • 4

    Handling UnauthorizedAccessException

    I have a forms-based authentication application on our intranet - ASP.NET 3.5 (C#).

    For security purposes there is one specific .aspx file that we have enabled Integrated Windows Authentication turned on. Administrators in another group control access to this .aspx file via the file system. They have specifically set DENY access on this file to a few groups of employees.

    If one of those employees somehow manages to bring up that .aspx, they generate an exception (UnauthorizedAc cessException).

    Without debating the merits of the above solution as it cannot be changed, my question is this: how do I go about trapping that exception and redirecting the user back to a page they can access?

    According to the stack trace, it seems to be failing at the IO level, so I'm not sure exactly where to insert code to catch this exception and redirect the user back to the home page of the application. It doesn't seem to even touch any of the events on the .aspx, as I've tried going back as far as Page Init with no luck.

    Would this be something I'd have to catch in a handler of some sort? I'm kinda lost on this one.

    Here's the last bit of the trace:

    Exception Details: System.Unauthor izedAccessExcep tion: Access to the path 'H:\InetPub\Int ranet\tracking. aspx' is denied.

    [UnauthorizedAcc essException: Access to the path 'H:\InetPub\Int ranet\tracking. aspx' is denied.]
    System.IO.__Err or.WinIOError(I nt32 errorCode, String maybeFullPath) +7712175
    System.IO.FileS tream.Init(Stri ng path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIB UTES secAttrs, String msgPath, Boolean bFromProxy) +1162
    System.IO.FileS tream..ctor(Str ing path, FileMode mode, FileAccess access, FileShare share) +66
    System.Web.Host ing.MapPathBase dVirtualFile.Op en() +75
    System.Web.Host ing.VirtualPath Provider.OpenFi le(String virtualPath) +28
    System.Web.UI.T emplateParser.P arseFile(String physicalPath, VirtualPath virtualPath) +123
    System.Web.UI.T emplateParser.P arseInternal() +58
    System.Web.UI.T emplateParser.P arse() +167
  • PRR
    Recognized Expert Contributor
    • Dec 2007
    • 750

    #2
    You can put your code in try catch block and redirect?
    Code:
    try
                {
                    throw new UnauthorizedAccessException();
    
                }
                catch (UnauthorizedAccessException ex) 
                {
    Response.Redirect("somewhere.htm");
    }
    Another option would be to ask for user name and password to access the resource:Impers onation

    Comment

    • imukai
      New Member
      • Jan 2009
      • 4

      #3
      Thank you for the reply but I'm afraid that doesn't help.

      As I said in my initial post:

      1. Using Integrated Windows Authentication on one particular .aspx
      2. On the file system, have DENY access to certain people.
      3. If one of those people type in the URL to that .aspx, an exception is generated that I cannot find where to trap.

      People not on the DENY list can access the .aspx just fine. It's just those people that are on that list generate the UnauthorizedAcc essException.

      I can't put a try/catch until I know where to put it. I tried overriding the page's ProcessRequest to see if it's even getting that far - it isn't.

      This tells me that maybe I need some sort of handler or something to capture the attempted access to the file, but I don't know what to use.

      Recreating this should be easy.

      1. In any of your Forms Authentication websites, in IIS, right click an .aspx that you want to use, go to Properties, File Security, Authentication and access control.
      2. Turn off Enable Anonymous and turn on Integrated Windows Authentication. Hit OK.
      3. Open Windows Explorer and browse to where that .aspx is located, right click Properties, Security.
      4. Add your username and click Deny for Read and Read & Execute, hit OK.

      Now try to access that .aspx. Unless your browser is set to automatically log you in, you'll get the Username/Password popup box. Sign in with your information. You should get the exception I was referring to.

      Ideally if you are going to recreate this, you'll have two Windows accounts that you can use - one that you can set DENY access on, and one that is not denied so you can verify that Integrated Windows Authentication is working.

      Comment

      • Frinavale
        Recognized Expert Expert
        • Oct 2006
        • 9749

        #4
        There's 2 things that I can suggest.

        The first is to modify your web.config file and set your CustomErrors tag to redirect any user to a "safe" page when an error occurs.

        For example:
        Expand|Select|W rap|Line Numbers
        1. <customErrors mode="On" defaultRedirect ="http://bytes.com"></customErrors>





        Check out custom errors to see what else they can do for you.

        The second thing I would suggest is implementing a method that handles the Application_Err or event in the Global.asax file. This method is executed every time an unhandled error occurs in the application.

        To determine what type of exception/error happened, you can retrieve the last exception that occurred on the server by using Server.GetLastE rror.GetBaseExc eption. From there you can check if it's an UnauthorizedAcc essException and redirect the user accordingly.

        Eg:
        Code:
         
        Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs) 
           Dim ex As Exception 
           ex = Server.GetLastError.GetBaseException 
           If ex IsNot Nothing Then 
              'Check the type of exception and take action accordingly. 
              'I would also record any violations at this point 
           End If 
            Server.ClearError() 
        End Sub



        The Server.ClearErr or() clears the error and prevents it from being bubbled up any further.

        Hope this helps.

        -Frinny
        Last edited by Curtis Rutland; Jan 9 '09, 02:26 PM. Reason: fixed the code tags

        Comment

        • imukai
          New Member
          • Jan 2009
          • 4

          #5
          It might not be the "correct" way to handle it, but the global.asax suggestion was a good one, and works. Thank you. =)

          I'm still curious where in the lifecycle this goes before the error is generated.

          Is there a way to determine exactly what called the Application_Err or?

          Since the stack trace has System.IO in it right before it bombs out, I'm guessing it came from the filesystem, but .NET had to process it somewhere... and ultimately it's that somewhere that I'd like to trap this error.

          For now, global.asax works. Thanks again.

          Comment

          • Frinavale
            Recognized Expert Expert
            • Oct 2006
            • 9749

            #6
            Originally posted by imukai
            It might not be the "correct" way to handle it, but the global.asax suggestion was a good one, and works. Thank you. =)

            I'm still curious where in the lifecycle this goes before the error is generated.

            Is there a way to determine exactly what called the Application_Err or?

            Since the stack trace has System.IO in it right before it bombs out, I'm guessing it came from the filesystem, but .NET had to process it somewhere... and ultimately it's that somewhere that I'd like to trap this error.

            For now, global.asax works. Thanks again.
            It probably occurs when the request for the resource is made, before any of your ASPX page code is accessed. Since ASP.NET generates the error at this stage it's impossible to catch the error anywhere else except the Global.asax

            Comment

            • PRR
              Recognized Expert Contributor
              • Dec 2007
              • 750

              #7
              In addition to what Frinny said ... try page_error...
              Code:
               public void Page_Error(object sender, EventArgs e)
               {
              Exception objError = Server.GetLastError().GetBaseException();
                      Type t=objError.GetType();
                      Type t1 = typeof(System.UnauthorizedAccessException);
                      if (t == t1)
                      {
                          Response.Redirect("~/YourAccessVoilationPage.aspx");
                      }
                      else 
                      {
                          //some other Exception 
                      }
              }

              Comment

              • imukai
                New Member
                • Jan 2009
                • 4

                #8
                I presume you mean Page_Error within that specific .aspx

                On that suggestion, I gave it a try - unfortunately it does not appear to call it.

                From what I understand of the lifecycle of a page, the first thing that gets called is ProcessRequest (part of the base Page class) - but even that isn't being called, so I believe .NET is being stopped by the filesystem before it has a chance to touch the offending page.

                Unless this can be trapped by some sort of ISAPI or something, I think Frinavale's solution is probably the only feasible one for this situation.

                Comment

                • Frinavale
                  Recognized Expert Expert
                  • Oct 2006
                  • 9749

                  #9
                  The page_error captures any errors that happens within that .aspx page but this exception's thrown before the page code is executed.

                  There are a number of things that happen before your code is actually run which can generate errors (before any page class code is called). The Global.asax handles anything that happens with regard to the application and so it's able to catch the exception thrown.

                  Comment

                  Working...