是否可以在IIS HttpModule中修改HttpRequest POST的内容?

我需要在IIS中修改某些HttpRequests(SSAS连接字符串)的内容。 基本上,我需要向请求中包含的SOAP添加一个元素。

到目前为止,我的方法是向HttpRequest添加一个Filter,并在filter的Read方法中执行更改。 据我所知,Read永远不会被执行。

我对Request.Filter的理解是它从IIS处理请求时读取,因此IIS应该看到我修改过的Request。

我正在尝试使用HttpModule实际可行,并且我的Filter方法是否正确?

如果是这样,什么会导致Read不被击中?

这是我的代码的简化版本:

public class CustomHttpModule : IHttpModule { private HttpApplication app; public string ModuleName { get { return "CustomHttpModule"; } } public void Init(HttpApplication context) { app = context; context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute); } void context_PreRequestHandlerExecute(object sender, EventArgs e) { var request = app.Context.Request; request.Filter = new CustomHttpFilter(request.Filter); } } public class CustomHttpFilter : Stream { private Stream outputStream; public CustomHttpFilter(Stream outputFilter) { outputStream = outputFilter; } public override int Read(byte[] buffer, int offset, int count) { // read and make the necessary changes } } 

我不相信可以使用http模块修改请求 ,但是可以修改响应HttpRequest对象大部分是只读的,因此它通常在任何上下文中都是不可变的,而不仅仅是来自模块。

如果你真的很绝望,你可以尝试使用reflection来访问更多的http请求对象。 但是,要访问,修改或调用非公共成员,您的进程将需要完全信任权限, 这在Web环境中非常危险

实际上,可以通过 IIS 7.0+中的HttpModule修改IIS中HttpRequest POST的内容 。 我有这个问题,并且能够解决它。 我发布以供将来参考,因为没有很多post详细说明何时/为什么它将起作用或不起作用。

这是一个故障排除清单:

  1. 确保您的模块和任何其他模块没有访问Request对象,以便在将filter添加到请求filter之前评估输入流。 例如,访问Request.Form["param"]将触发输入流的评估。 这种情况的一个症状是从未调用filterRead方法。

  2. 查看统一IIS管道中的事件顺序https://msdn.microsoft.com/en-us/library/bb470252.aspx 。 您将看到PreRequestHandlerExecute事件与第12个事件一样发生。 为了最好地设置请求filter并将其应用,您应该在BeginRequest事件中执行此操作,这是请求validation和url映射之后的第一个事件(在HttpModule中公开,在ISAPI扩展或filter中有其他公开) 。 ISAPIfilter和扩展确实有一些事件可能发生在HttpModule事件之前,但从那以后

  3. 考虑到Request.Filter是Streams链,它们会连续评估,将输出从一个传递到下一个输入,它们也可以在模块接收输入之前修改请求。 如果存在一些奇怪的行为,请考虑删除其他一些filter以隔离问题或更改它们的加载顺序。

  4. 还要考虑Streamfilter的读取和写入方法是以块的forms调用的,因此它们可以被多次调用,具有不同的偏移量,因此请确保您的重写逻辑正常运行,特别是如果您要替换导致不同总体请求或响应大小的内容见下文。

  5. 如果要在“读取”或“写入”中执行搜索/替换,则需要考虑数据可能跨越多个读/写。 在这种情况下,您可能需要考虑在MemoryStream中缓冲请求或响应流并对其进行操作。

如果您将问题隔离并简化为最基本的方案,您最终将确定导致其无法工作的原因。 这里的简单示例演示了https://msdn.microsoft.com/en-us/library/system.web.httprequest.filter.aspx,但它没有演示在缓冲流上运行。

我已经整理了一个示例,演示了缓冲请求和响应重写HttpModule以供参考。 https://github.com/snives/HttpModuleRewrite

通过覆盖WorkerRequest可以实现。 您可以获得如下的当前工作人员请求:

 (HttpWorkerRequest)context.GetService(typeof(HttpWorkerRequest)) 

您可以通过引用IIS7WorkerRequest.cs .net参考源来实现派生的工作者请求。

硬部分从输入流中读取所有字节并解析数据。 您应该知道HTTP Multipart-form数据规范。