IIS 7.5: How to configure custom Authentication Error page with Windows Authentication. 401 header problems

custom-errorsiis-7.5windows-authentication

I have a php website running under IIS 7.5. The site is secured by Windows authentication and that works fine:

Windows Authentication is on

When users go to the site, they are asked for username/password and get through if authenticated. If users click Cancel or mistype password 3 times, they are shown 401 error page:

Ugly 401 page

Now I would like to show custom page explaining how to log-in. So I go to Error pages, select status code 401.2 and point it to the page I would like to display:

Error pages settings

Then make sure the custom errors are turned on for everybody. And kaa-boom! Authentication does not work any more, users are not presented with the password prompt. As documentation says, Windows Authentication works by sending 401 reply first, then browser asks user to provider credentials and then they work out what to do next.

What happens here: on first request for the page IIS tries to send 401-header, but notices that web.config says "on 401 redirect to this page". And instead of authentication, it just gives the redirect page.

I've tried replacing 401, 401.1, 401.2 – made no difference.

What am I doing wrong and how to give custom page on user authentication error?

p.s. Here is the web.config:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <httpErrors errorMode="Custom">
            <remove statusCode="500" subStatusCode="-1" />
            <remove statusCode="404" subStatusCode="-1" />
            <remove statusCode="401" subStatusCode="-1" />
            <error statusCode="401" subStatusCode="2" prefixLanguageFilePath="" path="/not_restricted/401.htm" responseMode="ExecuteURL" />
            <error statusCode="404" prefixLanguageFilePath="" path="/not_restricted/404.htm" responseMode="ExecuteURL" />
        </httpErrors>
        <httpProtocol>
            <customHeaders>
                <remove name="X-Powered-By" />
            </customHeaders>
        </httpProtocol>
    </system.webServer>
    <system.web>
        <identity impersonate="false" />
        <customErrors defaultRedirect="http://www.myserver.com/not_restricted/500.htm" mode="Off">
        </customErrors>
    </system.web>
</configuration>

Best Answer

Try this:

change:

<error statusCode="401" subStatusCode="2" prefixLanguageFilePath="" path="/not_restricted/401.htm" responseMode="ExecuteURL" />

to

<error statusCode="401" subStatusCode="2" prefixLanguageFilePath="" path="not_restricted\401.htm" responseMode="File" />

With the response mode 'File' IIS just loads the content of that file and displays it, it still sends the 401 status back to the client.

I used to use 'ExecuteURL' but have learned that File mode works much better. You just have to make sure that any linked resources in your error pages still work.