首页 > 解决方案 > 发送到服务器后删除 C# HttpClient 授权标头

问题描述

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 中的重定向。

我将HttpClientHandlerwith添加AllowAutoRedirect = false到我的HttpClient

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

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

我决定在 Postman 中测试代码。默认情况下,当我在 Postman 中调用 API 时,我得到 http 错误 405 方法不允许,错误详情如下:

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

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

当我打开它时,外部 API 工作正常。我也对其进行了测试,Insomnia并且可以正常工作。

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

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

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

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

我将不胜感激您的回答。

更新

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

标签: c#httpclientbasic-authenticationunauthorizedwww-authenticate

解决方案


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

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


推荐阅读