4

我正在使用 HttpClient 构建 API 使用者。因为提供者要求消费者使用 Digest Authentication 进行身份验证,所以我需要编写一个自定义 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;   

这样做之后,我的消费者看起来就像永远运行。当我在上面的代码行 await base.SendAsync 之后添加断点时,我看到代码永远不会返回,因此我无法检查响应是否获得 401 未授权以提取摘要授权标头详细信息。API 提供者没有任何问题,因为我已经使用传统的 WebHttpRequest 支持 Digest Authenticate 成功构建了另一个 API 消费者站点,并且它运行良好。

重要提示:如果我切换到将消费者编写为控制台应用程序,那么它运行良好。所以,我不确定,但我认为这是在异步模式下运行时与 ASP.NET 线程有关的问题?

我做错了什么吗?

4

3 回答 3

1

我同意 Darrel - 很可能,任务出错并且没有结果......您可以使用显式延续来检查任务状态 - 例如,

return base.SendAsync(request, cancellationToken).ContinueWith(task =>
    {
        // put the code to check the task state here...
    });

另一方面,我不确定您是否需要创建自定义DelegatingHandler身份验证...尝试使用HttpClientHandler凭据属性(或UseDefaultCredentials传递当前用户的默认凭据)

var httpClient = new HttpClient(new HttpClientHandler() {
       PreAuthenticate = true,
       Credentials = new NetworkCredentials(...
   }); 

编辑:找到与使用凭证缓存的 http 客户端一起使用摘要身份验证的示例 - 请参阅此 SO Q & A: HttpRequestMessage and Digest Authentication

这应该可以解决您在摘要身份验证方面的实际问题,而无需构建您自己的处理程序。

于 2012-10-26T10:54:35.257 回答
0

我的猜测是 .Result 阻止了您的处理程序中的继续。尝试将 .Result 更改为 .ContinueWith

于 2012-10-25T04:15:25.490 回答
0

遇到同样的问题,这就是最终为我工作的原因。问题是端点抛出了 500 Internal Server Error 并因此阻塞了线程。

protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        return await base.SendAsync(request, cancellationToken)
                         .ContinueWith<HttpResponseMessage>(task =>
        {
            return task.Result;
        });
    }

注意anon函数内部的return是返回到SendAsync函数,然后我们实际返回的是Result。

于 2018-01-22T14:52:24.683 回答