写在前面
由于sharepoint服务器上的站点采用的域用户windows认证的方式登陆,而app项目虽然能够提供用户名和密码,但客户是不愿意在网络上这样传输的。所以给提供了使用ssl证书认证的方式。而webhttprequest和sharepoint的Client object model 的结合还是蛮靠谱的,这里将采用这两种方式,带上证书发送请求进行上传文件。
核心代码
1 /// <summary> 2 /// 上传文件 3 /// </summary> 4 /// <param name="serverReleativeUrl">文件夹的相对路径</param> 5 /// <param name="fileName"></param> 6 /// <returns></returns> 7 public string UploadFile(string serverReleativeUrl, string fileName, byte[] data, bool bOverWrite) 8 { 9 if (data.Length == 0) 10 { 11 return string.Empty.ToErrorJson("500", "不允许上传空文件"); 12 } 13 if (string.IsNullOrEmpty(this._siteInfo.UserName)) 14 { 15 return string.Empty.ToErrorJson("500", new ArgumentNullException("用户名参数为空").Message); 16 } 17 ClientContext spContext = new ClientContext(this._siteInfo.AppUrl); 18 //spContext.Credentials = new NetworkCredential(this._userName, this._pwd, this.strDomain); 19 /* 20 * SSL 支持 21 * SSL 身份验证协议依赖于证书。. 22 * NET Framework 中对 SSL 的支持包含两个部分。 23 * HTTP 上的 SSL 这种特殊情况(但使用最为广泛)由 HttpWebRequest 类(它最终还可用于 Web 服务客户端代理)实现。 24 * 要启用 SSL,除了要指定一个使用 Https: 协议的 URL 外,不必执行任何特殊操作。 25 * 当连接到一个受 SSL 保护的终结点时,会在客户端上对服务器证书进行验证。 26 * 如果验证失败,连接会根据默认设置立即关闭。您可以回调一个名为 ServicePointManager 的类来重写该行为。 27 * 每当 HTTP 客户端的堆栈进行证书验证时,都会首先检查是否可以回调; 28 * 如果可以,则执行您的代码。要挂接该回调,您必须提供类型 RemoteCertificateValidationCallback 的一个委托: 29 */ 30 ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(VerifyServerCertificate); 31 32 spContext.ExecutingWebRequest += spContext_ExecutingWebRequest; 33 Web website = spContext.Web; 34 Folder folder = website.GetFolderByServerRelativeUrl(serverReleativeUrl); 35 try 36 { 37 FileCreationInformation file = new FileCreationInformation(); 38 file.Content = data; 39 file.Url = fileName; 40 file.Overwrite = bOverWrite; 41 folder.Files.Add(file); 42 spContext.ExecuteQuery(); 43 } 44 catch (Exception ex) 45 { 46 throw ex; 47 } 48 49 return string.Empty.ToSuccessJson("200", "上传成功"); 50 } 51 /// <summary> 52 /// 在回调中,您会获得服务器证书、一个错误代码和一个传入的链对象,然后可以执行自己的检查并返回 true 或 false。 53 /// 如果出现诸如证书在开发或测试期间就已过期的情况,那么关闭其中某项检查是有好处的。另一方面,这样做还可以执行比默认更为严格的验证策略。 54 /// https://msdn.microsoft.com/zh-cn/magazine/cc163454.aspx#S6 55 /// </summary> 56 /// <param name="sender"></param> 57 /// <param name="certificate"></param> 58 /// <param name="chain"></param> 59 /// <param name="sslPolicyErrors"></param> 60 /// <returns></returns> 61 private bool VerifyServerCertificate(object sender, X509Certificate certificate, 62 X509Chain chain, SslPolicyErrors sslPolicyErrors) 63 { 64 if (sslPolicyErrors == SslPolicyErrors.None) return true; 65 66 foreach (X509ChainStatus s in chain.ChainStatus) 67 { 68 // allows expired certificates 69 if (string.Equals(s.Status.ToString(), "NotTimeValid", 70 StringComparison.OrdinalIgnoreCase)) 71 return true; 72 } 73 74 return false; 75 } 76 void spContext_ExecutingWebRequest(object sender, WebRequestEventArgs e) 77 { 78 HttpWebRequest webReq = e.WebRequestExecutor.WebRequest; 79 #region 此种方式个人的能上传,团队的不能上传 80 //string pfxPath = ConfigurationManager.AppSettings["ClientSigningCertificatePath"]; 81 //string pfxPassword = ConfigurationManager.AppSettings["ClientSigningCertificatePassword"]; 82 //X509Certificate2 cert = new X509Certificate2(pfxPath, pfxPassword); 83 //webReq.Credentials = new NetworkCredential(this._userName, _pwd, strDomain); 84 //webReq.ClientCertificates.Add(cert); 85 #endregion 86 CheckAppExsit(); 87 var accessToken = TokenHelper.GetS2SAccessTokenWithWindowsIdentity(new Uri(_siteInfo.AppUrl), null); 88 webReq.Method = "Post"; 89 webReq.Accept = "application/json;odata=verbose"; 90 webReq.Headers.Add("Authorization", "Bearer " + accessToken); 91 }
这种方式,可以直接使用证书进行认证,而不用提供账户信息。这里提供一下思路,希望对你有所帮助。
总结
在sharepoint中上传文件,采用Client object model是相对rest api更简单的一种方式,采用rest api,我是没有成功过,也不知道那地方出问题了,很是头疼,最后没办法,采用了这种方式。
参考文章:
http://blog.csdn.net/starlee/article/details/4441150
https://msdn.microsoft.com/zh-cn/magazine/cc163454.aspx#S6
http://www.cnblogs.com/dosboy/p/4045773.html
时间: 2024-10-05 14:25:39