【问题标题】:Is it possible to remove some post data with an HttpModule?是否可以使用 HttpModule 删除一些帖子数据?
【发布时间】:2009-06-24 17:00:14
【问题描述】:

我正在将一个旧的经典 asp 网站转换为 asp.net。

该应用程序基本上是针对给定用户集的工具集的扩展,但它由外部供应商托管。

为了执行到这个应用程序的无缝传输,它会发布一些 xml 数据,这些数据会触发“潜在危险的 Request.Form 值”。我知道我可以关闭 validateRequest 标志,但我不想这样做。

我已经编写了一个 httpmodule,它获取这些数据并使用它来验证用户,是否可以使用相同的模块或不同的模块来删除之前发布数据中的这些“坏”值数据已“验证”?

否则,如果这些想法都不起作用,我愿意接受其他建议。

【问题讨论】:

    标签: asp.net asp-classic


    【解决方案1】:

    是的。以下类实现 IHttpModule 接口并注册和事件,这些事件将在 HttpRequestValidationException 检查发生之前触发。它检查请求是 POST 并且“testinput”不为空,然后对其进行 HTML 编码。该类需要在您的 Web.config 中注册为 httpModule。

    类...

    using System;
    using System.Collections.Specialized;
    using System.Reflection;
    using System.Web;
    
    public class PrevalidationSanitizer : System.Web.IHttpModule
    {
        private HttpApplication httpApp;
    
        public void Init(HttpApplication httpApp)
        {
            this.httpApp = httpApp;
            httpApp.PreRequestHandlerExecute += new System.EventHandler(PreRequestHandlerExecute_Event);
        }
    
        public void Dispose() { }
    
        public void PreRequestHandlerExecute_Event(object sender, System.EventArgs args)
        {
            NameValueCollection form = httpApp.Request.Form;
    
            Type type = form.GetType();
    
            PropertyInfo prop = type.GetProperty("IsReadOnly", BindingFlags.Instance 
                | BindingFlags.IgnoreCase | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy);
    
            prop.SetValue(form, false, null);
    
            if (httpApp.Request.RequestType == "POST" != null 
                && httpApp.Request.Form["testinput"])
                    httpApp.Request.Form.Set("testinput"
                        , httpApp.Server.HtmlEncode(httpApp.Request.Form["testinput"]));
        }
    }
    

    web.config 条目...

    <system.web>
      <httpModules>
        <add type="PrevalidationSanitizer" name="PrevalidationSanitizer" />
    ...
    

    【讨论】:

    • 啊,真聪明!我不知道您可以使表单对象像那样可写。我猜 Dave 问题的解决方案是解析安全凭证并使用 Form.Remove() 从 Form 集合对象中删除它们
    • 太好了,将此标记为答案,但是我自己没有测试过
    • 我对此进行了测试,它就像一个魅力但是我以前从未像这样修改过只读对象,所以我不确定这样做的后果但是我怀疑这些集合请求中的内容本质上是只读的,而不是因为它们需要是只读的。
    • 表单/请求参数是否存在于内存中的其他任何地方?还是 Form 集合是它们的唯一来源?
    • @JohnBubriski - 是的,Request.Params 属性返回一个 NameValueCollection,它是 QueryString、Form、Cookie 和 ServerVariables HttpValueCollections 的合并。它是惰性的,因此在第一次访问该属性时创建组合集合。原始 HTTP POST 数据也以原始格式存在,因此可以重新解析它以生成原始集合。
    【解决方案2】:

    我很想排除通过 HTML 表单将 XML 数据放置在字段帖子中的糟糕模式。我了解您希望“无缝”移植,我认为这意味着您希望能够在一段时间内同时维护 ASP 和 ASPX 页面。但是在这种情况下,您应该考虑同时更改表单和表单的操作目标。

    我猜这类似于我给here 的建议。只有在这种情况下,情况才更糟,即使在经典 ASP 的限制范围内,原始 ASP 中的代码模式也达不到理想状态。

    如果您不想同时完全移植 ASP 表单及其操作页面,请考虑修改 ASP 页面以使用 XHR 将 XML 发布到 ashx,该 ashx 将 XML 放置在安全的地方并返回 GUID。将返回的 GUID 放置在隐藏字段中,而不是最初保存 XML 的字段中。在接收 ASPX 页面中,使用 GUID 检索以前发布的 XML。

    【讨论】:

    • 发布我无法控制的数据的应用程序。不过,我确实计划将整个供应商应用程序从 asp 转换为 aspx。我正在等待对此的回复,并希望我可以更改表单操作,但我不确定该部门的灵活性究竟有多大。
    【解决方案3】:

    听起来很麻烦。使用validateRequest 标记页面级别有什么不好?

    只要确保正确清理输入并对其进行编码(如果您需要将其存储在任何地方)和/或确保在未编码的情况下不会将字段吐回浏览器。

    【讨论】:

    • 因为客户端可以将这些凭据发布到任何页面,我需要关闭每个页面的验证请求
    • 我打算在输入流上建议一个过滤器,但它有自己的一组令人头疼的问题要处理。 CptSkippy 有一个很好的解决方案!
    猜你喜欢
    • 2010-09-26
    • 1970-01-01
    • 2012-08-23
    • 2010-09-12
    • 1970-01-01
    • 2013-09-07
    • 1970-01-01
    • 2011-11-27
    • 1970-01-01
    相关资源
    最近更新 更多