IIS筛选器编程

基于Vc++开发IIS7以及IIS6的万能筛选器

一、iis6篇

1)新建工程:准备好vs6以后,新建新工程,选择"ISAPI Filter Wizard" 工程类型,一路下一步之后,工程目录就出来了(暂时将我们初始化的filter类命令为CTestFilter)。

2)打开vs初始化的工程,打开CTestFilter.cpp文件,我们可以看到有一个自动生成的函数:

BOOL CTestFilter::GetFilterVersion(PHTTP_FILTER_VERSION pVer)
{
// Call default implementation for initialization
CTestFilter::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_HIGH| SF_NOTIFY_PREPROC_HEADERS | SF_NOTIFY_SEND_RAW_DATA;

// 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;
}

不要关注其他代码,只需要关注红色字体部分,这几个系统常量是用来指定筛选器需要拦截哪些http内容的,我简单拦截类型有好几种,详细信息可以查询msdn的文档,我只简单介绍下其中的SF_NOTIFY_PREPROC_HEADERS和 SF_NOTIFY_SEND_RAW_DATA,SF_NOTIFY_PREPROC_HEADERS代表在iis处理http的header请求时触发一次拦截,而SF_NOTIFY_SEND_RAW_DATA代表在iis向客户端回写http的response内容前触发拦截,在这个拦截当中,你可以接收到response的指针,修改response的内容。

3)还是用wizard,去实现CHttpFilter基类的各个拦截方法(需要与前面的GetFilterVersion方法中指定的拦截事件对应,否则iis不会触发这些方法的),这里我还是介绍下与上一步向对应的OnSendRawData(CHttpFilterContext* pfc, PHTTP_FILTER_RAW_DATA pRawData)和OnPreprocHeaders(CHttpFilterContext* pfc,PHTTP_FILTER_PREPROC_HEADERS pHeaders)两个函数,大家可以很容易地看出这两个函数与前面两个拦截类型的对应关系。OnPreprocHeaders是专门用来在iis处理http请求前,对客户端的http header进行处理,其中入参pHeaders是个结构型数据,其中包含了一个指向header对象的指针,我们可以拿到这个指针进行预处理,并可以修改headers的内容。

OnSendRawData可以说是这些方法中最强悍的了,它可以拿到iis的response内容,并可以修改response的内容,其中pRawData这个结构型的入参就包含了response内容的指针,还是上代码给大家讲讲这个函数是如何去修改一切的吧:

DWORD CTestFilter::OnSendRawData(CHttpFilterContext* pfc, PHTTP_FILTER_RAW_DATA pRawData)
{
// TODO: Add your specialized code here and/or call the base class
CString resp="Hello isapi!!";
void* mem=(void*)pfc->AllocMem(resp.GetLength());//必须使用isapi提供的申请内存方法,才能正常返回http内容,用isapi的方法申请的内存,iis会自动帮你回收
memset(mem,0,resp.GetLength());
memcpy(mem,resp.GetBuffer(0),resp.GetLength());
pRawData->cbInBuffer=resp.GetLength();
pRawData->cbInData=resp.GetLength();
pRawData->pvInData=mem;
return SF_STATUS_REQ_NEXT_NOTIFICATION;
}

这样修改过后,所有客户端的请求都变成了”Hello isqpi!!“了,而且连正常的http头都被去掉了。

4)部署:编译完成刚才的工程后,我们可以得到一个TestFilter.dll的文件,打开iis6的管理页面,进入web站点的属性对话框,到isapi的选项卡中,添加我们刚才生成的dll文件,并重启iis服务器,ok,iis就只会返回”Hello isapi!!“了。

二、iis7篇

伴随着windows server2008的出现,iis7也一起推出,iis7虽然也可以通过很曲折的方式,实现isapi接口功能,但根据实践的情况来开,iis7在使用isapi扩展来实现拦截功能时,经常会出现拦截不了的烦人问题,这时我们在查阅了大量资料后发现,iis7对isapi的支持本来就不好,因为微软又在iis7这个平台上推出了一个更强大的拦截实现,那就是iis扩展模块,iis7的所有功能都是通过加载不同的模块来实现的,而且为我们实现拦截器特别提供了一个httpmodule的模块,这个模块是凌驾于所有http请求的,不管你使用的asp还是asp.net甚至是借用iis做服务器的php服务器,所有的请求都会先经过这个模块来处理,难怪微软不会去关注iis7对isapi的兼容问题,它要推新东西了嘛~

下面我们就介绍下如何通过iis的模块来实现拦截并修改http请求的功能:

1)环境准备:visual studio2008/2005+iis7+windows server2008。

