我很难理解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,但我很难将相关信息与过时和不相关的信息分开。
如果有人可以帮助我解决最值得赞赏的问题,但即使是链接到适当的教育资源也将有所帮助。
答案 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;
}
}
您可以使用处理程序来执行其他各种操作,客户端可以像设置请求标头或设置基地址一样。