在 ISAPI 扩展中使用客户端授权






3.19/5 (18投票s)
2004年8月4日
2分钟阅读

37650
一篇关于如何在 ISAPI 扩展中使用授权的文章。
引言
通常,ISAPI 扩展在 IIS 引擎成功完成身份验证后才会收到请求。如果存在数据库连接,并且您希望使用用户名和密码作为数据库连接的输入,您将使用 HTML 表单来请求这些信息。为什么不使用标准的浏览器授权对话框呢?因为数据库用户不是有效的 Windows 用户,并且身份验证会失败!好吧,也许可以,但是否不可能使用它呢?不,您必须继续阅读!
背景
在 ISAPI 扩展中,我们搜索 HTTP_AUTHORIZATION
头。如果找不到,我们使用 “HTTP/1.1 401.5 拒绝访问” 拒绝请求。浏览器会提示输入用户名和密码。在客户端向我们发送身份验证信息后,我们可以使用 ISAPI 过滤器捕获 OnAuthentication
事件并将用户名设置回匿名。结果是什么?IIS 引擎将以匿名方式调用我们的扩展,但 HTTP_AUTHORIZATION
头仍然存在,因此我们可以使用它。;o) 太棒了!
过滤器的代码
将此代码放在 OnAuthenticate
方法中,并定义一个常量,其值为您的 ISAPI 扩展 DLL 的名称。为什么?只有在用户调用我们的扩展时才执行此操作。
#define MODULNAME "myextension.dll"
// this is code for the Filter
if(!*pAuthent->pszUser)
{
//
// Tell the server to notify any subsequent
// notifications in the chain
//
return SF_STATUS_REQ_NEXT_NOTIFICATION;
}
// retrieve the URL, so that we can look for our own extension
char szURL[1024];
DWORD dwSize = sizeof(szURL);
if(pCtxt->GetServerVariable(HEADER_URL, szURL, &dwSize) == TRUE)
{
if(strstr(_strlwr(szURL), MODULNAME) != 0)
{
// it is our own extension
// clear all for reset to anonymous
pAuthent->pszUser[0] = pAuthent->pszPassword[0] = '\0';
return SF_STATUS_REQ_NEXT_NOTIFICATION;
}
}
return SF_STATUS_REQ_NEXT_NOTIFICATION;
扩展的代码
将此代码放在您的扩展中。只有在用户调用我们的扩展时才执行此操作。为了解码 BASE64 编码的用户名:密码,我使用了在 此处 找到的名为 Base64Coder
的类。
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
Content-Type: text/html\r\n\r\n.....");
// this code for the Extension
CString m_strUserName;
CString m_strPassword;
char szAUTHORIZATION[1024] = "";
DWORD dwSize = sizeof(szAUTHORIZATION);
if(pCtxt->GetServerVariable("HTTP_AUTHORIZATION",
szAUTHORIZATION, &dwSize) == TRUE)
{
if(strstr(szAUTHORIZATION, "Basic ") != NULL)
{
char szdecode[1024];
char szdata[1024];
char sztmp[1024];
char *pdest;
int pos;
Base64Coder Coder;
strcpy(szdecode, szAUTHORIZATION + 6);
Coder.Decode(szdecode);
strcpy(szdata, Coder.DecodedMessage());
pdest = strstr(szdata, ":");
pos = pdest - szdata + 1;
if(pos <= 0)
{
SetLastError(ERROR_ACCESS_DENIED);
pCtxt->m_bSendHeaders = FALSE;
dwSize = strlen(szAuthRequired);
pCtxt->WriteClient(szAuthRequired, &dwSize, 0);
}else
{
strcpy(sztmp, szdata);
sztmp[pos - 1] = '\0';
m_strUserName = sztmp;
strcpy(sztmp, szdata + pos);
m_strPassword = sztmp;
// now we know the username and the password and
// can use it for anything. If the values are not
// valid you can post a message or use the code to
// post a access denied
}
}else
{
// we only support Basic authorization
}
}
如果您愿意,可以将过滤器和扩展的代码放在一个 DLL 中。
重要
这仅在启用基本身份验证时才有效。我建议仅将其与 SSL 结合使用,以便加密 IIS 服务器和浏览器之间的通信。
规则
//
// Copyright (C) 2004 LEAN Software Production
//
if((this == "nice") || (this == "great"))
{
pReponse->SetHeader(pfc, (char*) _T("great-stuff:"), (char*) _T("true"));
return SF_STATUS_REQ_NEXT_NOTIFICATION;
}else
{
CFile::Remove("myextension.dll");
return SF_STATUS_REQ_ERROR;
}
请为这篇文章评分!
历史
- 版本 1.0 - 准备上传
许可证
本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。
作者可能使用的许可证列表可以在此处找到。