首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NetWorkCredentials未出现在标头中

NetWorkCredentials未出现在标头中
EN

Stack Overflow用户
提问于 2021-12-02 20:24:59
回答 1查看 287关注 0票数 1

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

在客户端应用程序中,我的HttpClient配置如下。

代码语言:javascript
复制
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),
        };
    });

然后在我的类中调用API:

代码语言:javascript
复制
public TrackAndTraceClient(IHttpClientFactory httpClientFactory, IOptions<TrackAndTraceSettings> settings)
{
    HttpClient = httpClientFactory.CreateClient(nameof(TrackAndTraceClient));
    Settings = settings.Value;
}

我的Web站点使用这篇文章中描述的技术实现了基本身份验证。但是我的代码抛出一个异常,因为没有找到授权头。

代码语言:javascript
复制
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");

        // ...
    }
}

我只能通过将以下代码添加到调用API的类中才能使其工作:

代码语言:javascript
复制
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,客户端的配置方式与我的第一个代码块完全相同。所以我知道这是可行的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-05 20:19:51

从我们在评论部分的谈话来看-

BasicAuthenticationHandler的实现缺少添加WWW-Authenticate HTTP头(带有值Basic)。

这是当HttpClient接收到401 Unauthorized响应时,它会对其作出反应以包含401Unauthorized头的报头。

若要解决此问题,请将下面的行添加到BasicAuthenticationHandler中。

代码语言:javascript
复制
Response.Headers.Add("WWW-Authenticate", "Basic");

现在,NetworkCredentials将进入Authorization HTTP头。

简而言之,没有完整地说明这是如何工作的;

HttpClient发出请求(没有Authorization头),并结合WWW-Authenticate HTTP报头接收401 Unauthorized响应时,它将第二次尝试在Authorization HTTP报头中配置凭证(如果有的话)。

为了简单起见,您可能希望同时包含Authorization,而不依赖于NetworkCredentialsWWW-Authenticate HTTP头。

代码语言:javascript
复制
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");        
    });
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70206032

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档