Sending a different 401 error with ISAPI or ASP.NET 2.0
Sending a different 401 error with ISAPI or ASP.NET 2.0
am 27.11.2007 22:49:47 von Craig Box
I want to take a page that would otherwise generate a 401 error, and
instead of returning the standard IIS 401, call a custom page, with
the original request URL intact. This should then generate a client-
side redirect to another page.
By way of example: if logging into http://site/WindowsAuthLogin.aspx?ReturnURL=foo
(with Windows authentication) fails, I want the 401 page to trigger a
redirect to http://site/FormsLogin.aspx?ReturnURL=foo. This can't be a
302 redirect because the browser needs the 401 to send the
credentials, and it can't be a custom error page in IIS because I need
to pass the ReturnURL value.
(I am aware of the possibility in ASP.NET of capturing the original
returnURL value in the global.asax, but I'd like to see if this can be
done without changing the code.)
I've done a lot of searching, and found numerous posts suggesting (1)
custom 401 responses will be available in ASP.NET 2.0, and (2) this
should be trivial with an ISAPI filter. However, discussion on it
seems to have dried up a couple of years ago.
Can someone please give me a rundown on the possibilities as they
stand today? If it is possible to do what I want, I promise to
publicise the up-to-date information about the topic so no-one need
ask again. :-)
Thanks,
Craig
Re: Sending a different 401 error with ISAPI or ASP.NET 2.0
am 28.11.2007 07:36:58 von David Wang
On Nov 27, 1:49 pm, Craig Box wrote:
> I want to take a page that would otherwise generate a 401 error, and
> instead of returning the standard IIS 401, call a custom page, with
> the original request URL intact. This should then generate a client-
> side redirect to another page.
>
> By way of example: if logging intohttp://site/WindowsAuthLogin.aspx?ReturnURL=foo
> (with Windows authentication) fails, I want the 401 page to trigger a
> redirect tohttp://site/FormsLogin.aspx?ReturnURL=foo. This can't be a
> 302 redirect because the browser needs the 401 to send the
> credentials, and it can't be a custom error page in IIS because I need
> to pass the ReturnURL value.
>
> (I am aware of the possibility in ASP.NET of capturing the original
> returnURL value in the global.asax, but I'd like to see if this can be
> done without changing the code.)
>
> I've done a lot of searching, and found numerous posts suggesting (1)
> custom 401 responses will be available in ASP.NET 2.0, and (2) this
> should be trivial with an ISAPI filter. However, discussion on it
> seems to have dried up a couple of years ago.
>
> Can someone please give me a rundown on the possibilities as they
> stand today? If it is possible to do what I want, I promise to
> publicise the up-to-date information about the topic so no-one need
> ask again. :-)
>
> Thanks,
> Craig
IIS version?
This is intrinsically possible in IIS7. You basically write a "custom"
CustomError module that runs before the built-in IIS CustomError
module, using the same mechanisms, and do exactly what you want in
exactly the ways you want.
This is not really possible in a generic fashion in IIS6 and earlier
because Custom Error handling is a function of the handler, not IIS.
- ISAPI Filter is an extension of IIS functionality, not handler nor
IIS. It can easily capture the HTTP response status code but not the
sub-status code. You can choose to buffer the response and figure it
out, but that is not guaranteed.
- Application Frameworks like ASP.Net have their own custom error
mechanisms, but they do not apply generically -- only whatever
ASPNET_ISAPI is Application Mapped to.
- IIS Static File Handler obey Custom Error handling as configured via
the IIS UI, as well as any other ISAPI/CGI which reads IIS Custom
Error configuration and behaves accordingly or uses the
HSE_REQ_SEND_CUSTOM_ERROR API function call.
- Any other handler simply has no integration with IIS CustomError and
thus ISAPI Filter is the only way to deal with them
//David
http://w3-4u.blogspot.com
http://blogs.msdn.com/David.Wang
//
Re: Sending a different 401 error with ISAPI or ASP.NET 2.0
am 28.11.2007 15:18:07 von Craig Box
Hi David,
> IIS version?
Unfortunately, IIS6. I thought about this after posting and knew that
seeing as I'd neglected to mention, it would be easy on IIS7 and hard
on IIS6!
> This is not really possible in a generic fashion in IIS6 and earlier
> because Custom Error handling is a function of the handler, not IIS.
> - ISAPI Filter is an extension of IIS functionality, not handler nor
> IIS. It can easily capture the HTTP response status code but not the
> sub-status code. You can choose to buffer the response and figure it
> out, but that is not guaranteed.
I would be prepared in this case to redirect on any 401, not just
401.1.
> - Application Frameworks like ASP.Net have their own custom error
> mechanisms, but they do not apply generically -- only whatever
> ASPNET_ISAPI is Application Mapped to.
Again, I only need to catch a 401 on an .aspx page (but only one) - so
if there is a good answer involving writing an HTTP handler for
ASP.NET 2.0, I'd love a link to it.
Thanks for your reply. Hopefully a smart solution will come out of
the woodwork!
Craig
Re: Sending a different 401 error with ISAPI or ASP.NET 2.0
am 28.11.2007 22:01:05 von Craig Box
Here's another related question, which would solve the same problem.
Is it possible to write your own back-end to the Integrated Windows
Authentication provider to IIS? Can you hook into it allowing it to
return 'true' to users other than just those with Windows accounts?
I would like to allow the user to enter either a Windows username, or
an account that exists in the application database (such as one a
forms login would check against). If a Windows username exists, IIS
could impersonate that user for reading files; if not, it could use a
pre-defined (or anonymous) user.
This sounds like a nice clean solution that doesn't require using
forms, so will allow automatic login for people with it configured in
their IE zone. Which leads me to believe it can't be done (or at
least not in IIS6) :-)
Thanks,
Craig
Re: Sending a different 401 error with ISAPI or ASP.NET 2.0
am 28.11.2007 23:08:06 von David Wang
On Nov 28, 1:01 pm, Craig Box wrote:
> Here's another related question, which would solve the same problem.
>
> Is it possible to write your own back-end to the Integrated Windows
> Authentication provider to IIS? Can you hook into it allowing it to
> return 'true' to users other than just those with Windows accounts?
>
> I would like to allow the user to enter either a Windows username, or
> an account that exists in the application database (such as one a
> forms login would check against). If a Windows username exists, IIS
> could impersonate that user for reading files; if not, it could use a
> pre-defined (or anonymous) user.
>
> This sounds like a nice clean solution that doesn't require using
> forms, so will allow automatic login for people with it configured in
> their IE zone. Which leads me to believe it can't be done (or at
> least not in IIS6) :-)
>
> Thanks,
> Craig
IIS's authentication providers are not extensible. This is true for
all versions of IIS.
Your "clean" solution requires that you write your own custom
authentication protocol from scratch. For many reasons, trying to
patch together existing protocols is simply kludgy and insecure, and
no secure authentication protocols support it. It's the same argument
that IIS's authentication providers are not extensible.
What IIS7 does is make custom authentication protocols easier to plug
in, but you still gotta do the work to create the custom
authentication protocol.
This can be done on both IIS6 and IIS7, in different ways.
For example, what you would like to do is not really compatible
between the Integrated Windows Authentication protocol and the typical
Forms Login protocol. IWA never passes the username nor password over
the wire, uses an HTTP request header to transport the hashes around,
and the end result of the auth handshake is a Windows user token.
Forms Login protocol either passes some encrypted form of the username/
password or hash over the HTTP request entity body to the server, and
the end result of the handshake is some token which may not have any
relationship to a Windows user token. You can't just merge the two
protocols together at arbitrary times or extension hooks -- there are
different security problems and assumptions for each protocol.
In other words, what you want to do is possible. It is just no where
as simple as you think.
//David
http://w3-4u.blogspot.com
http://blogs.msdn.com/David.Wang
//