HttpWebRequest提交Form和上传文件的认证问题

来源:互联网 发布:维纶触摸屏数据存储 编辑:程序博客网 时间:2024/04/30 00:07

HttpWebRequest提交Form和上传文件的认证问题

HttpWebRequest, 集成认证, IIS, DefaultCredentials, Credentials

使用HttpWebRequest调用在SharePoint上开发的一个上传页面上传文件和提交Form数据,方法是:
1、先通过GET的方法获取Upload.aspx页的内容,用正则表达式过滤出所有的input元素,重要的如__VIEWSTATE等:

  1. NetworkCredential credential = new NetworkCredential("userid", "password", "domain");
  2. CookieContainer cookieContainer = new CookieContainer();
  3. HttpWebRequest webRequest = HttpWebRequest.Create(url) as HttpWebRequest;
  4. webRequest.Method = "GET";
  5. webRequest.CookieContainer = cookieContainer;
  6. HttpWebResponse webResponse = webRequest.GetResponse() as HttpWebResponse;
  7. Stream responseStream = webResponse.GetResponseStream();
  8. StreamReader streamReader = new StreamReader(responseStream, Encoding.UTF8);
  9. string responseStr = streamReader.ReadToEnd();
  10. ……
复制代码

2、然后把Get取到的hidden域、需要输入的内容及文件内容编码POST到Web Server端,再读取Web Server的响应以判断是否上传成功:

  1. byte[] aryPostData = Encoding.UTF8.GetBytes(strPostData);
  2. FileStream fileStream = new FileStream(txtFile.Text, FileMode.Open, FileAccess.Read);
  3. byte[] aryFileData = new byte[fileStream.Length];
  4. fileStream.Read(aryFileData, 0, (int)fileStream.Length);
  5. fileStream.Close();
  6. byte[] aryBoundaryEnd = Encoding.UTF8.GetBytes("/r/n--" + boundary + "/r/n");
  7. webRequest = HttpWebRequest.Create(url) as HttpWebRequest;
  8. webRequest.CookieContainer = cookieContainer;
  9. webRequest.Credentials = credential;
  10. webRequest.Method = "OST";
  11. webRequest.ContentType = "multipart/form-data; boundary=" + boundary;
  12. webRequest.ContentLength = aryPostData.Length + aryFileData.Length + aryBoundaryEnd.Length;
  13. webRequest.CookieContainer = cookieContainer;
  14. webRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)";
  15. webRequest.Referer = referer;
  16. responseStream = webRequest.GetRequestStream();
  17. responseStream.Write(aryPostData, 0, aryPostData.Length);
  18. responseStream.Write(aryFileData, 0, aryFileData.Length);
  19. responseStream.Write(aryBoundaryEnd, 0, aryBoundaryEnd.Length);
  20. responseStream.Flush();
  21. responseStream.Close();
  22. try
  23. {
  24. webResponse = webRequest.GetResponse() as HttpWebResponse;
  25. responseStream = webResponse.GetResponseStream();
  26. streamReader = new StreamReader(responseStream, Encoding.UTF8);
  27. responseStr = streamReader.ReadToEnd();
  28. }
  29. catch (WebException exp)
  30. {
  31. if(exp.Response!=null)
  32.     System.Diagnostics.Trace.WriteLine(((HttpWebResponse)exp.Response).StatusDescription;
  33. else
  34.     System.Diagnostics.Trace.WriteLine(exp.Message);
  35. }
复制代码

客户端和Web Server处于同一个NT域中,由于该站点采用了Windows集成认证,所以new 了一个NetworkCredential作为认证凭证,提供了用户名、密码和域名信息:

  1. NetworkCredential credential = new NetworkCredential("userid", "password", "domain");
  2. ...
  3. webRequest.Credentials = credential;
复制代码

但是,虽然提供了正确的用户名和密码,每次在POST完Form数据后,从Web Server获取响应时:

  1. webResponse = webRequest.GetResponse() as HttpWebResponse;
复制代码

总是报"Unauthorized"的错误,查看Web Server,文件已经成功传上去了,怪事

后来把认证凭证改成了:

  1. NetworkCredential credential = CredentialCache.DefaultCredentials as NetworkCredential;
  2. ...
  3. webRequest.Credentials = credential;
复制代码

竟然不出错了,默认取当前登录到域的用户的帐户信息,正好与我当前的应用环境相附。

----------------------------------------------------------------------------------------------------------------------------
MSDN中对DefaultCredentials的解释是:

CredentialCache.DefaultCredentials 属性
    获取应用程序的系统凭据。
...
DefaultCredentials 属性仅适用于基于 NTLM、协商和 Kerberos 的身份验证。
  DefaultCredentials 表示运行应用程序的当前安全上下文的系统凭据。对于客户端应用程序,这些通常是运行应用程序的用户的 Windows 凭据(用户名、密码和域)。对于 ASP.NET 应用程序,默认凭据是已登录的用户或正被模拟的用户的用户凭据。

ref: http://www.cnblogs.com/cowbird/archive/2005/03/04/113281.aspx

原创粉丝点击