.NET中的CredentialCache和HttpWebRequest

时间:2018-08-01 10:40:00

标签: c# http authentication

我很难理解Web请求和凭据在.NET中的工作方式。

我有以下方法正在执行对SOAP端点的请求。

 public WebResponse Execute(NetworkCredential Credentials)
 {
       HttpWebRequest webRequest = CreateWebRequest(_url, actionUrl);
       webRequest.AllowAutoRedirect = true;
       webRequest.PreAuthenticate = true;
       webRequest.Credentials = Credentials; 

       // Add headers and content into the requestStream

       asyncResult.AsyncWaitHandle.WaitOne();
       return webRequest.EndGetResponse(asyncResult);
}

效果很好。但是,我的应用程序的用户可能不得不在短时间内连续执行许多此类请求。一天中有数百个。我的目标是实施我已阅读的一些建议,即在应用程序整个生命周期中都存在的using an HttpClient,并使用CredentialCache存储用户的凭据,而不是将其传递给每个请求。

所以我从CredentialCache开始。

按照上面链接的示例,我实例化了一个CredentialCache并向其中添加了网络凭据。请注意,这与我之前传递给请求的NetworkCredential对象完全相同。

NetworkCredential credential = new NetworkCredential();
credential.UserName = Name;
credential.Password = PW;
Program.CredCache.Add(new Uri("https://blah.com/"), "Basic", credential);

然后,当我发送HTTP请求时,我从缓存中获取凭据,而不是直接提供凭据对象。

 public WebResponse Execute(NetworkCredential Credentials)
 {
        HttpWebRequest webRequest = CreateWebRequest(_url, actionUrl);
        webRequest.AllowAutoRedirect = true;
        webRequest.PreAuthenticate = true;
        webRequest.Credentials = Program.CredCache; 

        // more stuff down here
}

请求现在失败,并显示401错误。

我未能从多个层面上理解这一点。首先,我似乎无法弄清楚CredentialCache是否确实已将正确的凭据传递给HTTP请求。

我怀疑部分问题可能是我正在尝试使用“基本”身份验证。我尝试过“摘要”功能,就像在黑暗中拍摄一样(也失败了),但是我敢肯定,必须有一种方法来查看服务器期望进行哪种身份验证。

我一直在试图尽可能多地阅读StackOverflow和MDN,但我很难将相关信息与过时和不相关的信息分开。

如果有人可以帮助我解决最值得赞赏的问题,但即使是链接到适当的教育资源也将有所帮助。

1 个答案:

答案 0 :(得分:0)

根据文档,CredentialCache类仅适用于SMTP,它明确指出它不适用于HTTP或FTP请求:

https://msdn.microsoft.com/en-us/library/system.net.credentialcache(v=vs.110).aspx

这与后面的api文档中的信息直接矛盾。我不知道哪一个是正确的。

您可以尝试使用HttpClient类。方法和返回类型是不同的,因此您需要稍微调整一下其他代码,但是看起来有点像这样:

public class CommsClass
{
    private HttpClient _httpClient;

    public CommsClass(NetworkCredential credentials)
    {
         var handler = new HttpClientHandler { Credentials = credentials };
         _httpclient = new HttpClient(handler);
    }

    public HttpResponseMessage Execute(HttpRequestMessage message)
    {
        var response = _httpClient.SendAsync(message).Result;
        return response;
    }
}

您可以使用处理程序来执行其他各种操作,客户端可以像设置请求标头或设置基地址一样。