2011-09-05 116 views
0

嘗試使用摘要式身份驗證與Web服務器(Apache 2.2.17)通信並使用POST方法發送數據時遇到問題:它始終返回401錯誤。但是,如果我們不發佈數據,或者當Fiddler正在運行(即使發佈數據時),它也會運行良好......您是否瞭解可能導致問題的原因?奇怪的HTTP身份驗證問題

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(); 

} 
+1

請出示一些源代碼和 – Yahia

+0

你需要顯示源代碼比較有什麼越過線(有和沒有小提琴手),例如使用Wireshark ...我寫了大量的C#代碼,它們使用HTTP發佈數據並摘要身份驗證,這些身份驗證在生產環境中使用並且沒有問題。因此,無論您的代碼是否存在一些錯誤,或者存在服務器配置問題,沒有示例代碼/更多細節,都無法分辨! – RobV

+0

我會盡快發佈源代碼! – JoRoy

回答

0

我們終於解決了這個問題:

objHttpWebRequest.ServicePoint.Expect100Continue = false; 
2

是否有某些原因需要設置Content-Type標頭兩次?這不太可能做你想做的事情。另外,爲什麼你把信譽放在服務器IP而不是主機名的緩存中?

HTTP/401表明服務器正在挑戰客戶端的憑證。預計客戶端將通過重新提交帶有憑證的請求進行響應。一個關鍵問題是,在失敗的情況下,客戶端是否嘗試發送憑證,並且他們被拒絕,或者根本沒有嘗試發送憑證?

如果Fiddler「神奇地」爲您解決問題,您可能應該使用Netmon或Wireshark進行低級外觀。

+0

對不起,設置Content-Type頭兩次是一個錯誤。服務器IP是我們唯一的信息......要回答您的關鍵問題,是的,客戶端嘗試發送憑據,他們被拒絕。 –

+0

我*認爲*你是說服務器IP是你在URL中而不是主機名?另外,您能否提供示例URL(例如,是否存在查詢字符串參數)以及服務器摘要挑戰中的令牌(例如,它是否配置爲完整性?) – EricLaw

1

您的HttpWebRequest.Create()調用(即v_strUrl)中的主機名是否與調用credentialCache.Add()(即ServerIP)時的主機名相同?如果不是,那麼這總是會失敗。

代替使用CredentialCache的,只是直接添加憑據HttpWebRequest對象

request.Credentials =新的NetworkCredential( 「用戶」, 「密碼」, 「域」);

看看是否有效。