SharePoint 2010客户端对象模型-Kerberos/声明身份验证
我正在尝试从远程SharePoint网站(不同的SP Web应用)的列表中读取值。web应用程序使用Claims Auth进行设置,客户端web应用程序SP托管帐户使用SPN进行配置。我相信Kerberos和声明设置正确,但我无法访问远程服务器,请求导致异常:“远程服务器返回错误:(401)未经授权。” 异常发生在SharePoint 2010客户端对象模型-Kerberos/声明身份验证,sharepoint,sharepoint-2010,claims-based-identity,sharepoint-clientobject,Sharepoint,Sharepoint 2010,Claims Based Identity,Sharepoint Clientobject,我正在尝试从远程SharePoint网站(不同的SP Web应用)的列表中读取值。web应用程序使用Claims Auth进行设置,客户端web应用程序SP托管帐户使用SPN进行配置。我相信Kerberos和声明设置正确,但我无法访问远程服务器,请求导致异常:“远程服务器返回错误:(401)未经授权。” 异常发生在ctx.ExecuteQuery()行中但是它不会捕获中的异常,如果(scope.HasException)相反,异常被调用代码捕获(在using{}块之外) 当我使用Wireshar
ctx.ExecuteQuery()行中代码>但是它不会捕获中的异常,如果(scope.HasException)
相反,异常被调用代码捕获(在using{}块之外)
当我使用Wireshark查看远程服务器上的流量时,看起来请求甚至没有到达服务器;这几乎就像401发生在Kerberos票证交换声明之前
这是我的密码:
using (ClientContext ctx = new ClientContext(contextUrl))
{
CredentialCache cc = new CredentialCache();
cc.Add(new Uri(contextUrl), "Kerberos", CredentialCache.DefaultNetworkCredentials);
ctx.Credentials = cc;
ctx.AuthenticationMode = ClientAuthenticationMode.Default;
ExceptionHandlingScope scope = new ExceptionHandlingScope(ctx);
Web ctxWeb = ctx.Web;
List ctxList;
Microsoft.SharePoint.Client.ListItemCollection listItems;
using (scope.StartScope())
{
using (scope.StartTry())
{
ctxList = ctxWeb.Lists.GetByTitle("Reusable Content");
CamlQuery qry = new CamlQuery();
qry.ViewXml = string.Format(ViewQueryByField, "Title", "Text", SharedContentTitle);
listItems = ctxList.GetItems(qry);
ctx.Load(listItems, items => items.Include(
item => item["Title"],
item => item["ReusableHtml"],
item => item["ReusableText"]));
}
using (scope.StartCatch()) { }
using (scope.StartFinally()) { }
}
ctx.ExecuteQuery();
if (scope.HasException)
{
result = string.Format("Error retrieving content<!-- Error Message: {0} | {1} -->", scope.ErrorMessage, contextUrl);
}
if (listItems.Count == 1)
{
Microsoft.SharePoint.Client.ListItem contentItem = listItems[0];
if (SelectedType == SharedContentType.Html)
{
result = contentItem["ReusableHtml"].ToString();
}
else if (SelectedType == SharedContentType.Text)
{
result = contentItem["ReusableText"].ToString();
}
}
}
使用(ClientContext ctx=newclientcontext(contextrl))
{
CredentialCache cc=新的CredentialCache();
cc.Add(新Uri(contextUrl),“Kerberos”,CredentialCache.DefaultNetworkCredentials);
ctx.Credentials=cc;
ctx.AuthenticationMode=ClientAuthenticationMode.Default;
例外处理范围=新的例外处理范围(ctx);
Web-ctxWeb=ctx.Web;
列出ctxList;
Microsoft.SharePoint.Client.ListItemCollection listItems;
使用(scope.StartScope())
{
使用(scope.StartTry())
{
ctxList=ctxWeb.Lists.GetByTitle(“可重用内容”);
CamlQuery qry=新的CamlQuery();
qry.ViewXml=string.Format(viewQueryField,“Title”,“Text”,SharedContentTitle);
listItems=ctxList.GetItems(qry);
Load(listItems,items=>items.Include(
项目=>项目[“标题”],
item=>item[“ReusableHtml”],
item=>item[“ReusableText”]);
}
使用(scope.StartCatch()){}
使用(scope.StartFinally()){}
}
ctx.ExecuteQuery();
if(scope.HasException)
{
结果=string.Format(“检索内容时出错”,scope.ErrorMessage,contextUrl);
}
如果(listItems.Count==1)
{
Microsoft.SharePoint.Client.ListItem contentItem=listItems[0];
if(SelectedType==SharedContentType.Html)
{
结果=contentItem[“ReusableHtml”].ToString();
}
else if(SelectedType==SharedContentType.Text)
{
结果=contentItem[“ReusableText”]。ToString();
}
}
}
我意识到在声明中不需要使用CredentialCache,但我能找到的每一个示例要么运行在控制台应用程序中,要么运行在某种客户端应用程序中;此代码在常规ASP.NET用户控件的代码隐藏中运行
编辑:我可能应该提到,当远程URL是与调用代码(位于/sites/)相同web应用程序上的根网站集时,上面的代码甚至不起作用——换句话说,即使主机名与调用代码相同
任何关于下一步尝试的建议都将不胜感激
Mike您不使用标准OM有什么原因吗
您已经说过这是在web部件中运行的,这意味着它在应用程序池帐户的上下文中。除非通过切换用户来提升权限,否则无法正确进行身份验证。也许可以试试。但是,如果您已经可以访问API,我就不会使用客户端OM。我需要能够跨web应用程序和跨场进行调用……我想我可以放弃跨场功能,但我更愿意保留它。它实际上是在用户控件中运行的,而不是在web部件中运行的,但我想就它而言,这里没有什么不同——它们都在SPContext中运行。我认为值得尝试跨web应用程序调用的服务器端api,因为我使用的是kerberos。今天上午我将试一试。好吧,接下来,我无法在那种环境下使用客户端OM进行跨场呼叫。我仍然不确定这是一个环境问题,还是我的工作方式有一些模糊的错误,所以在我能够自己从头开始建立一个独立的环境之前,我放弃了跨农场的工作,转而使用标准的服务器端OM。