奇怪的HTTP身份验证问题

时间:2011-09-05 13:50:38

标签: c# httpwebrequest digest-authentication

尝试使用摘要式身份验证与Web服务器(Apache 2.2.17)进行通信,并使用POST方法发送数据时,我遇到了问题:它总是返回401错误。但是,当我们不发布数据或Fiddler正在运行时(即使在发布数据时)它也能正常工作......您是否知道可能导致问题的原因?

public void DoRequest(string v_strURL, XmlDocument v_objXMLDoc)
{

var credentialCache = new CredentialCache();

credentialCache.Add(new Uri("http://" + ServerIP + "/"), "Digest", new NetworkCredential("admin", "test", "realm"));

String RequestContent = "request=" + v_objXMLDoc.InnerXml.Replace(' ', '+');
Uri Url = new Uri(v_strURL);

HttpWebRequest objHttpWebRequest;
HttpWebResponse objHttpWebResponse = null;

Stream objRequestStream = null;

byte[] bytes = new byte[0];
bytes = System.Text.Encoding.UTF8.GetBytes(RequestContent);

objHttpWebRequest = (HttpWebRequest)WebRequest.Create(v_strURL);
objHttpWebRequest.UserAgent = "MySampleCode";
objHttpWebRequest.Credentials = credentialCache;
objHttpWebRequest.Method = "POST";
objHttpWebRequest.ContentLength = bytes.Length;
objHttpWebRequest.ContentType = "text/xml; encoding='utf-8'";
objHttpWebRequest.ContentType = "application/x-www-form-urlencoded";

objRequestStream = objHttpWebRequest.GetRequestStream();
objRequestStream.Write(bytes, 0, bytes.Length);
objRequestStream.Close();

objHttpWebResponse = (HttpWebResponse)objHttpWebRequest.GetResponse();

}

3 个答案:

答案 0 :(得分:2)

您是否有某种原因要将Content-Type标头设置两次?这不可能做你想做的事。另外,为什么要使用服务器IP而不是主机名将缓冲区放入缓存中?

HTTP / 401表明服务器正在挑战客户端的凭据。期望客户通过附加凭证重新提交请求来做出响应。一个关键问题是,在失败的情况下,客户端是否尝试发送凭据并被拒绝,或者根本没有尝试发送凭据?

如果Fiddler“神奇地”为您解决问题,您可能应该使用Netmon或Wireshark作为较低级别的外观。

答案 1 :(得分:1)

HttpWebRequest.Create()调用中的主机名(即v_strUrl)是否与调用credentialCache.Add()(即ServerIP)中的主机名相同?如果没有,那么这将永远失败。

只需将凭据直接添加到HttpWebRequest对象

,而不是使用CredentialCache
  

request.Credentials = new NetworkCredential(“user”,“password”,“realm”);

看看是否有效。

答案 2 :(得分:0)

我们终于解决了这个问题:

objHttpWebRequest.ServicePoint.Expect100Continue = false;