任何添加到 DefaultRequestHeaders 的 headers 都不会进入 API

Any added headers to DefaultRequestHeaders will not make it through to the API

在我的 API 项目中,我有以下控制器,在使用 Postman 调用时可以正常工作:

[HttpPost]
public async Task<ActionResult> Upload([FromHeader] string authorization, IFormFile payLoad) { ... }

当我使用 Postman 时,我在 Auth 部分添加了一个字符串 (Token),并将 Type 指定为 Bearer Token。然后我转到 Body 部分并将密钥 payLoad 设置为 File 并选择要上传的文件。

Postman生成C#-RestSharp代码如下:

var client = new RestClient("http://localhost:11764/api/logdata");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer exampleTokenString");
request.AddFile("payLoad", "/C:/path/oqwi.zip");
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);

我没有使用 RestSharp,所以我没有验证上面的代码是否有效 但是 Postman post 本身在工具中工作正常,我的 API 得到了我期望的所有数据。

在单独的客户端应用程序中,每当我尝试进行 POST 调用时,API 控制器(在本页顶部)总是收到 null authorization 参数。文件加载正常。这是客户端代码尝试 POST 到 API 我尝试添加 header 的每个示例(我没有一次尝试全部):

Uri EndPoint = new Uri("http://localhost:11764/api/logdata");
using (var client = new HttpClient())
{
    client.DefaultRequestHeaders.Authorization
        = new AuthenticationHeaderValue("Bearer", AccessToken);
    client.DefaultRequestHeaders.Add("Authorization", "Bearer " + AccessToken);

    var request = new HttpRequestMessage(HttpMethod.Post, EndPoint)
    {
        Content = fileAsFormData
    };

    request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken);
    request.Headers.Add("Authorization", "Bearer " + AccessToken);

    var response = await client.SendAsync(request);
    ...

注意:以上是我在添加授权和令牌时所做的各种不同尝试的示例;我没有一次完成以上所有操作。

我在运行时检查了客户端中的 object,看起来好像 header(s) 添加到了我期望的位置。使用 Fiddler,我可以确认这一点:


更新: 我尝试添加其他 headers,例如 CacheControl,其中 none 进入 API.我在运行时在客户端看到它,我在 Fiddler 中看到它,但是当它们到达 API 时它们都被清除了。我想知道这个 Github 讨论是否与此有关:

https://github.com/dotnet/runtime/issues/26475

根据 dotnet 运行时团队中的 Github ticket

karelz commented on Oct 24, 2018 • FYI: 2 weeks ago we released a security fix to remove Authorization request headers from redirects.

认为重定向可能是问题的核心,通过使用 Fiddler 或 Visual Studio 检查工具,我能够观察到对我的客户端的回调来自 https://localhost:5001。我没想到会这样...

当我将 POST 的原始客户端代码构建到我的 API 时,我只是简单地复制了我在从 Postman 执行这些调用时使用的所有值。以 Postman 的 C# RestSharp 为例:

var client = new RestClient("http://localhost:11764/api/logdata");

这最终是由 Postman 处理重定向的智能方式引起的转移注意力。 Postman 确实在向 http://localhost:11764 发帖——但随后获得安全重定向到 https://localhost:5001。然后邮递员会巧妙地重新发送原始请求并重新附加 headers 到这个新的安全端点。

因此,在将客户端 POST 的端点从 http://localhost:11764/api/logdata 更新到 https://localhost:5001/api/logdata 之后,一切都按预期进行。

但为什么 https://localhost:5001?它在(大多数)launchSettings.json:

中是这样设置的
"MyProj.UploadApi.WebApi": {
  "commandName": "Project",
  "launchBrowser": false,
  "environmentVariables": {
    "ASPNETCORE_ENVIRONMENT": "Development"
  },
  "applicationUrl": "https://localhost:5001;http://localhost:11764"
}