Cloudflare 502问题排查:ASP.NET受保护内容重定向后连接重置
排查Cloudflare+IIS 10+ASP.NET/Sitefinity+自定义SSO重定向流程中的502 Bad Gateway问题
问题背景
未认证用户请求会员专属文档/页面等受保护内容时,预期流程为:
- 用户请求受保护内容
- ASP.NET/Sitefinity检测到用户未认证
- 服务器返回
302 Found重定向至SSO登录页 - 登录页接收指向原受保护URL的
redir参数 - 登录后用户返回原内容
实际用户收到Cloudflare 502 Bad Gateway错误,源服务器虽生成302重定向,但响应完成前连接被重置。
请求测试结果
通过Cloudflare的GET请求
curl.exe -vk --output NUL -H "Accept: text/html" "https://www.example.com/docs/default-source/members-only/example-document.pdf?sfvrsn=12345"
响应结果:
HTTP/1.1 502 Bad Gateway Server: cloudflare Content-Type: text/html Content-Length: 155
绕过Cloudflare直接访问源IP的GET请求
curl.exe -vk --resolve www.example.com:443:ORIGIN_IP --output NUL -H "Accept: text/html" "https://www.example.com/docs/default-source/members-only/example-document.pdf?sfvrsn=12345"
响应结果:
HTTP/1.1 302 Found Cache-Control: private Transfer-Encoding: chunked Content-Type: text/html; charset=utf-8 Location: https://sso.example.com/login?sso=www&redir=https%3a%2f%2fwww.example.com%2fdocs%2fdefault-source%2fmembers-only%2fexample-document.pdf Server: Microsoft-IIS/10.0 X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET { [response body data] } Recv failure: Connection was reset curl: (56) Recv failure: Connection was reset
通过Cloudflare的HEAD请求
curl.exe -vkI -H "Accept: text/html" "https://www.example.com/docs/default-source/members-only/example-document.pdf?sfvrsn=12345"
响应结果:
HTTP/1.1 302 Found Location: https://sso.example.com/login?sso=www&redir=... Server: cloudflare Connection: keep-alive
请求模式总结
HEAD请求通过Cloudflare → 正常返回302重定向 GET请求通过Cloudflare → 502 Bad Gateway GET请求直接访问源服务器 → 返回302 Found后连接重置 GET请求带Accept: */* → 有时Cloudflare返回302,但curl提示传输不完整 GET请求带Accept: text/html → Cloudflare返回502
浏览器默认发送的Accept头示例:
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8
因此真实浏览器访问通常触发502错误。
SSO代码修改情况
原SSO DLL代码:
HttpContext.Current.Response.Redirect(redirectUrl);
修改后代码:
HttpContext.Current.Response.Redirect(redirectUrl, false); HttpContext.Current.ApplicationInstance.CompleteRequest();
后续补丁添加:
HttpContext.Current.Response.Flush();
但生产环境仍存在问题:返回302 Found后连接重置。
环境差异
测试环境(Staging)
相同请求返回带Content-Length的完整302响应,连接保持正常:
HTTP/1.1 302 Found Content-Length: 364 Location: https://sso-staging.example.com/login?sso=...&redir=... Connection remains intact
生产环境
返回Transfer-Encoding: chunked后连接重置:
HTTP/1.1 302 Found Transfer-Encoding: chunked Location: https://sso.example.com/login?sso=...&redir=... Recv failure: Connection was reset curl: (56) Recv failure: Connection was reset
已知差异:测试环境流量不经过Cloudflare,生产环境则经过。
已完成的测试
- 在Cloudflare中禁用HTTP/2至源服务器
- 临时在Cloudflare中禁用客户端HTTP/2
- 测试SSL模式变更
- 为受保护文档路径添加临时Cloudflare配置规则
- 禁用该路径的常见Cloudflare功能
- 测试
Response Body Buffering - 测试带
Accept-Encoding: identity的请求 - 测试带
Accept: */*的请求 - 测试带
Accept: text/html的请求 - 使用
curl --resolve直接测试源IP - 对比
GET与HEAD请求
当前推测
Cloudflare并非根因,仅将源服务器的不完整/重置响应转换为502错误。根因是IIS/ASP.NET/Sitefinity/自定义SSO逻辑在发送重定向响应体后,未正常关闭302 GET响应。
技术疑问
- 在经典ASP.NET/IIS中,哪些因素会导致发送
302响应后TCP连接被重置? Response.Redirect(url, false)搭配CompleteRequest()是否足够?是否存在其他响应结束方式仍会引发该问题?Response.Flush()与重定向结合是否会加剧问题?- 为何测试环境返回
Content-Length并正常关闭连接,而生产环境返回Transfer-Encoding: chunked后重置连接? - IIS设置、ASP.NET模块、压缩设置、URL授权模块或自定义HTTP模块是否可能导致重定向后连接重置?
- 哪些日志有助于确认连接重置是由ASP.NET、IIS、模块还是IIS与Cloudflare之间的因素导致?
重点关注如何调试源服务器端返回302后的连接重置问题(绕过Cloudflare仍可复现)。
内容的提问来源于stack exchange,提问作者hnnnng
相关产品推荐
相关产品推荐

