HTTP.SYS authentification with HTTP Server API 2.0

  • warning: preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead in /data/www/dupuisme/includes/unicode.inc on line 349.
  • warning: preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead in /data/www/dupuisme/includes/unicode.inc on line 349.
  • warning: preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead in /data/www/dupuisme/includes/unicode.inc on line 349.
  • warning: preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead in /data/www/dupuisme/includes/unicode.inc on line 349.
  • warning: preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead in /data/www/dupuisme/includes/unicode.inc on line 349.
  • warning: preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead in /data/www/dupuisme/includes/unicode.inc on line 349.
In my last entry, I was detailing how to create a web server with NTLM authentication with HTTP.SYS v1.0. Since then, Microsoft updated the HTTP Server API on Vista for supporting authentication directly. However, the documentation lacks of an explicit example, so I decided to update my code.
 

Updating the server initialization

The HTTP API v2.0 is only visible if the API level is the to Vista or above (v6.0):

 

Then the process must activate the API asking for v2.0:

 

The API v2.0 is much more flexible than the API v1.0. For example, several processes can share and process a single URL (for load balancing for example). The process must create a session with HTTP.SYS then create an URL group and attach some listening URL template to it:

 

Each session and URL group have properties to alter their behavior. The most important one in this example is HttpServerAuthenticationProperty. The associate structure HTTP_SERVER_AUTHENTICATION_INFO handles all type of authentication (basic, digest, NTLM, Negotiate, Kerberos ....). For using Windows authentication, the best option is to activate the "NEGOTIATE" protocol. The client and the server will negotiate between NTLM or ActiveDirectory/Kerberos:

 

Enforcing authentication

Activating authentication on the URL group doesn't enforce it. Microsoft has decided (rightly) to let the application choose if the authentication is required. When the request is received, the HTTP_REQUEST may have an associate pRequestInfo containing authentication information. The application must check it first:

 

If m_reqAuthStatus is HttpAuthStatusSuccess, then m_hAccessToken contains the user credential and everything is OK.

But, as explained, Windows doesn't enforce authentication. So the first query will always have m_reqAuthStatus==HttpAuthStatusNotAuthenticated. Unfortunately, there is no clear API like "HttpPleaseAuthenticateRequest". The application must generate a well formed 401 response as if it would process the the authentication itself.

 

This is capture and monitored by HTTP.SYS and the remaining of the authentication process is done internally without the application intervention. Eventually, another request will be presented with the HttpAuthStatusSuccess.

As usual, please find the source code attached.

AttachmentSize
HttpServerDemo2.zip30.97 KB