Http 403 Response, rather than default.aspx, when site's root requested

  • Thread starter Thread starter Jeremy S.
  • Start date Start date
J

Jeremy S.

I'm developing an ASP.NET 3.5 web application using Visual Studio Pro 2008
on an XP Pro/SP3 dev box using IIS as the Web server.

The app performs url rewriting in global.asax.cs.Application_BeginRequest.

Everything works as intended when a full path, including .aspx page is
requested from the browser. For example:
http://localhost/MySite.testsite.Default.aspx

In this case the logic in Application_BeginRequest logs (for testing
purposes only) the value of Context.Request.Path as:
Context.Request.Path = [/MySite.testsite/Default.aspx]


But there is a problem when the browser does not request a specific .aspx
page and instead requests the site root, like this:
http://localhost/MySite.testsite
or
http://localhost/MySite.testsite/

(notice no specific .aspx page is requested)

In this case Application_BeginRequest doesn't even run, and the browser
immediately receives an HTTP 403 / Forbidden response.

What's going on here? How can I have IIS route requests for the site's root
(e.g., http://localhost/MySite.testsite) to my ASP.NET application, rather
than responding with the 403 Forbidden response? My intent is to have my url
rewriting logic translate requests for the site's root to be treated as
requests for default.aspx.

FWIW: The IIS Console shows Default.aspx is in fact set up as the site's
only default document (under the Documents tab), and the "Enable Default
Document" check box is in fact checked. Also in IIS console, security tab -
Authentication Methods - shows that Anonymous access is checked, in addition
to Integrated Windows Authenticatoin. I would not have both except that
Visual Studio complained when I went to debug - it wanted windows
authentication to be enabled.

Thanks!
 
RE:

In the OP I wrote the following. Is there more I need to do in IIS?:
The IIS Console shows Default.aspx is in fact set up as the site's only
default document (under the Documents tab), and the "Enable Default
Document" check box is in fact checked.


Separately, IIS does map the .aspx extension to the .NET Framework 2.0
isapi.
 
check the iis log to see exactly what IIS thinks is being requested that is
generating the error
 
That level of integration is impossible to achieve with any IIS/
ASP.Net versions prior to IIS7 and Windows Server 2008.

You are expecting ASP.Net to be invoked on every one of those requests
and then your code does something to affect request processing.
However, that is not what is happening, so your expectations are
misplaced.

What is actually happening on the server is that IIS parses and hands
certain requests to ASP.Net according to configuration, which then
continue processing the request according to its own configuration and
can do nothing to affect request processing in IIS. This is the limit
of integration between IIS and ASP.Net prior to IIS7, so there is no
way to configure things to get your desired behavior.

On IIS7, managed modules, handlers, and global.asax can actually
natively participate in the IIS request pipeline and affect request
processing behavior -- when you are running in Integrated Pipeline
mode (default). If you turn on "Classic Pipeline mode", you get the
some disjoint behavior of IIS6/ASP.Net.

What happens for a request to http://localhost/MySite.testsite is that
IIS:
- first attempts to see if MySite.testsite exists as a file and if so,
what handler is mapped to .testsite at "/". If it matches a handler,
it makes sure that the directory has at least Script execute
permissions before allowing the handler to process the request
- if the file does not exist, then check if the directory named
MySite.testsite exists, and if so, do a courtesy 302 redirect to "/"
of that directory. The courtesy 302 redirect will trigger in-order
DefaultDocument lookup to determine whether any Default Document
matches and if so, do the handler execution logic described earlier
- if there is no default document, then check if "Directory Browsing"
is enabled. If it is, return the Directory Browsing page. Otherwise,
return 403.

Notice, nowhere in my description does ASP.Net even come into the
picture until I mention handlers to process the request, so there is
no way for your global.asax to affect the processing of
http://localhost/MySite.testsite generically. You may think wildcard
application mapping is the solution, but even that does not work, as I
describe in these blog entries (not to mention you cannot get it to
work on IIS5.1 of XP):

http://blogs.msdn.com/david.wang/ar...-can-disable-Default-Document-resolution.aspx

http://blogs.msdn.com/david.wang/ar...application-mapping-is-not-catching-404s.aspx

http://blogs.msdn.com/david.wang/ar...-from-IIS6-on-Windows-Server-2003-Part-2.aspx

Bottom line -- either use IIS7, or just accept the existing behavior.



//David
http://w3-4u.blogspot.com
http://blogs.msdn.com/David.Wang
//



I'm developing an ASP.NET 3.5 web application using Visual Studio Pro 2008
on an XP Pro/SP3 dev box using IIS as the Web server.

The app performs url rewriting in global.asax.cs.Application_BeginRequest..

Everything works as intended when a full path, including .aspx page is
requested from the browser. For example:
     http://localhost/MySite.testsite.Default.aspx

In this case the logic in Application_BeginRequest logs (for testing
purposes only) the value of Context.Request.Path as:
     Context.Request.Path = [/MySite.testsite/Default.aspx]

But there is a problem when the browser does not request a specific .aspx
page and instead requests the site root, like this:
     http://localhost/MySite.testsite
  or
     http://localhost/MySite.testsite/

     (notice no specific .aspx page is requested)

In this case Application_BeginRequest doesn't even run, and the browser
immediately receives an HTTP 403 / Forbidden response.

What's going on here? How can I have IIS route requests for the site's root
(e.g.,  http://localhost/MySite.testsite) to my ASP.NET application, rather
than responding with the 403 Forbidden response? My intent is to have my url
rewriting logic translate requests for the site's root to be treated as
requests for default.aspx.

FWIW: The IIS Console shows Default.aspx is in fact set up as the site's
only default document (under the Documents tab), and the "Enable Default
Document" check box is in fact checked. Also in IIS console, security tab-
Authentication Methods - shows that Anonymous access is checked, in addition
to Integrated Windows Authenticatoin. I would not have both except that
Visual Studio complained when I went to debug - it wanted windows
authentication to be enabled.

Thanks!
 
David,

Thank you for the detailed and helpful response. This is great.

So based on what you explained...

.... I came up with something that feels like a total hack, but it works on
my XP/IIS 5.1 dev box:

I added a file named "Default.aspx" to the root of the site (and
default.aspx is also set as the default document in IIS). Doing this causes
IIS to hand off the request to asp.net, where my global.asax url rewriting
logic kicks in. Everything from that point works as intended. The
Default.aspx file is never executed because my url rewriting logic
interecepts the request. Default.aspx is there merely to influence the logic
in IIS that looks for the site's default document (as you explained).

Long-term I plan to move this to IIS7 and get rid of this hack. But I cannot
because I am leasing a Web server, and the hosting provider does not yet
support Windows Server 2008. So until then, I need to make this work with
IIS 6.

Quick followup question: I have tested this with my XP Pro dev box and
therefore IIS 5.1. Do you see any reason this hack would not work on Windows
Server 2003 and IIS 6?

Thanks again!








That level of integration is impossible to achieve with any IIS/
ASP.Net versions prior to IIS7 and Windows Server 2008.

You are expecting ASP.Net to be invoked on every one of those requests
and then your code does something to affect request processing.
However, that is not what is happening, so your expectations are
misplaced.

What is actually happening on the server is that IIS parses and hands
certain requests to ASP.Net according to configuration, which then
continue processing the request according to its own configuration and
can do nothing to affect request processing in IIS. This is the limit
of integration between IIS and ASP.Net prior to IIS7, so there is no
way to configure things to get your desired behavior.

On IIS7, managed modules, handlers, and global.asax can actually
natively participate in the IIS request pipeline and affect request
processing behavior -- when you are running in Integrated Pipeline
mode (default). If you turn on "Classic Pipeline mode", you get the
some disjoint behavior of IIS6/ASP.Net.

What happens for a request to http://localhost/MySite.testsite is that
IIS:
- first attempts to see if MySite.testsite exists as a file and if so,
what handler is mapped to .testsite at "/". If it matches a handler,
it makes sure that the directory has at least Script execute
permissions before allowing the handler to process the request
- if the file does not exist, then check if the directory named
MySite.testsite exists, and if so, do a courtesy 302 redirect to "/"
of that directory. The courtesy 302 redirect will trigger in-order
DefaultDocument lookup to determine whether any Default Document
matches and if so, do the handler execution logic described earlier
- if there is no default document, then check if "Directory Browsing"
is enabled. If it is, return the Directory Browsing page. Otherwise,
return 403.

Notice, nowhere in my description does ASP.Net even come into the
picture until I mention handlers to process the request, so there is
no way for your global.asax to affect the processing of
http://localhost/MySite.testsite generically. You may think wildcard
application mapping is the solution, but even that does not work, as I
describe in these blog entries (not to mention you cannot get it to
work on IIS5.1 of XP):

http://blogs.msdn.com/david.wang/ar...-can-disable-Default-Document-resolution.aspx

http://blogs.msdn.com/david.wang/ar...application-mapping-is-not-catching-404s.aspx

http://blogs.msdn.com/david.wang/ar...-from-IIS6-on-Windows-Server-2003-Part-2.aspx

Bottom line -- either use IIS7, or just accept the existing behavior.



//David
http://w3-4u.blogspot.com
http://blogs.msdn.com/David.Wang
//



I'm developing an ASP.NET 3.5 web application using Visual Studio Pro 2008
on an XP Pro/SP3 dev box using IIS as the Web server.

The app performs url rewriting in global.asax.cs.Application_BeginRequest.

Everything works as intended when a full path, including .aspx page is
requested from the browser. For example:
http://localhost/MySite.testsite.Default.aspx

In this case the logic in Application_BeginRequest logs (for testing
purposes only) the value of Context.Request.Path as:
Context.Request.Path = [/MySite.testsite/Default.aspx]

But there is a problem when the browser does not request a specific .aspx
page and instead requests the site root, like this:
http://localhost/MySite.testsite
or
http://localhost/MySite.testsite/

(notice no specific .aspx page is requested)

In this case Application_BeginRequest doesn't even run, and the browser
immediately receives an HTTP 403 / Forbidden response.

What's going on here? How can I have IIS route requests for the site's
root
(e.g., http://localhost/MySite.testsite) to my ASP.NET application, rather
than responding with the 403 Forbidden response? My intent is to have my
url
rewriting logic translate requests for the site's root to be treated as
requests for default.aspx.

FWIW: The IIS Console shows Default.aspx is in fact set up as the site's
only default document (under the Documents tab), and the "Enable Default
Document" check box is in fact checked. Also in IIS console, security
tab -
Authentication Methods - shows that Anonymous access is checked, in
addition
to Integrated Windows Authenticatoin. I would not have both except that
Visual Studio complained when I went to debug - it wanted windows
authentication to be enabled.

Thanks!
 
It should work on IIS6 in the same configuration.

Of course, you should realize that you may want people's 404 requests
to also be captured by your URL rewriter and handled appropriately. As
well as all other sorts of error/authentication/etc conditions. And
you will see that this "hack" will simply get harder and harder to
implement and maintain -- mostly because you are fighting against what
does not fundamentally work. You will have to be well defined in your
expectations/capabilities of this hack.

IIS7 is the first time that managed code extensibility gets near first-
class treatment on IIS.

To be certain, managed code extensibility can not be truly first-class
because IIS will always be written in native code (performance), and
there will always be an interpretation layer between native and
managed code, and thus managed code is not natively first class. But
it is close on IIS7.


//David
http://w3-4u.blogspot.com
http://blogs.msdn.com/David.Wang
//




David,

Thank you for the detailed and helpful response. This is great.

So based on what you explained...

... I came up with something that feels like a total hack, but it works on
my XP/IIS 5.1 dev box:

I added a file named "Default.aspx" to the root of the site (and
default.aspx is also set as the default document in IIS). Doing this causes
IIS to hand off the request to asp.net, where my global.asax url rewriting
logic kicks in. Everything from that point works as intended. The
Default.aspx file is never executed because my url rewriting logic
interecepts the request. Default.aspx is there merely to influence the logic
in IIS that looks for the site's default document (as you explained).

Long-term I plan to move this to IIS7 and get rid of this hack. But I cannot
because I am leasing a Web server, and the hosting provider does not yet
support Windows Server 2008. So until then, I need to make this work with
IIS 6.

Quick followup question: I have tested this with my XP Pro dev box and
therefore IIS 5.1. Do you see any reason this hack would not work on Windows
Server 2003 and IIS 6?

Thanks again!


That level of integration is impossible to achieve with any IIS/
ASP.Net versions prior to IIS7 and Windows Server 2008.

You are expecting ASP.Net to be invoked on every one of those requests
and then your code does something to affect request processing.
However, that is not what is happening, so your expectations are
misplaced.

What is actually happening on the server is that IIS parses and hands
certain requests to ASP.Net according to configuration, which then
continue processing the request according to its own configuration and
can do nothing to affect request processing in IIS. This is the limit
of integration between IIS and ASP.Net prior to IIS7, so there is no
way to configure things to get your desired behavior.

On IIS7, managed modules, handlers, and global.asax can actually
natively participate in the IIS request pipeline and affect request
processing behavior -- when you are running in Integrated Pipeline
mode (default). If you turn on "Classic Pipeline mode", you get the
some disjoint behavior of IIS6/ASP.Net.

What happens for a request tohttp://localhost/MySite.testsiteis that
IIS:
- first attempts to see if MySite.testsite exists as a file and if so,
what handler is mapped to .testsite at "/". If it matches a handler,
it makes sure that the directory has at least Script execute
permissions before allowing the handler to process the request
- if the file does not exist, then check if the directory named
MySite.testsite exists, and if so, do a courtesy 302 redirect to "/"
of that directory. The courtesy 302 redirect will trigger in-order
DefaultDocument lookup to determine whether any Default Document
matches and if so, do the handler execution logic described earlier
- if there is no default document, then check if "Directory Browsing"
is enabled. If it is, return the Directory Browsing page. Otherwise,
return 403.

Notice, nowhere in my description does ASP.Net even come into the
picture until I mention handlers to process the request, so there is
no way for your global.asax to affect the processing ofhttp://localhost/MySite.testsitegenerically. You may think wildcard
application mapping is the solution, but even that does not work, as I
describe in these blog entries (not to mention you cannot get it to
work on IIS5.1 of XP):

http://blogs.msdn.com/david.wang/archive/2005/10/15/Why-Wildcard-appl...

http://blogs.msdn.com/david.wang/archive/2005/10/16/Why-Wildcard-appl...

http://blogs.msdn.com/david.wang/archive/2006/04/28/HOWTO-Run-Console...

Bottom line -- either use IIS7, or just accept the existing behavior.

//Davidhttp://w3-4u.blogspot.comhttp://blogs.msdn.com/David.Wang
//

I'm developing an ASP.NET 3.5 web application using Visual Studio Pro 2008
on an XP Pro/SP3 dev box using IIS as the Web server.
The app performs url rewriting in global.asax.cs.Application_BeginRequest.
Everything works as intended when a full path, including .aspx page is
requested from the browser. For example:
http://localhost/MySite.testsite.Default.aspx
In this case the logic in Application_BeginRequest logs (for testing
purposes only) the value of Context.Request.Path as:
Context.Request.Path = [/MySite.testsite/Default.aspx]
But there is a problem when the browser does not request a specific .aspx
page and instead requests the site root, like this:
http://localhost/MySite.testsite
or
http://localhost/MySite.testsite/
(notice no specific .aspx page is requested)
In this case Application_BeginRequest doesn't even run, and the browser
immediately receives an HTTP 403 / Forbidden response.
What's going on here? How can I have IIS route requests for the site's
root
(e.g.,http://localhost/MySite.testsite) to my ASP.NET application, rather
than responding with the 403 Forbidden response? My intent is to have my
url
rewriting logic translate requests for the site's root to be treated as
requests for default.aspx.
FWIW: The IIS Console shows Default.aspx is in fact set up as the site's
only default document (under the Documents tab), and the "Enable Default
Document" check box is in fact checked. Also in IIS console, security
tab -
Authentication Methods - shows that Anonymous access is checked, in
addition
to Integrated Windows Authenticatoin. I would not have both except that
Visual Studio complained when I went to debug - it wanted windows
authentication to be enabled.
Thanks!- Hide quoted text -

- Show quoted text -
 
Understood. And I appreciate this additional feedback. My intent is to live
with this no longer than 6-10 months... depending on when the hosting
provider starts supporting Windows Server 2008. I'm looking forward to
IIS7... have been since I heard about the integrated pipeline - I knew I'd
need it for this project.

- J



It should work on IIS6 in the same configuration.

Of course, you should realize that you may want people's 404 requests
to also be captured by your URL rewriter and handled appropriately. As
well as all other sorts of error/authentication/etc conditions. And
you will see that this "hack" will simply get harder and harder to
implement and maintain -- mostly because you are fighting against what
does not fundamentally work. You will have to be well defined in your
expectations/capabilities of this hack.

IIS7 is the first time that managed code extensibility gets near first-
class treatment on IIS.

To be certain, managed code extensibility can not be truly first-class
because IIS will always be written in native code (performance), and
there will always be an interpretation layer between native and
managed code, and thus managed code is not natively first class. But
it is close on IIS7.


//David
http://w3-4u.blogspot.com
http://blogs.msdn.com/David.Wang
//




David,

Thank you for the detailed and helpful response. This is great.

So based on what you explained...

... I came up with something that feels like a total hack, but it works on
my XP/IIS 5.1 dev box:

I added a file named "Default.aspx" to the root of the site (and
default.aspx is also set as the default document in IIS). Doing this
causes
IIS to hand off the request to asp.net, where my global.asax url rewriting
logic kicks in. Everything from that point works as intended. The
Default.aspx file is never executed because my url rewriting logic
interecepts the request. Default.aspx is there merely to influence the
logic
in IIS that looks for the site's default document (as you explained).

Long-term I plan to move this to IIS7 and get rid of this hack. But I
cannot
because I am leasing a Web server, and the hosting provider does not yet
support Windows Server 2008. So until then, I need to make this work with
IIS 6.

Quick followup question: I have tested this with my XP Pro dev box and
therefore IIS 5.1. Do you see any reason this hack would not work on
Windows
Server 2003 and IIS 6?

Thanks again!


That level of integration is impossible to achieve with any IIS/
ASP.Net versions prior to IIS7 and Windows Server 2008.

You are expecting ASP.Net to be invoked on every one of those requests
and then your code does something to affect request processing.
However, that is not what is happening, so your expectations are
misplaced.

What is actually happening on the server is that IIS parses and hands
certain requests to ASP.Net according to configuration, which then
continue processing the request according to its own configuration and
can do nothing to affect request processing in IIS. This is the limit
of integration between IIS and ASP.Net prior to IIS7, so there is no
way to configure things to get your desired behavior.

On IIS7, managed modules, handlers, and global.asax can actually
natively participate in the IIS request pipeline and affect request
processing behavior -- when you are running in Integrated Pipeline
mode (default). If you turn on "Classic Pipeline mode", you get the
some disjoint behavior of IIS6/ASP.Net.

What happens for a request tohttp://localhost/MySite.testsiteis that
IIS:
- first attempts to see if MySite.testsite exists as a file and if so,
what handler is mapped to .testsite at "/". If it matches a handler,
it makes sure that the directory has at least Script execute
permissions before allowing the handler to process the request
- if the file does not exist, then check if the directory named
MySite.testsite exists, and if so, do a courtesy 302 redirect to "/"
of that directory. The courtesy 302 redirect will trigger in-order
DefaultDocument lookup to determine whether any Default Document
matches and if so, do the handler execution logic described earlier
- if there is no default document, then check if "Directory Browsing"
is enabled. If it is, return the Directory Browsing page. Otherwise,
return 403.

Notice, nowhere in my description does ASP.Net even come into the
picture until I mention handlers to process the request, so there is
no way for your global.asax to affect the processing
ofhttp://localhost/MySite.testsitegenerically. You may think wildcard
application mapping is the solution, but even that does not work, as I
describe in these blog entries (not to mention you cannot get it to
work on IIS5.1 of XP):

http://blogs.msdn.com/david.wang/archive/2005/10/15/Why-Wildcard-appl...

http://blogs.msdn.com/david.wang/archive/2005/10/16/Why-Wildcard-appl...

http://blogs.msdn.com/david.wang/archive/2006/04/28/HOWTO-Run-Console...

Bottom line -- either use IIS7, or just accept the existing behavior.

//Davidhttp://w3-4u.blogspot.comhttp://blogs.msdn.com/David.Wang
//

I'm developing an ASP.NET 3.5 web application using Visual Studio Pro
2008
on an XP Pro/SP3 dev box using IIS as the Web server.
The app performs url rewriting in
global.asax.cs.Application_BeginRequest.
Everything works as intended when a full path, including .aspx page is
requested from the browser. For example:
http://localhost/MySite.testsite.Default.aspx
In this case the logic in Application_BeginRequest logs (for testing
purposes only) the value of Context.Request.Path as:
Context.Request.Path = [/MySite.testsite/Default.aspx]
But there is a problem when the browser does not request a specific
.aspx
page and instead requests the site root, like this:
http://localhost/MySite.testsite
or
http://localhost/MySite.testsite/
(notice no specific .aspx page is requested)
In this case Application_BeginRequest doesn't even run, and the browser
immediately receives an HTTP 403 / Forbidden response.
What's going on here? How can I have IIS route requests for the site's
root
(e.g.,http://localhost/MySite.testsite) to my ASP.NET application,
rather
than responding with the 403 Forbidden response? My intent is to have my
url
rewriting logic translate requests for the site's root to be treated as
requests for default.aspx.
FWIW: The IIS Console shows Default.aspx is in fact set up as the site's
only default document (under the Documents tab), and the "Enable Default
Document" check box is in fact checked. Also in IIS console, security
tab -
Authentication Methods - shows that Anonymous access is checked, in
addition
to Integrated Windows Authenticatoin. I would not have both except that
Visual Studio complained when I went to debug - it wanted windows
authentication to be enabled.
Thanks!- Hide quoted text -

- Show quoted text -
 
Back
Top