我很难理解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);
}
它足够好用了。然而,我的应用程序的用户可能不得不在短时间内连续执行数十个这样的请求。一天中有数百人。我的目标是实现我读到的一些建议,即使用在应用程序的整个生命周期中都存在的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请求传递了正确的凭据。
我怀疑问题的一部分可能是我试图使用"基本"身份验证。我也尝试过"摘要"(Digest(,但也失败了,但我相信一定有办法了解服务器期望的身份验证类型。
我一直在梳理StackOverflow和MDN,试图尽可能多地了解这一点,但我很难将相关信息与过时和无关的信息区分开来。
如果有人能帮我解决这个问题,我将不胜感激,但即使是连接到适当的教育资源也会有所帮助。
根据文档,CredentialCache
类仅用于SMTP,它明确表示不用于HTTP或FTP请求:
https://msdn.microsoft.com/en-us/library/system.net.credentialcache(v=vs.110(.aspx
这与后面的api文档中的信息直接矛盾。我不知道哪一个是对的。
您可以尝试使用HttpClient
类。方法和返回类型不同,所以你需要稍微调整一下你的另一个a代码,但它看起来有点像:
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;
}
}
您可以使用处理程序和客户端来做各种其他事情,比如设置请求头或设置基地址。