在 SharePoint 2010 中使用 Client OM 和 Web 服务从多身份验证网站检索数据
原文发布于 2011 年 4 月 2 日(星期六)
从本文的标题来看,如果今天什么都要说的话,那内容可就多了。 本文主要解决长期以来一直困扰我和其他人的问题。 我最近才开始问及该问题,然后偶然收到来自某人的一封电子邮件,说他刚知道如何解决该问题。
我只讲述该应用场景最常见的部分;因为它可能变得非常复杂。 问题是从使用多个身份验证提供程序的 SharePoint 网站检索数据;在该应用场景中,假设一个是 Windows 声明,而另一个则是其他什么东西(可以是基于表单的身份验证或是 SAML 身份验证)。 通常,您需要使用 Client OM 或 SharePoint Web 服务而不是 Windows 身份验证来从此类网站检索数据。 到此问题就出来了,即使您对请求设置了 Windows 凭据,还是会在请求数据时被“拒绝访问”。
对于该问题的基本解决方案是,如果您想要使用一组 Windows 凭据以编程方式访问使用多个身份验证提供程序的 SharePoint 网站,那么您需要对请求添加一个额外的标头。 标头名称需要为 X-FORMS_BASED_AUTH_ACCEPTED 而且值需要为“f”。 添加此标头对于这两个常见的应用场景来说,可能稍显复杂,所以本文的余下部分将介绍如何使用一些示例代码来解决问题。
如果您使用的是 Client OM,则需要添加 ExecutingWebRequest 事件的事件处理程序。 下面是该代码的示例及其用法:
//create the client context
ClientContext ctx = new ClientContext(MixedUrlTxt.Text);
//configure the handler that will add the header
ctx.ExecutingWebRequest +=
new EventHandler<WebRequestEventArgs>(ctx_MixedAuthRequest);
//set windows creds
ctx.AuthenticationMode = ClientAuthenticationMode.Default;
ctx.Credentials = System.Net.CredentialCache.DefaultCredentials;
//get the web
Web w = ctx.Web;
//LOAD LISTS WITH ALL PROPERTIES
var lists = ctx.LoadQuery(w.Lists);
//execute the query
ctx.ExecuteQuery();
//enumerate the results
foreach (List theList in lists)
{
//do something with each list
}
这就是见证奇迹的地方:
void ctx_MixedAuthRequest(object sender, WebRequestEventArgs e)
{
try
{
//add the header that tells SharePoint to use Windows Auth
e.WebRequestExecutor.RequestHeaders.Add(
"X-FORMS_BASED_AUTH_ACCEPTED", "f");
}
catch (Exception ex)
{
MessageBox.Show("Error setting auth header: " + ex.Message);
}
}
就这么多了,该代码非常简单,我相信可以无师自通。 对标准的 Web 服务引用执行相同的操作时则有点不同。 开始前,让我们先了解一下将 SharePoint 网站中标准样式的 Web 引用添加至 Visual Studio 2010 中项目的流程:
1. 右键单击“服务引用”节点并选择“添加服务引用”。
2. 单击对话框底部的“高级”按钮。
3. 单击下一个对话框底部的“添加 Web 引用…”按钮。
4. 在 URL 编辑框中输入指向要使用的 Web 服务的 Url;例如,若要在网站 https://foo 中添加对列表 Web 服务的引用,我会输入以下 URL: https://foo/_vti_bin/lists.asmx。
5. 按 Enter 或单击绿色箭头按钮以找到 Web 服务引用,然后在 Web 引用名称编辑框中键入 Web 服务引用的名称并单击“添加引用”按钮。
此时应该创建您的引用和引用的代理类,但是您将需要添加一个额外的分部类以便将标头添加至您的 Web 服务请求。 先向您的项目添加一个新类,然后给它取一个您喜欢的名字。 由于您只是想增加一些额外的行为(将标头添加至请求),因此您将需要使用分部类。 这意味着您需要同时复制为 Web 引用创建的代理中使用的命名空间和类名。下面是执行该操作的步骤:
1. 单击 Visual Studio 的“解决方案资源浏览器”窗口中的“显示所有文件”按钮。
2. 单击 Web 服务引用旁边的加号以将其展开。
3. 单击 Reference.map 文件旁边的加号以将其展开。
4. 双击 Reference.cs 文件以将其打开。
5. 复制命名空间并将其粘贴到您的类中。
6. 复制类名,包括继承,并将其作为类名粘贴到您的类中。 Web 服务引用类已是分部类,所以不需要对它做什么更改。
下面的示例中,您可以看到我的 Web 服务引用的 Reference.cs 类是怎样的:
namespace ClientOmAuth.listsWS {
using System;
using System.Web.Services;
using System.Diagnostics;
using System.Web.Services.Protocols;
using System.ComponentModel;
using System.Xml.Serialization;
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "4.0.30319.1")]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Web.Services.WebServiceBindingAttribute(Name="ListsSoap", Namespace="https://schemas.microsoft.com/sharepoint/soap/")]
public partial class Lists : System.Web.Services.Protocols.SoapHttpClientProtocol {
这就是我向创建的类中粘贴的内容:
namespace ClientOmAuth.listsWS
{
public partial class Lists : System.Web.Services.Protocols.SoapHttpClientProtocol
{
}
}
所以您将注意到命名空间和类名是如何匹配的,并且该两个类都是继承自同一个基本类型。
现在您需要替代 GetWebRequest 方法,以便可以添加标头。 为此,只需将此代码添加到您的分部类中:
protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
System.Net.WebRequest wr = null;
try
{
wr = base.GetWebRequest(uri);
wr.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
}
catch (Exception ex)
{
//some error handling here
}
return wr;
}
针对通过 Web 服务检索数据进行编码现在与您对任何 Windows 身份验证 SharePoint 网站所做的完全相同:
//create the web service proxy and configure it use my Windows credentials
listsWS.Lists lws = new listsWS.Lists();
lws.UseDefaultCredentials = true;
//get the collection of lists
XmlNode xLists = lws.GetListCollection();
//enumerate results
foreach (XmlNode xList in xLists.ChildNodes)
{
//do something with each List
}
就这么多了。 您也可以应用此信息通过 REST 检索数据,使用我下面介绍的技术即可: https://blogs.technet.com/b/speschka/archive/2010/09/25/retrieving-rest-data-in-a-claims-based-auth-site-in-sharepoint-2010.aspx(该链接可能指向英文页面)。
这是一篇本地化的博客文章。请访问 Retrieving Data from a Multi Auth Site Using the Client OM and Web Services in SharePoint 2010 以查看原文