【问题标题】:How do I override RequestValidation in ASP.NET WebAPI如何在 ASP.NET WebAPI 中覆盖 RequestValidation
【发布时间】:2012-03-30 16:35:50
【问题描述】:

我在处理包含“危险字符”作为 Web API URL 一部分的请求时遇到问题。 Url 包含一个 & ,该 & 已正确 Url 编码,但仍会导致请求验证 ASP.NET 错误。

与 MVC 不同,似乎没有 [ValidateInput(false)] 属性来强制和禁用此功能。

【问题讨论】:

    标签: asp.net-web-api request-validation


    【解决方案1】:

    原来答案是在 web.config 中使用:

    <system.web>
      <httpRuntime requestPathInvalidCharacters="" />  
    </system.web>
    

    您可以在全局或子目录级别进行设置。您可以利用&lt;location path=""&gt; 元素仅在某些路径下指定此设置。例如,如果受影响的 Web API 路由位于 api/images 下,您可以执行以下操作:

    <location path="api/images">
      <system.web>
        <httpRuntime requestPathInvalidCharacters="" />  
      </system.web>
    </location>
    

    更多信息:https://msdn.microsoft.com/en-us/library/e1f13641(v=vs.100).aspx

    【讨论】:

    • 这是唯一对我有用的解决方案。将 requestValidationMode='2.0' 添加到 web.config 并尝试操作方法上的 [ValidateInput(false)] 属性不起作用。我添加requestPathInvalidCharacters="" 后它开始工作。我认为这是因为这里的错误是 Request.Path 验证而不是 Request.Form 验证的一部分。
    • 不需要是全局的,只要使用location元素限制路径即可。因此,如果您的 Web API 路由在 api/foo 下,您可以将位置限制为 path="api/foo" 并在那里添加 httpRuntime 配置。确认这在 IIS 中工作正常。 MSDN 还明确指出 &lt;httpRuntime&gt; 可以“在机器、站点、应用程序和子目录级别声明”。我更新了答案。
    【解决方案2】:

    每个 @Levi 我们的网络安全人员:

    配置是执行此操作的唯一方法。即使是 MVC 的 [ValidateInput(false)] 对这种特殊情况也无济于事。

    Web.config 中禁用它并不是一个糟糕的主意。如果您通过验证和编码不受信任的数据来遵循良好的安全实践,那么在应用程序范围内应用它是非常好的。

    【讨论】:

    • [ValidateInput(false)] 在我的情况下不起作用。我认为这是因为[ValidateInput(false)] 指的是Request.Form 而不是Request.Path
    【解决方案3】:

    在配置中将 RequestValidation 设置为 4.0 时,答案是否定的。但是,您可以恢复到 2.0 请求验证,在这种情况下,MVC 属性可以按预期工作:默认验证并在需要时显式覆盖。

    <httpRuntime executionTimeout="300" requestValidationMode="2.0" />
    

    在这里详细讨论了这个和一些选项: http://www.west-wind.com/weblog/posts/2010/Aug/19/RequestValidation-Changes-in-ASPNET-40

    【讨论】:

      【解决方案4】:

      您可以通过将httpRuntime 元素的requestValidationType 属性设置为继承自System.Web.Util.RequestValidator 并覆盖IsValidRequestString 的自定义类型来对此进行更细粒度的控制。

      很遗憾,这不是 WebAPI 管道的一部分,因此无法直接检查动作过滤器(即控制器方法上的属性)等内容。

      但是,如果您特别关心表单字段的验证,则在您访问它们之前不会调用验证器,这发生在触发操作过滤器之后,因此您可以通过以下方式选择退出使用属性的验证创建如下类...

      public class AllowFormHtmlAttribute : ActionFilterAttribute
      {
          public override void OnActionExecuting(HttpActionContext actionContext)
          {
              HttpContext.Current.Items["AllowFormHtml"] = true;
          }
      }
      
      public class CustomRequestValidator : RequestValidator
      {
          protected override bool IsValidRequestString(HttpContext context, string value, RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex)
          {
              if (context.Items["AllowFormHtml"] as bool? == true && requestValidationSource == RequestValidationSource.Form)
              {
                  validationFailureIndex = 0;
                  return true;
              }
      
              return base.IsValidRequestString(
                  context, value, requestValidationSource, collectionKey, out validationFailureIndex);
          }
      }
      

      ...然后用[AllowFormHtml]注释你的控制器方法

      但是,如果您直接从 HttpRequest 访问表单字段,则使用 HttpRequest.Unvalidated 会更简单,它会绕过验证。

      【讨论】:

        猜你喜欢
        • 2012-04-01
        • 1970-01-01
        • 2017-11-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多