I spent a while trying to make an ISAPI filter that would perform the NTLM challenge/response handshake with Internet Explorer. Why? Well, apart from wanting to find out more about how the authentication process works, this would allow the authentication to occur without IIS then impersonating that user. In addition, you could add control with the filter without needing to worry about setting NTFS permissions on files and folders.
I ran into a problem though, and I’m sure it is my ISAPI code rather than my NTLM code causing the problem.
Here’s what happens:
The first request comes in and I check for an Authorization: header. Since there isn’t one, I send back a 401 with a WWW-Authenticate: header asking for NTLM and close the connection.
The second request comes in on a new connection as planned with an Authorization: header with NTLM and the base 64 encoded token. I hook up AcceptSecurityContext and receive SEC_I_CONTINUE_NEEDED as expected so I create a new WWW-Authenticate: header with the base 64 encoded token for the challenge. I send this back with a 401 and ask for the connection to be kept open (SF_STATUS_REQ_FINISHED_KEEP_CONN). I think this is where it goes wrong.
The next request comes in on the same connection with the NTLM response in the Authorization: header, but my filter never sees it. I can see the response from Internet Explorer by monitoring the TCP port with tcpTrace, but I think something has gone wrong with the connection by then.
What should happen is that I will get the NTLM response, again call AcceptSecurityContext and this time I should get SEC_E_OK whereupon I know that I am authenticated, I can set my custom HTTP header, and also set a flag so that I know any subsequent requests on the same connection are preauthenticated.
I’ve made the source code available here in case somebody can spot what I’ve done wrong (it’s a VS.NET project but that’s only really important in so far as I used an ATL Server include for the base 64 coding).
If you spot what is wrong or have any clues, please get in touch.