服务端能否获取HttpClientHandler.Credentials?该配置为何无Authorization头?
你给出的客户端配置代码如下:
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), }; });
问题解答
1. 该方式设置凭证的实际作用
给HttpClientHandler.Credentials赋值的本质是让HttpClient遵循标准HTTP质询-响应认证流程,支持Basic、Digest、NTLM、Kerberos等多种HTTP认证方案。它不会主动在首次请求就携带认证信息,只会在收到服务端返回的401 Unauthorized响应,且响应头包含WWW-Authenticate字段明确指定了支持的认证方案时,才会自动把凭证按照对应方案的规则生成认证信息,重新发起请求。
这就是你首次请求看不到Authorization头的原因:客户端还没收到服务端的认证质询,不会主动发送凭证。
2. 凭证的存放位置
当触发认证流程后,凭证会根据你使用的认证方案生成对应格式的内容,放到请求的Authorization头中:
- 如果是Basic认证:会将
用户名:密码的字符串做Base64编码,头的值为Basic 编码后的字符串,和手动拼接添加该头的效果完全一致 - 如果是NTLM/Kerberos等Windows集成认证:会按照对应协商协议生成认证令牌放到该头中
3. 自行实现服务端兼容逻辑的方案
完全可以兼容,只需要服务端按照HTTP标准实现认证流程即可,不需要修改现有客户端配置:
- 服务端接收到请求后先校验是否存在合法的
Authorization头 - 如果不存在或者校验不通过,返回
401 Unauthorized状态码,同时在响应头中添加WWW-Authenticate: Basic realm="你的服务标识"(realm可自定义,一般填服务名称即可) - 客户端收到该响应后会自动用你配置的凭证生成正确的Authorization头,重新发起请求,服务端正常校验该头的内容即可
如果想要避免首次请求401的额外往返,也可以直接修改客户端配置,主动给HttpClient添加默认Authorization头,不需要依赖Credentials的质询响应流程:
services.AddHttpClient<TrackAndTraceClient>() .ConfigureHttpClient(httpClient => { httpClient.BaseAddress = new Uri(settings.BaseUrl); httpClient.Timeout = TimeSpan.FromMinutes(5); // 主动添加Basic Auth头 var authBytes = Encoding.ASCII.GetBytes($"{settings.Username}:{settings.Password}"); httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(authBytes)); });
内容的提问来源于stack exchange,提问作者Jonathan Wood
相关产品推荐
相关产品推荐

