.NET 7.0:HttpClient在执行301重定向时不发送DefaultRequestHeaders

hm2xizp9  于 2023-03-24  发布在  .NET
关注(0)|答案(2)|浏览(122)

我很困惑为什么HttpClient示例在301重定向后不发送DefaultRequestHeaders(特别是Authorization头)。考虑到集合的名称(即DefaultRequestHeaders),我希望总是发送这些。这是一个bug还是一个预期的行为?
为了给我所面临的失败提供更多的背景,我尝试调用Microsoft Graph getOffice365GroupsActivityDetail API,从昨天开始,此API使用301 http响应代码强制重定向到位置https://reportsweu.office.com/graph/v1.0/data/[tenant-id]/Microsoft.O365Reporting.getOffice365GroupsActivityDetail,意外的是似乎需要不同的令牌,因为使用对调用原始API有效的承载令牌进行调用(即https://graph.microsoft.com/v1.0/reports/getOffice365GroupsActivityDetail)失败,并显示“S2S auth failed”错误。

kqqjbcuj

kqqjbcuj1#

我刚刚发现,这种行为是通过设计实现的,正如HttpClientHandler.AllowAutoRedirect Property的文档所述:
Authorization头在自动重定向时被清除,处理程序自动尝试重新验证到重定向的位置。没有其他头被清除。实际上,这意味着如果可能遇到重定向,应用程序不能将自定义身份验证信息放入Authorization头。相反,应用程序必须实现并注册自定义身份验证模块。
对我来说,这种行为并不直观,因为在301重定向之后,HttpClient仍然显示DefaultRequestHeaders集合中存在的标头,但在重定向之后不会发送。将此标头添加到HttpRequestMessage对象的Headers集合中可能比添加到HttpClient对象的DefaultRequestHeaders集合中更好,因为这样可以更好地控制添加它或者不指向跟随重定向所需的新HttpRequestMessage对象。

3qpi33ja

3qpi33ja2#

这根本不是bug。它实际上是一种防止身份验证泄漏的常见安全措施。就像其他工具一样,如果你想保留头部,你必须显式地这样做。
此措施用于防止凭据泄漏。如果没有此措施,被黑客攻击的站点可能会将您重定向到恶意的第三方站点,在Authorization标头中记录凭据,然后将您重定向回最终站点。
.NET Framework也是这样工作的。有一个bug in .NET Core 2.0(* 默认情况下在HttpClientHandler重定向中不剥离Auth *)没有重置Authorization标头,但在2.1中已修复
其他工具也是以同样的方式工作的,包括curl。例如,在CVE-2018-1000007中,它们准确地描述了以下场景:
当要求curl在HTTP请求中发送自定义头时,curl会首先将这组头发送到初始URL中的主机,但如果要求遵循重定向并返回30X HTTP响应代码,则会将其发送到Location:响应标头值。
向后续主机发送同一组标头对于传递自定义Authorization的应用程序来说尤其是一个问题:头部,因为该头部通常包含隐私敏感信息或数据,这些信息或数据可能允许其他人模仿使用curl的客户端的请求。
解决方案是重置header,除非用户明确地强制工具重用它:
自定义授权:header将以与curl中控制其他此类header相同的方式受到限制:它们将只被发送到原始URL中使用的主机,除非curl被告知可以使用CURLOPT_UNRESTRICTED_AUTH选项传递给其他主机。

相关问题