我正在使用HttpClient构建API使用者。因为提供者要求使用者使用摘要式身份验证进行身份验证,所以我需要编写一个自定义DelegatingHandler,如下所示:
public class DigestAuthDelegatingHandler : DelegatingHandler
{
public DigestAuthDelegatingHandler(HttpMessageHandler innerHandler) : base(innerHandler) { }
protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var response = await base.SendAsync(request, cancellationToken);
if (!response.IsSuccessStatusCode && response.StatusCode == HttpStatusCode.Unauthorized)//This line of code is never reached
{
//Generate the Digest Authorization header string and add to the request header,
//then try to resend the request to the API provider
}
return response;
}
}
我创建了一个HttpClient并将我的自定义DelegatingHandler添加到消息处理程序pineline
HttpClient httpClient = new HttpClient(new DigestAuthDelegatingHandler(new HttpClientHandler()));
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
httpClient.BaseAddress = new Uri("http://127.0.0.1/");
HttpResponseMessage response = httpClient.GetAsync("api/getTransactionInfo?TransactionNumber=1000).Result;
在这样做之后,看起来我的消费者永远都会跑。当我在代码行等待base.SendAsync之后添加一个断点时,我发现代码永远不会返回,所以我无法检查响应是否获得401未经授权的提取摘要授权标题详细信息。 API提供商没有错,因为我已经使用传统的WebHttpRequest支持Digest Authenticate成功构建了另一个API使用者网站,并且运行良好。
重要说明:如果我切换到将消费者作为控制台应用程序编写,那么它运行良好。所以,我不确定,但我认为在异步模式下运行时,它与ASP.NET线程有关吗?
我在做什么事吗?
答案 0 :(得分:1)
我同意Darrel - 最有可能的是,任务出现故障并且没有结果......您可以使用显式延续来检查任务状态 - 例如,
return base.SendAsync(request, cancellationToken).ContinueWith(task =>
{
// put the code to check the task state here...
});
另据说明,我不确定您是否需要创建自定义DelegatingHandler
进行身份验证...尝试使用HttpClientHandler
Credentials属性(或UseDefaultCredentials传递当前用户的默认凭据)
var httpClient = new HttpClient(new HttpClientHandler() {
PreAuthenticate = true,
Credentials = new NetworkCredentials(...
});
编辑:找到使用凭据缓存与http客户端一起使用摘要式身份验证的示例 - 请参阅此SO Q&amp;答:HttpRequestMessage and Digest Authentication
这应该解决你的实际问题w.r.t.摘要身份验证,无需构建自己的处理程序。
答案 1 :(得分:0)
我的猜测是.Result阻止了你的处理程序中的延续。尝试将.Result更改为.ContinueWith
答案 2 :(得分:0)
遇到同样的问题,这就是我最终的工作。问题是端点抛出了500内部服务器错误,因此阻止了线程。
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
return await base.SendAsync(request, cancellationToken)
.ContinueWith<HttpResponseMessage>(task =>
{
return task.Result;
});
}
请注意,anon函数内部的返回返回SendAsync函数,然后我们实际返回Result。