编程语言
首页 > 编程语言> > C#HttpClient重定向后不发送基本身份验证

C#HttpClient重定向后不发送基本身份验证

作者:互联网

我的代码正在对需要基本身份验证的Web服务URL进行HTTP GET.

我使用HttpClient和HttpClientHandler实现了这个,HttpClientHandler定义了Credentials属性.

这一切都很完美.除了我的一个用例,我正在进行经过身份验证的GET:
http://somedomain.com重定向到http://www.somedomain.com.

似乎HttpClientHandler在重定向期间清除了身份验证标头.我怎么能阻止这个?无论重定向如何,我都希望发送凭据.

这是我的代码:

// prepare the request
var request = new HttpRequestMessage(method, url);
using (var handler = new HttpClientHandler { Credentials = new NetworkCredential(username, password) , PreAuthenticate = true })
using (var client = new HttpClient(handler))
{
    // send the request
    var response = await client.SendAsync(request);

注意:这是一个相关的问题:
Keeping HTTP Basic Authentification alive while being redirected
但由于我使用不同的类来提出请求,因此可能会有更好,更具体的解决方案

解决方法:

默认的HttpClientHandler使用相同的HttpWebRequest基础结构.而不是将NetworkCredential分配给Credentials属性,而是创建CredentialCache并分配它.

这就是我用来代替AutoRedirect的东西,并且有一点async / await仙尘,它可能会更漂亮,更可靠.

 public class GlobalRedirectHandler : DelegatingHandler {

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) {
        var tcs = new TaskCompletionSource<HttpResponseMessage>();

        base.SendAsync(request, cancellationToken)
            .ContinueWith(t => {
                HttpResponseMessage response;
                try {
                    response = t.Result;
                }
                catch (Exception e) {
                    response = new HttpResponseMessage(HttpStatusCode.ServiceUnavailable);
                    response.ReasonPhrase = e.Message;
                }
                if (response.StatusCode == HttpStatusCode.MovedPermanently
                    || response.StatusCode == HttpStatusCode.Moved
                    || response.StatusCode == HttpStatusCode.Redirect
                    || response.StatusCode == HttpStatusCode.Found
                    || response.StatusCode == HttpStatusCode.SeeOther
                    || response.StatusCode == HttpStatusCode.RedirectKeepVerb
                    || response.StatusCode == HttpStatusCode.TemporaryRedirect

                    || (int)response.StatusCode == 308) 
                {

                    var newRequest = CopyRequest(response.RequestMessage);

                    if (response.StatusCode == HttpStatusCode.Redirect 
                        || response.StatusCode == HttpStatusCode.Found
                        || response.StatusCode == HttpStatusCode.SeeOther)
                    {
                        newRequest.Content = null;
                        newRequest.Method = HttpMethod.Get;

                    }
                    newRequest.RequestUri = response.Headers.Location;

                    base.SendAsync(newRequest, cancellationToken)
                        .ContinueWith(t2 => tcs.SetResult(t2.Result));
                }
                else {
                    tcs.SetResult(response);
                }
            });

        return tcs.Task;
    }

    private static HttpRequestMessage CopyRequest(HttpRequestMessage oldRequest) {
        var newrequest = new HttpRequestMessage(oldRequest.Method, oldRequest.RequestUri);

        foreach (var header in oldRequest.Headers) {
            newrequest.Headers.TryAddWithoutValidation(header.Key, header.Value);
        }
        foreach (var property in oldRequest.Properties) {
            newrequest.Properties.Add(property);
        }
        if (oldRequest.Content != null) newrequest.Content = new StreamContent(oldRequest.Content.ReadAsStreamAsync().Result);
        return newrequest;
    }
}

标签:c,redirect,authentication,net,dotnet-httpclient
来源: https://codeday.me/bug/20190703/1367537.html