Click here to Skip to main content
12,406,313 members (68,355 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as

Stats

250.5K views
2.3K downloads
43 bookmarked
Posted

ISAPI authentication filter

, 6 Dec 1999 CPOL
Rate this:
Please Sign up or sign in to vote.
This article demonstrates the use of the MFC ISAPI classes to write filters.

In this article the Microsoft SDK ISAPI authentication filter sample was rewritten using MFC ISAPI classes. The filter's funcionality remains exactly the same, the purpose of the article is to demonstrate the use of the MFC ISAPI classes to write filters. Note that this authentication filter is not the most trivial sample, it provides pretty serious functionality (Microsoft refers to it as "A Filter for Advanced Authentication"). The filter functionality is described below using an excerption of Microsoft documentation.

"AuthFilt demonstrates how to write an authentication filter based on an external datasource. Authentication is the process of accepting or denying a request from a client, so AuthFilt will be notified each time an authentication request comes in. This sample uses a file (userdb.txt) to keep track of authorized users, but you might modify this sample to access a database which holds user info.

For each authentication request, AuthFilt first looks in a cache of recently authenticated users, and when that fails, AuthFilt looks in the userdb.txt file. This shows an efficient way to authorize connections: a cache allows the filter to quickly authenticate users, and because each request comes in through the filter, speed is critical."

The project is a standard appwizard generated ISAPI filter. The global functions of the AuthFilt Microsoft sample were encapsulated in the filter class. There are 3 parameters that can be changed to fine tune the filter: the maximum number of cached users, the position after which a cached entry will be moved to the front of the list (to make the search time shorter!) and the name of the file that contains the username/password pairs and the appropriate NT account the username/password should be mapped to. All this parameters are #define directives in the authflit.h header file.

The filter could be improved in several ways: using a database instead of a file for authentication information (you should consider using stored procedures to search and/or to cache!), load parameters from registry, automatic selection of the number of cached users and the list reorder parameter, etc.

The full source code is provided, you will have to compile it in order to get a working filter. Once you have compiled the project you will need to take the following steps to install:

  1. Run REGEDT32.EXE and modify the server's registry as follows. Select the Filter DLLs key in HKEY_LOCAL_MACHINE\CurrentControlSet\Services\W3SVC\Parameters. Add a local path to authfilt.dll, usually C:\WinNT\System32\InetSrv\authfilt.dll. The filter entries are separated by commas. The order is important, if you have other authentication filter with the same priority, the first one listed will receive the authentication request.
  2. Copy the authfilt.dll file to the directory you specified in the registry.
  3. Make sure the System account have execute rights on the filter dll file.
  4. Edit the userdb.txt file so it contains valid users and passwords. The format of the file is:
    User1:Password1, NTUser1:NTPassword1
    User2:Password2, NTUser2:NTPassword2
    User3:Password3, NTUser3:NTPassword3
  5. Copy the userdb.txt file to the directory you specified in the authfilt.h header file for the user database.
  6. Make sure the System account have read rights on the userdb.txt file.
  7. Restart the WWW service.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

No Biography provided

You may also be interested in...

Comments and Discussions

 
QuestionISAPI Development Question Pin
FranklinIssac11-Jun-08 8:13
memberFranklinIssac11-Jun-08 8:13 
QuestionISAPI for Windows 2003 Server IIS Service not work !? Pin
jackie hsu18-Mar-08 18:04
memberjackie hsu18-Mar-08 18:04 
AnswerRe: ISAPI for Windows 2003 Server IIS Service not work !? Pin
shanhe24-Aug-09 4:23
membershanhe24-Aug-09 4:23 
GeneralISAPI authentication filter problem Pin
imazing1039-Dec-07 19:35
memberimazing1039-Dec-07 19:35 
I have written an authentication filter which performs non form based Basic authentication. The problem is once the authentication is done the page does not get displayed.

//Code
#include
#include
#include
#include
#define USERNAME "user"
#define PASSWORD "pass"
#define DOMAIN "domain.com"
#define BASIC_HDR "Basic"
#define FOURK_STR_SIZE 4*1024
#define ONEK_STR_SIZE 1024


DWORD WINAPI
HttpFilterProc( PHTTP_FILTER_CONTEXT pfc,
DWORD notificationType,
VOID *pvNotification )
{
struct
{
char userpass[ONEK_STR_SIZE];
char url[ONEK_STR_SIZE];
char cookie[256];
}*head;
unsigned int cookielen;
char domain[ONEK_STR_SIZE];
DWORD urllen = sizeof(head->url);
char str[ONEK_STR_SIZE];
char *user = NULL;
char *pass = NULL;
char szBuffer [ FOURK_STR_SIZE + 1 ] = { 0 };
char *userpass64;
char userpassde[ONEK_STR_SIZE];
char *up1;
unsigned int userpassdelen;
DWORD userpasslen;

HTTP_FILTER_PREPROC_HEADERS *headers = (HTTP_FILTER_PREPROC_HEADERS *) pvNotification;
HTTP_FILTER_SEND_RESPONSE *response = (HTTP_FILTER_SEND_RESPONSE *) pvNotification;


switch(notificationType)
{

case SF_NOTIFY_PREPROC_HEADERS :


OutputDebugString("SF_NOTIFY_PREPROC_HEADERS");

if ( !pfc->pFilterContext )
{
pfc->pFilterContext = pfc->AllocMem( pfc, sizeof ( head ), 0 );
if ( !pfc->pFilterContext )
{
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return SF_STATUS_REQ_ERROR;
}
}
head = pfc->pFilterContext;
headers->GetHeader( pfc, "url", head->url,&urllen);
headers->GetHeader( pfc, "Authorization:", head->userpass, &userpasslen );
headers->GetHeader( pfc, "Cookie:", head->cookie, &cookielen );

sprintf(str,"url is %s userpass is %s cookie is %s",head->url,head->userpass,head->cookie);
OutputDebugString(str);
sprintf(str,"url length is %d userpass length is %d cookie length is %d",strlen(head->url),strlen(head->userpass), strlen(head->cookie));
OutputDebugString(str);


//break;

case SF_NOTIFY_AUTHENTICATION:

OutputDebugString("SF_NOTIFY_AUTHENTICATION");


if ( !strcmp(head->cookie,"auth=Authenticated") )
{
OutputDebugString("Authentication completed");
OutputDebugString("returning SF_STATUS_REQ_NEXT_NOTIFICATION");
return SF_STATUS_REQ_NEXT_NOTIFICATION;
}

else //No cookie or cookie has auth=NotAuthenticated
{
OutputDebugString("cookie not equals auth=Authenticated");

if(!strlen(head->userpass)==0) //Check whether username and password are being sent
{
OutputDebugString(str);
OutputDebugString(head->userpass);
userpass64 = (char*) malloc (strlen(head->userpass));

userpass64=strchr(head->userpass,' '); //separating the base64 part from the rest of the string
userpass64++;
OutputDebugString(userpass64);


// decoding the base64 username password

b64_decode(userpass64,strlen(userpass64),userpassde,&userpassdelen); // Decoded string is stored in userpassde


OutputDebugString(userpassde);//Output will be user:pass
up1 = (char*) malloc (strlen(userpassde));
strcpy(up1,userpassde);

OutputDebugString(up1);
user=strtok(userpassde,":");//Copy user into a string

OutputDebugString(user);
pass=strchr(up1,':');//Copy pass into a string
pass++;//Remove : from the string
OutputDebugString(pass);


if( !strcmp( user, USERNAME ) && !strcmp( pass, PASSWORD ) )

{
//Every thing is perfect
OutputDebugString("All conditions satisfied");
pfc->AddResponseHeaders(pfc,"Set-Cookie: auth=Authenticated; path=/;\r\n", 0);
OutputDebugString("returning SF_STATUS_REQ_NEXT_NOTIFICATION");
return SF_STATUS_REQ_NEXT_NOTIFICATION;
}
}
//All conditions have failed

OutputDebugString("Wrong Username or password");

sprintf(domain, "WWW-Authenticate: Basic realm=\"%s\"\r\n", DOMAIN);
pfc->AddResponseHeaders(pfc,"Set-Cookie: auth=NotAuthenticated; path=/;\r\n", 0);
pfc->ServerSupportFunction( pfc, SF_REQ_SEND_RESPONSE_HEADER,
(PVOID) "401 Unauthorized",
(DWORD) domain,
(DWORD) NULL );

OutputDebugString("returning SF_STATUS_REQ_FINISHED_KEEP_CONN");
return SF_STATUS_REQ_FINISHED_KEEP_CONN;

}

break;


default:
break;

}


return SF_STATUS_REQ_NEXT_NOTIFICATION;

}


Debug Output :

00000000 1:06:18 PM [5924] SF_NOTIFY_PREPROC_HEADERS
00000001 1:06:18 PM [5924] url is /index.htm userpass is cookie is
00000002 1:06:18 PM [5924] url length is 10 userpass length is 0 cookie length is 0
00000003 1:06:18 PM [5924] SF_NOTIFY_AUTHENTICATION
00000004 1:06:18 PM [5924] cookie not equals auth=Authenticated
00000005 1:06:18 PM [5924] Wrong Username or password
00000006 1:06:18 PM [5924] returning SF_STATUS_REQ_FINISHED_KEEP_CONN
00000007 1:06:23 PM [5924] SF_NOTIFY_PREPROC_HEADERS
00000008 1:06:23 PM [5924] url is /index.htm userpass is Basic dXNlcjpwYXNz cookie is auth=NotAuthenticated
00000009 1:06:23 PM [5924] url length is 10 userpass length is 18 cookie length is 21
00000010 1:06:23 PM [5924] SF_NOTIFY_AUTHENTICATION
00000011 1:06:23 PM [5924] cookie not equals auth=Authenticated
00000012 1:06:23 PM [5924] url length is 10 userpass length is 18 cookie length is 21
00000013 1:06:23 PM [5924] Basic dXNlcjpwYXNz
00000014 1:06:23 PM [5924] dXNlcjpwYXNz
00000015 1:06:23 PM [5924] user:pass
00000016 1:06:23 PM [5924] user:pass
00000017 1:06:23 PM [5924] user
00000018 1:06:23 PM [5924] pass
00000019 1:06:23 PM [5924] All conditions satisfied
00000020 1:06:23 PM [5924] returning SF_STATUS_REQ_NEXT_NOTIFICATION

imazing

GeneralISAPI on ISA Server Pin
LeoNicolas15-Mar-05 6:01
memberLeoNicolas15-Mar-05 6:01 
GeneralISAPI filter for Windows Shared Services Pin
Sarma Pisapati25-Sep-04 2:10
memberSarma Pisapati25-Sep-04 2:10 
QuestionGetting client IP address in ISAPI filters? Pin
gtyhf8-Jul-04 20:32
membergtyhf8-Jul-04 20:32 
GeneralGetting Session ID without using cookies. Pin
gtyhf8-Jul-04 20:26
membergtyhf8-Jul-04 20:26 
GeneralRe: Getting Session ID without using cookies. Pin
Gumba14-Sep-04 20:28
memberGumba14-Sep-04 20:28 
GeneralCannot execute Pin
Anonymous7-Apr-04 22:36
sussAnonymous7-Apr-04 22:36 
QuestionHow to use this?? Pin
alan9325-Aug-03 12:25
memberalan9325-Aug-03 12:25 
GeneralProject compiled in VC++.NET is not working Pin
Udhaya Moorthi5-Aug-03 20:16
memberUdhaya Moorthi5-Aug-03 20:16 
GeneralRe: Project compiled in VC++.NET is not working Pin
slimtim25-Nov-03 13:15
memberslimtim25-Nov-03 13:15 
Questionuser/password not being passed?? Pin
hanzhanquan2002atyahoocomcn20-Mar-03 16:03
memberhanzhanquan2002atyahoocomcn20-Mar-03 16:03 
QuestionHow can I activate this filter!! Pin
sayhappy2-Dec-02 21:02
membersayhappy2-Dec-02 21:02 
AnswerRe: How can I activate this filter!! Pin
hanzhanquan2002atyahoocomcn20-Mar-03 16:11
memberhanzhanquan2002atyahoocomcn20-Mar-03 16:11 
GeneralConcurrency issues with the IIS Log Pin
Anonymous16-Oct-02 11:53
memberAnonymous16-Oct-02 11:53 
GeneralGetting IIS 5 SessionID vai ISAPI Filter Pin
Ajith de Silva19-May-02 22:00
memberAjith de Silva19-May-02 22:00 
GeneralRe: Getting IIS 5 SessionID vai ISAPI Filter Pin
Taliesin13-Sep-02 21:04
sussTaliesin13-Sep-02 21:04 
QuestionWinNT account from ISAPI????? Pin
Jesse20027-May-02 15:43
memberJesse20027-May-02 15:43 
QuestionISAPI filter sends HTTP client call? Pin
thorsten25-Apr-02 21:20
memberthorsten25-Apr-02 21:20 
GeneralUser not being passed Pin
Gerard Nicol19-Mar-02 16:06
memberGerard Nicol19-Mar-02 16:06 
GeneralRe: User not being passed Pin
hanzhanquan2002atyahoocomcn20-Mar-03 15:35
memberhanzhanquan2002atyahoocomcn20-Mar-03 15:35 
GeneralRe: User not being passed Pin
Muhammad Asim Sajjad25-Sep-07 22:29
memberMuhammad Asim Sajjad25-Sep-07 22:29 
GeneralInstall of ISAPI Filter Pin
Anonymous6-Feb-02 11:58
memberAnonymous6-Feb-02 11:58 
GeneralForm based authentication Pin
Bob Cowdery5-Feb-02 22:33
memberBob Cowdery5-Feb-02 22:33 
GeneralRe: Form based authentication Pin
Bob Cowdery6-Feb-02 2:18
memberBob Cowdery6-Feb-02 2:18 
GeneralIIS Filter & Cookie Pin
Anonymous18-Oct-01 7:31
memberAnonymous18-Oct-01 7:31 
Generalcache Pin
Anonymous18-Oct-01 3:37
memberAnonymous18-Oct-01 3:37 
GeneralRe: cache Pin
Anonymous16-Oct-02 11:21
memberAnonymous16-Oct-02 11:21 
GeneralAuthfilt.dll & IIS problem Pin
Anonymous21-Sep-01 11:13
memberAnonymous21-Sep-01 11:13 
GeneralRe: Authfilt.dll & IIS problem Pin
Anonymous12-Jun-02 10:18
memberAnonymous12-Jun-02 10:18 
Questionisapi filter ? Pin
yatch8-Aug-01 15:36
memberyatch8-Aug-01 15:36 
AnswerRe: isapi filter ? Pin
Rajendrappa9-Sep-01 18:47
memberRajendrappa9-Sep-01 18:47 
GeneralDistributing SSL cert's Pin
Anonymous11-Jun-01 10:12
memberAnonymous11-Jun-01 10:12 
GeneralCan't get it to work Pin
Anonymous7-Jun-01 3:50
memberAnonymous7-Jun-01 3:50 
GeneralRe: Can't get it to work Pin
ThatInstant12-Dec-03 8:46
memberThatInstant12-Dec-03 8:46 
GeneralIs it possible One directory, one diferent ACL? (as Apache) Pin
Rafa23-Feb-01 2:02
memberRafa23-Feb-01 2:02 
GeneralRe: Is it possible One directory, one diferent ACL? (as Apache) Pin
Anonymous9-Oct-01 2:55
memberAnonymous9-Oct-01 2:55 
GeneralAuthentication from database Pin
Bill Robinson28-Jul-00 10:55
sussBill Robinson28-Jul-00 10:55 
GeneralRe: Authentication from database Pin
Tom de Grunt5-Feb-01 0:00
memberTom de Grunt5-Feb-01 0:00 
GeneralRe: Authentication from database Pin
Taliesin14-Apr-02 20:01
memberTaliesin14-Apr-02 20:01 
QuestionWhy map to NT account? Pin
Scott4-Jul-00 20:24
sussScott4-Jul-00 20:24 
AnswerRe: Why map to NT account? Pin
Anonymous25-Jan-01 15:24
memberAnonymous25-Jan-01 15:24 
GeneralRe: Why map to NT account? Pin
Daniele Speziale21-Feb-01 21:49
memberDaniele Speziale21-Feb-01 21:49 
GeneralRe: Why map to NT account? Pin
Anonymous17-Apr-01 3:43
memberAnonymous17-Apr-01 3:43 
Generalauthentication with LDAP Pin
daniele speziale6-Jun-00 21:13
sussdaniele speziale6-Jun-00 21:13 
GeneralRe: authentication with LDAP Pin
Anonymous5-Sep-01 13:13
memberAnonymous5-Sep-01 13:13 
GeneralRe: authentication with LDAP Pin
Jim Willeke13-Apr-02 1:12
memberJim Willeke13-Apr-02 1:12 
GeneralRe: authentication with LDAP Pin
PaoloM14-May-02 5:37
memberPaoloM14-May-02 5:37 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.160726.1 | Last Updated 7 Dec 1999
Article Copyright 1999 by Jorge Lodos
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid