FireFox+IIS+HTTPS+Windows认证下ASP.NET Core POST 1MB报400错误求解
问题根因定位
这个报错和应用层的POST请求体限制无关,完全是Windows内核层http.sys驱动的校验逻辑触发的:
- 响应头标识为
Microsoft-HTTPAPI/2.0即可证明,请求根本没走到IIS应用池、也没有进入ASP.NET Core应用代码,全程由内核态的http.sys完成校验拦截,和IIS本身的上层配置没有直接关系。 - Firefox 84版本之后修改了NTLM身份验证的流处理逻辑:当POST请求体积接近1MB阈值时,会把Windows认证的协商分片内容直接拼在POST请求流的最前面发送,而非传统实现里把认证头放在单独的请求报文头区域。
- http.sys收到连续的TCP流后,会从流的起始位置开始解析HTTP请求行,即读取第一个换行符之前的内容作为请求方法、访问路径、协议版本。当Firefox把二进制格式的NTLM分片塞在流最前面时,http.sys根本解析不出合法的POST请求动词,就会返回通用的400错误;如果是HTTP明文通道下触发同样的流拼接问题,http.sys就会匹配另一个硬编码的错误模板,返回“请求头长度过长”的提示——两种报错本质是同一个触发源,只是匹配的文案不同,和实际错误原因没有对应关系。
- 测试的边界值完全符合http.sys的默认阈值逻辑:默认情况下http.sys要求所有请求头的总长度不能超过8KB,当提交的Value字段从1048569字节涨到1048570字节时,嵌在请求流最前面的NTLM分片累积长度刚好顶破8KB的上限,立刻触发拦截;旧版Firefox、Chrome、IE因为没有把认证分片塞在请求流开头的实现,永远不会触发这个阈值,所以功能正常;匿名认证场景不需要携带NTLM分片,自然也不会出现问题。
具体解除限制的操作步骤
需要按从内核到应用层的顺序依次调整,否则上层配置会因为请求根本没走到对应层级而失效:
- 调整http.sys全局请求头长度阈值
以管理员身份打开命令提示符,执行命令:netsh http set serverparameter maxrequestheaderslength=16384
该操作会把默认8KB的请求头总长度上限提升到16KB,足够覆盖大体积POST场景下的NTLM分片长度,调整完成后需要重启W3SVC服务生效。 - 调整IIS站点的请求体大小限制
在站点根目录的web.config文件中,找到system.webServer/security/requestFiltering节点,增加或修改maxAllowedContentLength配置,单位为字节,比如设置为10485760就代表允许最大10MB的POST请求体积。 - 调整ASP.NET Core应用的请求体大小限制
在Startup.cs的服务配置环节,添加全局请求体上限配置:
services.AddControllersWithViews(options => { // 按实际业务需求调整上限,单位为字节 options.MaxRequestBodySize = 10 * 1024 * 1024; });
- 配置完成后重启对应的站点应用池,再使用Firefox 84+复现之前的1MB边界值测试,即可正常完成请求提交。
注意:不要只调整IIS或应用层的请求体大小限制,否则会因为请求被内核层拦截,所有配置都会失效,必须先调整http.sys的全局阈值才能解决核心拦截问题。
内容的提问来源于stack exchange,提问作者usausa
相关产品推荐
相关产品推荐