2)新建c++工程:在vs中新建一个空的动态链接库的工程。

3)新建一个CHttpModule的子类CMyHttpModule(需要基于对头文件httpserv.h的引用),并实现一个虚方法OnBeginRequest:

#define _WINSOCKAPI_
#include <windows.h>
#include <sal.h>
#include <httpserv.h>

class CMyHttpModule: public CHttpModule
{
public:
REQUEST_NOTIFICATION_STATUS
OnBeginRequest(
IN IHttpContext * pHttpContext,
IN IHttpEventProvider * pProvider
)
{
UNREFERENCED_PARAMETER( pProvider );

// 创建一个 HRESULT 来接收方法返回值.
HRESULT hr;

// 获取一个指向response对象的指针.
IHttpResponse * pHttpResponse = pHttpContext->GetResponse();

if (pHttpResponse != NULL)
{
// 直接清理掉原来的response内容.
pHttpResponse->Clear();
// 设置response的格式.
pHttpResponse->SetHeader(
HttpHeaderContentType,"text/plain",
(USHORT)strlen("text/plain"),TRUE);

PCSTR pszBuffer = "Hello HttpModule!!!";
// 创建一个数据块.
HTTP_DATA_CHUNK dataChunk;
// 把数据块类型设置成http类型的(后续的内存清理工作就会由iis容器自己完成).
dataChunk.DataChunkType = HttpDataChunkFromMemory;
DWORD cbSent;

// 给数据块赋值.
dataChunk.FromMemory.pBuffer =
(PVOID) pszBuffer;
dataChunk.FromMemory.BufferLength =
(USHORT) strlen(pszBuffer);
// 将数据块插入到response内容中.
hr = pHttpResponse->WriteEntityChunks(
&dataChunk,1,FALSE,TRUE,&cbSent);

if (FAILED(hr))
{
pHttpResponse->SetStatus(500,"Server Error",0,hr);
}

return RQ_NOTIFICATION_FINISH_REQUEST;
}
return RQ_NOTIFICATION_CONTINUE;
}
}

4)新建一个实现了IHttpModuleFactory接口的工厂类,用来注册拦截模块和拦截的方式

class CMyHttpModuleFactory : public IHttpModuleFactory
{
public:
HRESULT
GetHttpModule(
OUT CHttpModule ** ppModule, 
IN IModuleAllocator * pAllocator
)
{
UNREFERENCED_PARAMETER( pAllocator );

// 实例化一个模块的指针.
CMyHttpModule * pModule = new CMyHttpModule;

if (!pModule)
{
return HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
}
else
{
*ppModule = pModule;
pModule = NULL;
return S_OK;

}

void
Terminate()
{
// 清理自己的内存.
delete this;
}
};

// 用来注册模块工厂的方法.
HRESULT
__stdcall
RegisterModule(
DWORD dwServerVersion,
IHttpModuleRegistrationInfo * pModuleInfo,
IHttpServer * pGlobalInfo
)
{
UNREFERENCED_PARAMETER( dwServerVersion );
UNREFERENCED_PARAMETER( pGlobalInfo );

// 设置需要拦截的方式,这里设置的是给客户端返回response内容前,和我们之前iis6的示例类似,可以设置多个,但必须和你的httpmodule中对应.
return pModuleInfo->SetRequestNotifications(
new CMyHttpModuleFactory,
RQ_BEGIN_REQUEST,
0
);
}

5)编译并生成一个MyHttpModule.dll的动态链接库,将保存MyHttpModule.dll的全路径添加到%windir%\system32\inetsrv\config\applicationHost.config文件的globalModules节点下,重启iis,ok,这下访问你iis中的任何一个文件,返回的内容都会是:“Hello HttpModule!!!”。

时间: 2024-11-10 17:20:47

IIS筛选器编程的相关文章

调用 LoadLibraryEx 失败,在 ISAPI 筛选器 &quot;D:\Tomcat7\iis\isapi_redirect.dll&quot; 上

在配置IIS7.5和Tomcat整合时,总是报如下错误: 错误摘要 HTTP 错误 500.0 - Internal Server Error 调用 LoadLibraryEx 失败,在 ISAPI 筛选器 "D:\Tomcat7\iis\isapi_redirect.dll" 上 我的系统环境: windows2008 R2标准版 + tomcat7 + isapi_redirect.dll(连接插件) 解决方法: 开始 -> 运行 -> inetmgr -> 应用

WEB服务器5--IIS中ISAPI扩展、ISAPI筛选器

