【问题标题】:C# HttpClient authorization header removed after send to server发送到服务器后删除 C# HttpClient 授权标头
【发布时间】:2021-07-13 18:26:08
【问题描述】:

我想通过 HttpClient 从我自己的 C# API 向外部 API 发送请求。 我正在使用 dot net 5 和基本身份验证。 这是我的代码:

var client = new HttpClient 
{
    BaseAddress = new Uri(baseUrl)
};

HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Put, "apiUrl");

client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

var param = JsonConvert.SerializeObject(new
{
   param1="",
   param2=""
});

requestMessage.Content = new StringContent(param, Encoding.UTF8, "application/json");
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Basic",
     Convert.ToBase64String(Encoding.ASCII.GetBytes($"{user}:{pass}")));

HttpResponseMessage response = await client.SendAsync(requestMessage);

通常,我会这样发送 http 请求。 但现在我遇到了一些问题。

在从我的请求标头中删除行 HttpResponseMessage response = await client.SendAsync(requestMessage); 授权标头之后,我得到了 UnAuthorized http 错误。

我知道当重定向发生时,出于安全原因,授权标头被删除。我也不确定外部 API 中的重定向。

我将HttpClientHandlerAllowAutoRedirect = false 添加到我的HttpClient

var handler = new HttpClientHandler()
{
    AllowAutoRedirect = false,
};
var client = new HttpClient (handler)
{
    BaseAddress = new Uri(baseUrl)
};

现在我收到重定向错误 301(永久移动)。

我决定在 Postman 中测试代码。默认情况下,当我在 Postman 中调用 API 时,出现 http 错误 405 method not allowed 和错误详情如下:

{ "detail": "不允许使用方法 "GET"。"}

外部 API 方法是 PUT。但在这里我得到了GET 错误。 我在邮递员中尝试了很多选项,最后我在邮递员中找到了选项:

当我打开它时,外部 API 工作正常。 我还用Insomnia 对其进行了测试,它工作正常。

它是否与我的代码或 dot net 5 或我的代码中的其他内容或与外部 API 相关?

如果它与我的代码有关,我该如何解决?

如果错误与外部 API 有关,为什么 Postman 和 Insomnia 响应正常?

外部 API 具有特定域的核心策略,我从其他域发送请求。 我所知道的是浏览器中应用了 CORS 策略。不在 Postman、Insomnia 或 C# 代码中。 CORS 呢?它与CORS 有关吗?如果是,我该怎么办?

我会很感激你的回答。

更新

我在响应标头中检测到 WWW-Authenticate: JWT realm="api"。 它到底是什么?我该怎么办?

【问题讨论】:

  • 你试过把client.SendAsync(requestMessage);改成client.PutAsync(requestMessage);吗?
  • 是的,一开始我用的是client.PutAsync(requestMessage);

标签: c# httpclient basic-authentication unauthorized www-authenticate


【解决方案1】:

您在重定向后删除授权标头是正确的。但请记住,此行为是 C# 中 HttpClient 设计的一部分。 Postman 和 Insomnia 可能有不同的机制来发送由重定向引起的每个连续请求的授权标头。您在Postman 中启用的选项将使它使用您指定的原始 HTTP 方法 (PUT) 作为 HTTP 方法,以根据重定向消息发送进一步的请求(邮递员默认使用 GET 方法在由重定向消息)。

您看到 301 的事实表明需要重定向。您可以检查response.Headers 中的Location 标头值以查看真实位置并将带有授权标头的请求直接发送到该端点。如果我是你,我不会直接使用新位置,因为原始端点是 API 的作者给你的。相反,我会以编程方式将请求发送到原始端点,然后将 301 代码上的请求重新发送到新的 Location(由于 Postman 的行为,使用 PUT 方法),直到获得结果。这个答案可以给你一些想法:https://stackoverflow.com/a/42566541/1539231

【讨论】:

  • 你是对的,但位置没有改变,并且 response.location 与我发送请求的初始 URL 相同。
  • 我还与 API 提供商谈过,他们说目标 API 中没有重定向。重定向错误还有其他原因吗?
  • @AliasgharAhmadpour 我认为您可以通过查看 Postman 中的控制台日志来验证是否发生任何重定向。 Postman 的左下角应该有一个按钮可以打开控制台。发送有效的请求并检查控制台以查看正在发送的请求数。
  • 谢谢@pharaz-fadaei 这是一个很好的线索。每次我在邮递员中发送请求时,都会执行两个请求。第一个请求得到 301 错误,另一个请求成功执行。第一个和第二个之间的主要区别是在第二个请求标头中添加了引用者和主机是问题吗?我的意思是问题与推荐人有关吗?
  • 亲爱的@pharaz-fadaei,赏金属于你。你的好线索解决了我的问题
【解决方案2】:

我发现了问题。这真的很荒谬。 当我使用www.abc.com/api/something 之类的 URL 时,请求会出现 301 错误,并且邮递员会发送另一个请求,例如www.abc.com/api/something/。区别只是请求结束时的/。 我在邮递员中尝试了新的 URL,第一个请求没问题。 我还在我的 C# 代码中尝试了 URL,但它又没问题。 但我不明白为什么。

非常感谢亲爱的@pharaz-fadaei

【讨论】:

    【解决方案3】:

    由于您看到 WWW-Authenticate: JWT realm="api" 标头,因此外部 API 需要 JWT 令牌身份验证,而不是基本身份验证。我认为首先您可能需要检查外部 api 的文档。

    【讨论】:

    • 那么为什么邮递员或失眠症会得到基本身份验证的响应? C# API 调用和邮递员有什么区别?
    猜你喜欢
    • 1970-01-01
    • 2018-02-04
    • 2012-10-27
    • 2015-03-26
    • 1970-01-01
    • 2019-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多