Azure Function中C# HttpClient发带认证POST到第三方API时头与Body丢失问题
我已成功发出可正常处理的请求。第三方API要求我们将本质为Guid的Token作为Bearer Token发送,Azure似乎会对该Token执行某种预校验,当我将GUID替换为真正随机生成的Bearer Token后,请求可正常执行。我仍想了解是否有方法可以禁用Azure的这项校验,因为“不符合要求”的Bearer Token在GET请求中可正常使用,但POST/PUT请求会失败。
应用概述
我们的业务使用Azure Function(包括时间触发器、编排器、活动函数)扫描SQL中的本地队列表项,将对应数据以JSON格式POST到第三方API,该第三方API要求POST请求携带Authorization头。
技术概览
- dotnet core 3.1
- azure function runtime ~3
附加信息
- 该代码库今年4-5月用户验收测试(UAT)阶段运行正常,之后项目停滞,直到两周前重启
- 出站请求不经过APIM代理,直接发送到第三方API
- Azure Function已配置Application Insights
正常运行场景
所有GET请求均无异常。
故障场景
POST请求存在异常。我通过beeceptor代理请求查看实际接收内容:当请求携带Authorization头时,大部分请求头(如Content-Type、Content-Length)会被剥离,且请求体为空。如果移除Authorization头,所有请求头和请求体均可正常接收。
问题咨询
我目前推测是某个Azure服务、预检查机制或安全策略拦截了Authorization头,误认为该头是发给Azure自身的,但我无法定位具体是哪项配置导致该问题,已多日检索资料无果,希望得到对应的解决方案。
简化版代码
using var client = new HttpClient(); client.DefaultRequestHeaders.Clear(); // Request params are dynamic and a helper method builds the full request path var path = PathBuilder(queueItem.RequestParams, queueItem.Request.UrlPath); // This can change in code not shown if the request is sending files var contentType = "application/json"; client.BaseAddress = new Uri(queueItem.Request.Client.BaseApiUrl); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); client.DefaultRequestHeaders.CacheControl = new CacheControlHeaderValue { NoCache = true }; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", queueItem.Request.Client.AuthToken); // queueItem.Data is JSON HttpContent json = new StringContent(queueItem.Data, Encoding.UTF8, contentType); return await client.PostAsync(path, json);
补充说明
- 我已确认JSON请求体合法
- 代码未做修改,此前可正常运行
1. 禁用Azure Function内置身份验证校验
该问题是Azure App Service内置身份验证(Easy Auth)模块的默认行为导致:该模块会默认拦截所有携带Authorization头的请求,对Bearer Token执行JWT格式校验,非JWT格式的Token(如你使用的GUID)会触发请求头、请求体裁剪逻辑,POST/PUT这类带请求体的请求受影响更明显。
处理步骤:
- 进入Azure门户,找到对应的Function App,依次进入「设置」-「身份验证」页面
- 如果你不需要使用Azure内置的身份验证能力,直接删除所有身份验证配置,保存后重启应用即可生效
- 如果你必须保留Easy Auth功能,进入「配置」-「应用程序设置」页面,新增配置项
WEBSITE_AUTH_DISABLE_IDENTITY_FLOW = true,保存重启后,Easy Auth就不会再处理请求中的Authorization头
2. 调整HttpClient请求逻辑
避免将Authorization头添加到HttpClient的全局默认头中,改为单次请求单独添加,避免Runtime其他逻辑读取修改该头:
// 替换原有PostAsync调用逻辑 var request = new HttpRequestMessage(HttpMethod.Post, path); request.Content = json; request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", queueItem.Request.Client.AuthToken); return await client.SendAsync(request);
3. 排查其他安全策略
如果以上配置修改后问题仍然存在,检查两个配置项:
- 查看Function App「网络」配置中是否开启了WAF(Web应用防火墙),如果已开启,临时关闭WAF测试,确认是否是WAF规则拦截裁剪了请求
- 检查应用程序设置中是否存在
WEBSITE_LOAD_CERTIFICATES这类和证书、身份校验相关的配置,部分证书绑定场景也会触发额外的请求头校验逻辑
内容的提问来源于stack exchange,提问作者Drew Gierach