在IIS的文档中经常会提到两个术语:ISAPI扩展和ISAPI筛选器. ISAPI扩展 “ISAPI扩展(ISAPI Extension)”是一种可以添加到IIS中以增强Web服务器功能的程序,其载体为DLL文件.通常直接负责响应HTTP请求. 根据HTTP请求要访问的资源扩展名(通过URL获取),IIS会选取特定的ISAPI扩展来处理这一请求,这一过程被称为“程序映射”. 而用于响应HTTP请求的这一ISAPI扩展被称为“HTTP Handler(HTTP处理程序)”. 图 8?11展示了II

MVC中的筛选器

在 ASP.NET MVC 中,控制器将定义一些操作方法,这些操作方法与可能的用户交互(如单击链接或提交窗体)之间通常具有一一对应关系.例如,当用户单击链接时,会将请求路由到指定的控制器,然后调用对应的操作方法. 例如操作完成后你要产生日志.语言筛选.等其他动态操作. 筛选器的由来及用途 有时,您需要在调用操作方法之前或运行操作方法之后执行逻辑. 为了对此提供支持,ASP.NET MVC 提供了筛选器.筛选器是自定义类,可提供用于向控制器操作方法添加操作前行为和操作后行为的声明性和编程性手段.

MVC四大筛选器—AuthorizeFilter

在Action的执行中包括两个重要的部分,一个是Action方法本身逻辑代码的执行,第二个就是Action方法的筛选器的执行. MVC4中筛选器都是以AOP(面向方面编程)的方式来设计的,通过对Action方法上标注相应的Attribute标签来实现.MVC4提供了四种筛选器,分别为:AuthorizationFilter.ActionFilter.ExceptionFilter和ResultFilter,他们分别对应了四个筛选器接口IAuthorizationFilter.IActionFil

DirectX 因素:了解 XAudio2 中的筛选器

Charles Petzold 下载代码示例 在著名的波形的万神殿,简单的正弦曲线至高无上. 只是看着它,您可以看到其精髓的顺利起伏性质 - - 当它达到其峰值. 几乎停止,它冠,然后逐步加快速度减慢,达到它的最大速度横渡水平轴开始另一个经济放缓. 这种视觉印象更深的数学分析所证实. 正弦曲线在任意点的瞬时速度是对曲线切线. 图的那些速度,并可以得到另一个正弦曲线,由四分之一周期从原始偏移. 不要再使用这第二条曲线,它和那是显示加速度,偏移量从原来的半个周期,如中所示的正弦曲线图 1. 图 1

MVC四大筛选器—ExceptionFilter

该筛选器是在系统出现异常时触发,可以对抛出的异常进行处理.所有的ExceptionFilter筛选器都是实现自IExceptionFilter接口 public interface IExceptionFilter { void OnException(ExceptionContext filterContext); } 实现OnException方法来实现对异常的自定义处理 MVC4中实现了默认的异常处理机制,源码如下 public virtual void OnException(Excep

C# 之 读取Word时发生 “拒绝访问” 及 “消息筛选器显示应用程序正在使用中” 异常的处理

1.Asp.net中建立Microsoft.Office.Interop.Word.Application时出现 “ 拒绝访问 ” 错误 项目中要实现在服务器端打开一个Word模版文件,修改其内容后再下载到客户端使用,在Asp.net页面中建立Microsoft.Office.Interop.Word.Application对象时出现“拒绝访问”的错误,提示信息如下: 拒绝访问. 说明: 执行当前 Web 请求期间,出现未处理的异常.请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的

使用Micrisoft.net设计方案 第三章Web表示模式 Web模式集群详细介绍 Intercepting Filter(截取筛选器)

Intercepting Filter(截取筛选器) 我们在建立Web应用程序时需要更多的控制权限,或者需要在Web请求前或后,插入自己的业务逻辑. 如何围绕 Web页面请求来实现公共的预处理和后处理步骤? 有许多方法可以解决此问题,因此您需要考虑这会涉及哪些影响因素和权衡因素: A.常见的做法是,将较低级别的功能(如处理 HTTP 头.Cookie 或字符编码)与应用程序逻辑分离,这样有助于限制更改的扩散. B.许多预处理和后处理任务是所有 Web 页面公共的,应该在中心位置实现这些功能,以避

ASP.NET Web API 安全筛选器

原文:https://msdn.microsoft.com/zh-cn/magazine/dn781361.aspx 身份验证和授权是应用程序安全的基础.身份验证通过验证提供的凭据来确定用户身份,而授权则决定是否允许用户执行请求的操作.安全的 Web API 身份验证基于确定的身份请求和授权用户请求的资源访问. 您可以在 ASP.NET Web API 中使用 ASP.NET Web API 管道中提供的扩展点,以及使用由主机提供的选项来实现身份验证.对于 ASP.NET Web API 的第一