Normally, the ISAPI extension gets a request after the authentication was successful by the IIS engine. If there is, for example, a database connection, and you want to use a user input for username and password for the database connection, you will use a HTML Form to ask for that. Why not use the standard browser authorization dialog for that? Because, the database user is not a valid Windows user and authentication fails! OK, can be, but is it impossible to use it nevertheless? No, you must read on!
In the ISAPI extension, we search for the
HTTP_AUTHORIZATION header. If we do not find anything, we reject the request with "HTTP/1.1 401.5 Access Denied". The browser prompts for username and password. After the client has send us the authentication information, we can use a ISAPI Filter to catch the
OnAuthentication event and set the username back to anonymous. What is the result? The IIS engine calls our extension as anonymous, but the
HTTP_AUTHORIZATION header is still present, so we can use it. ;o) Great!
The code for the Filter
Put this in the
OnAuthenticate method and define a constant with the name of your ISAPI extension DLL. Why? We would do this only if the user called our extension.
#define MODULNAME "myextension.dll"
DWORD dwSize = sizeof(szURL);
if(pCtxt->GetServerVariable(HEADER_URL, szURL, &dwSize) == TRUE)
if(strstr(_strlwr(szURL), MODULNAME) != 0)
pAuthent->pszUser = pAuthent->pszPassword = '\0';
The code for the Extension
Put this in your extension. We would do this only if the user called our extension. To decode the BASE64 encoded Username:Password, I used a class called
Base64Coder found here.
static const TCHAR szAuthRequired = _T("HTTP/1.1 401.5 Access Denied\r\n
WWW-Authenticate: Basic realm=\"my own realm\"\r\nContent-Length: 837\r\n
char szAUTHORIZATION = "";
DWORD dwSize = sizeof(szAUTHORIZATION);
szAUTHORIZATION, &dwSize) == TRUE)
if(strstr(szAUTHORIZATION, "Basic ") != NULL)
strcpy(szdecode, szAUTHORIZATION + 6);
pdest = strstr(szdata, ":");
pos = pdest - szdata + 1;
if(pos <= 0)
pCtxt->m_bSendHeaders = FALSE;
dwSize = strlen(szAuthRequired);
pCtxt->WriteClient(szAuthRequired, &dwSize, 0);
sztmp[pos - 1] = '\0';
m_strUserName = sztmp;
strcpy(sztmp, szdata + pos);
m_strPassword = sztmp;
If you want, you can put the code for the filter and the extension in one DLL.
This only works if basic authentication is active. I suggest to use it only in combination of SSL, so that the communication between IIS server and browser is encrypted.
if((this == "nice") || (this == "great"))
pReponse->SetHeader(pfc, (char*) _T("great-stuff:"), (char*) _T("true"));
Please rate this article for me! You will find the rating down right.
Version: 1.0 - prepared for uploading.