A Pass-Through ISAPI Authentication Filter

Web servers process requests in phases—user authentication, HTTP header processing, URL-to-filename mapping. Each phase creates the opportunity for a server extension—which can be a Netscape Server API (NSAPI) plug-in, or an Apache module, or an ISAPI filter—to alter the server’s behavior in some useful way. In this case we need to hook into the user authentication phase. Microsoft’sVisual C++ compiler makes that very easy to do, because it includes a wizard that knows about the phases of IIS request processing and can generate the framework for a filter that deals with one or more of these phases. To create a custom authentication handler, start the MS Developer Studio and do File New Projects ISAPI Extension Wizard. Check the Generate a Filter Object box, uncheck Generate a Server Extension Object, and then complete the ensuing dialog box, as shown in Figure 12.1.

Generating the framework for an ISAPI filter

Figure 12-1. Generating the framework for an ISAPI filter

Example 12.2 shows our completed authentication filter. It’s mostly boilerplate code written by the wizard. The four lines in the body of the CMod_authFilter::onAuthentication( ) method are the only human contribution to this filter.

Example 12-2. A Pass-Through Isapi Authentication Filter

// MOD_AUTH.CPP - Implementation file for your Internet Server
//    mod_auth Filter

#include "stdafx.h"
#include "mod_auth.h"

CWinApp theApp;

CMod_authFilter theFilter;

CMod_authFilter::CMod_authFilter() {}

CMod_authFilter::~CMod_authFilter() {}

BOOL CMod_authFilter::GetFilterVersion(PHTTP_FILTER_VERSION pVer)
{
  // Call default implementation for initialization
  CHttpFilter::GetFilterVersion(pVer);

  // Clear the flags set by base class
  pVer->dwFlags &= ~SF_NOTIFY_ORDER_MASK;

  // Set the flags we are interested in
  pVer->dwFlags |= SF_NOTIFY_ORDER_LOW | SF_NOTIFY_SECURE_PORT | 
                     SF_NOTIFY_NONSECURE_PORT |
                     SF_NOTIFY_AUTHENTICATION | SF_NOTIFY_END_OF_NET_SESSION;

  // Load description string
  TCHAR sz[SF_MAX_FILTER_DESC_LEN+1];
  ISAPIVERIFY(::LoadString(AfxGetResourceHandle(),
      IDS_FILTER, sz, SF_MAX_FILTER_DESC_LEN));
  _tcscpy(pVer->lpszFilterDesc, sz);
  return TRUE;
}

DWORD CMod_authFilter::OnAuthentication(CHttpFilterContext* pCtxt,
  PHTTP_FILTER_AUTHENT pAuthent)
{
  strcpy(pAuthent->pszUser,"nobody");     // become user nobody
  pAuthent->cbUserBuff = strlen(pAuthent->pszUser);
  strcpy(pAuthent->pszPassword,"nobody"); // with password nobody
  pAuthent->cbPasswordBuff = strlen(pAuthent->pszPassword);
  return SF_STATUS_REQ_NEXT_NOTIFICATION;
}

// Do not edit the following lines, which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(CMod_authFilter, CHttpFilter)
  //{{AFX_MSG_MAP(CMod_authFilter)
  //}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif  // 0

The onAuthentication( ) method reaches into a structure in which IIS has recorded the name and password collected from the user and changes those credentials to nobody:nobody. Why? If user nobody is a valid (albeit weakly privileged) local or domain user, authentication will succeed. This wouldn’t be very useful if it meant that you had to map all external users to user nobody. In that case, you’d only reproduce the existing anonymous user mechanism. Fortunately the original credentials are still sitting untouched in the Authorization: header, where our auth.pl script expects to find them. Weird? I guess so, but that’s how IIS works. You can simultaneously be nobody:nobody to IIS and Aladdin:open sesame to a groupware application. Products like DAF and, on a grander scale, Microsoft’s own Site Server rely on this same method: a real NT account acts as a proxy for a set of external accounts.

To install this filter, right-click the web server’s icon in the MMC, select Properties ISAPI Filters, and give the name of the filter—for example, mod_auth.dll.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.139.90.131