headers 中未显示 NetWorkCredentials

NetWorkCredentials not showing up in headers

我有两个项目:Web API 项目和客户端项目。

在客户端应用程序中,我这样配置 HttpClient

services.AddHttpClient<TrackAndTraceClient>()
    .ConfigureHttpClient(httpClient =>
    {
        httpClient.BaseAddress = new Uri(settings.BaseUrl);
        httpClient.Timeout = TimeSpan.FromMinutes(5);
    })
    .ConfigurePrimaryHttpMessageHandler(serviceProvider =>
    {
        return new HttpClientHandler()
        {
            Credentials = new NetworkCredential(settings.Username, settings.Password),
        };
    });

然后在我的 class 中调用 API:

public TrackAndTraceClient(IHttpClientFactory httpClientFactory, IOptions<TrackAndTraceSettings> settings)
{
    HttpClient = httpClientFactory.CreateClient(nameof(TrackAndTraceClient));
    Settings = settings.Value;
}

我的网站 API 站点使用 this article 中描述的技术实现基本身份验证。但是我的代码抛出异常,因为没有找到 Authorization header。

public class BasicAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions>
{
    protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
    {

        // ...

        if (!Request.Headers.TryGetValue("Authorization", out StringValues authHeaderValues))
            throw new Exception("Missing Authorization header");

        // ...
    }
}

我只能通过将以下代码添加到我的 class 来调用 API:

HttpClient.DefaultRequestHeaders.Add("ContentType", "application/json");
byte[] credentialsData = Encoding.UTF8.GetBytes($"{Settings.Username}:{Settings.Password}");
string credentials = Convert.ToBase64String(credentialsData);
HttpClient.DefaultRequestHeaders.Add("Authorization", $"Basic {credentials}");

谁能告诉我为什么需要这最后一段代码?为什么使用 NetworkCredential 设置凭据似乎没有任何作用?我如何更改我的 Web API 以便它使用原始方式指定的凭据?

请注意,我还调用了 third-party API,并且客户端的配置方式与我的第一个代码块中的配置方式完全相同。所以我知道这可以工作。

来自我们在评论区的对话-

您的 BasicAuthenticationHandler 的实现缺少添加 WWW-Authenticate HTTP header(值为 Basic)。

这就是 header,HttpClient 在接收到 401 [时反应为包含 Authorization HTTP header =20=]响应。

要解决此问题,请将以下行添加到 BasicAuthenticationHandler

Response.Headers.Add("WWW-Authenticate", "Basic");

现在 NetworkCredentials 将进入 Authorization HTTP header.


简而言之,关于它的工作原理还不完整;
HttpClient 发出请求(没有 Authorization header),并收到 401 Unauthorized 响应与 WWW-Authenticate HTTP header,它将使用配置的凭据进行第二次尝试 - 如果有的话 - 在 Authorization HTTP header.


为简单起见,您可能希望立即包含 Authorization,而不依赖于 NetworkCredentialsWWW-Authenticate HTTP header。

services.AddHttpClient<TrackAndTraceClient>()
    .ConfigureHttpClient(httpClient =>
    {
        httpClient.BaseAddress = new Uri(settings.BaseUrl);
        httpClient.Timeout = TimeSpan.FromMinutes(5);

        // Add below to your existing code.
        var digest = Convert.ToBase64String(
            Encoding.UTF8.GetBytes($"{settings.Username}:{settings.Password}")
            );  
        httpClient.DefaultRequestHeaders.Add("Authorization", $"Basic {digest}");
        HttpClient.DefaultRequestHeaders.Add("ContentType", "application/json");        
    });