关于SharePoint REST中的授权的研究

博客地址:http://blog.csdn.net/FoxDave
当我们开发SharePoint APP需要调用REST服务时,可以使用OAuth完成授权,也可以使用跨域库。以下是微软专家的一段注解。
如果是从无法以独占方式使用客户端代码(HTML 和 JavaScript)的远程托管应用程序调用 SharePoint,且 SharePoint 与应用程序之间没有防火墙阻隔,则可使用 OAuth 2.0 令牌(使用 Microsoft 访问控制服务 (ACS) 作为安全令牌服务器)。
如果客户端代码和登录到 SharePoint 的用户的权限足够,则 JavaScript 跨域库 (bit.ly/12kFwSP) 将是一个很好的 OAuth 替代品。  另外,当进程调用需要穿过防火墙时,跨域库也是替代 OAuth 的一个好选择。 MSDN 库文章“SharePoint 2013 数据访问选项”(bit.ly/WGvt9L) 详细介绍了这些选项。
但是这些主要都是针对SharePoint App来说的,当我们在我们自己的应用(如第三方网站、移动设备等)中要通过REST获取sharepoint的内容时,要如何做呢?
笔者做了以下一些研究,但是没有得出最终解决方案,前一阵请教过Jason Huang,后来也没有音信了。欢迎大牛能进行指点,也欢迎大家多多讨论。
我先描述一下大致的场景:远程SharePoint网站,采用NTLM协议的认证。我要做的就是通过调用REST服务来获取数据。
本文以命令行程序作为示例,访问SharePoint的内容。

一. 采用网络请求(WebRequest)的方式
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://ap.2013.trial.nintex.com/_api/web/");
            request.Accept = "application/json;odata=verbose";
            NetworkCredential myCredential = new NetworkCredential("Justin.Liu1", "3QF0\"gn", "EXT");
            request.Credentials = myCredential;
            WebResponse response = request.GetResponse();
            Stream stream = response.GetResponseStream();
            StreamReader sr = new StreamReader(stream);
            string content = sr.ReadToEnd();
这个方式获得了我需要的数据,抓包可以看到网络请求的过程如下:
关于SharePoint REST中的授权的研究_第1张图片
关于SharePoint REST中的授权的研究_第2张图片
关于SharePoint REST中的授权的研究_第3张图片
基本的流程大致如下:
先去敲门,远程SharePoint回应“我在”;然后用提供的凭据去进行验证,验证通过后返回认证通过的编码串;通过这个编码串再去请求需要的数据,远程SharePoint认证通过会返回请求的数据。

二. 采用客户端对象模型CSOM的方式
NetworkCredential myCredential = new NetworkCredential("Justin.Liu1", "3QF0\"gn", "EXT");
ClientContext ctx = new ClientContext("https://ap.2013.trial.nintex.com/");
            ctx.Credentials = myCredential;
            Web web = ctx.Web;
            ctx.Load(web);
            ctx.ExecuteQuery();
            string title = web.Title;
这种方式也获得了我需要的数据,来看一下抓包得到的过程:
关于SharePoint REST中的授权的研究_第4张图片
关于SharePoint REST中的授权的研究_第5张图片
关于SharePoint REST中的授权的研究_第6张图片
关于SharePoint REST中的授权的研究_第7张图片
从中我们可以看到,CSOM实际上是封装了SharePoint的WebService。

三. 采用调用SharePoint WebService的方式
//Site URL: https://ap.2013.trial.nintex.com
            //Username: EXT\Justin.Liu1
            //Password: 3QF0"gn
            var soapEnv = string.Format(@"<?xml version=""1.0"" encoding=""utf-8""?>
                    <soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
                      <soap:Body>
                        <Login xmlns=""http://schemas.microsoft.com/sharepoint/soap/"">
                          <username>{0}</username>
                          <password>{1}</password>
                        </Login>
                      </soap:Body>
                    </soap:Envelope>","EXT\\Justin.Liu1","3QF0\"gn");
            byte[] data = Encoding.UTF8.GetBytes(soapEnv);
            HttpWebRequest loginRequest = (HttpWebRequest)WebRequest.Create("https://ap.2013.trial.nintex.com/_vti_bin/Authentication.asmx");
            loginRequest.Headers["SOAPAction"] = "http://schemas.microsoft.com/sharepoint/soap/Login";
            loginRequest.Method = "POST";
            loginRequest.ContentType = "text/xml; charset=utf-8";
            loginRequest.ContentLength = data.Length;
            Stream requestStream = loginRequest.GetRequestStream();
            requestStream.Write(data, 0, data.Length);
            requestStream.Close();
            WebResponse loginResponse = loginRequest.GetResponse();
            Stream loginStream = loginResponse.GetResponseStream();
            StreamReader lsr = new StreamReader(loginStream);
            string loginContent = lsr.ReadToEnd();
            requestStream.Close();
该方式并没有成功,报出401未授权的错误:
关于SharePoint REST中的授权的研究_第8张图片 
关于SharePoint REST中的授权的研究_第9张图片
我为什么尝试第三种方式,因为在移动设备中应该是无法应用前两种方式的。
以上便是之前研究的总结,由于有其他事情暂且搁置在此并分享出来,希望对朋友们能起到抛砖引玉的作用,也欢迎共同探讨解决方案。

你可能感兴趣的:(REST,SharePoint,SharePoint,2013)