我在ASP.NET 2.0中创建了一个非常简单的Web服务来查询SharePoint 2007中的列表,如下所示:
namespace WebService1
{
/// <summary>
/// Summary description for Service1
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
// [System.Web.Script.Services.ScriptService]
public class Service1 : System.Web.Services.WebService
{
[WebMethod]
public string HelloWorld()
{
return "Hello World";
}
[WebMethod]
public string ShowSPMyList()
{
string username = this.User.Identity.Name;
return GetList();
}
private string GetList()
{
string resutl = "";
SPSite siteCollection = new SPSite("http://localhost:89");
using (SPWeb web = siteCollection.OpenWeb())
{
SPList mylist = web.Lists["MySPList"];
SPQuery query = new SPQuery();
query.Query = "<Where><Eq><FieldRef Name=\"AssignedTo\"/><Value Type=\"Text\">Ramprasad</Value></Eq></Where>";
SPListItemCollection items = mylist.GetItems(query);
foreach (SPListItem item in items)
{
resutl = resutl + SPEncode.HtmlEncode(item["Title"].ToString());
}
}
return resutl;
}
}
}
使用Visual Studio 2008的内置服务器测试时,此Web服务运行良好。用户名完全表示我的域帐户(domain \ myusername)。
但是,当我创建一个虚拟文件夹来托管并启动此Web服务(仍与SP2007位于同一台机器中)时,在执行OpenWeb()的行中调用ShowSPMyList()方法时出现以下错误。以下是错误的详细信息:
System.Data.SqlClient.SqlException: Cannot open database "WSS_Content_8887ac57951146a290ca134778ddc3f8" requested by the login. The login failed.
Login failed for user 'NT AUTHORITY\NETWORK SERVICE'.
有谁知道为什么会发生这种错误?为什么Web服务在Visual Studio 2008中运行良好,但在独立运行时却没有?我检查过,在两种情况下,username变量都具有相同的值(domain \ myusername)。
非常感谢。
非常感谢您的回复。我将查看文档,了解如何根据建议更改与应用程序池相关的设置。
我想明确表示我想构建一个在sharepoint之外运行的web服务(但可以使用sharepoint部署在同一台服务器上)。
有什么办法可以在调用OpenWeb方法时以编程方式将凭据(默认情况下为另一个域帐户而不是“NT AUTHORITY \ NETWORK SERVICE”)传递给sharepoint?我相信如果我能够做到这一点,那么我可以解决上面的安全问题。
答案 0 :(得分:0)
当您创建自己的自定义虚拟文件夹并将其设置在IIS中时,运行该特定IIS虚拟目录的应用程序池的用户帐户很可能当前设置为NT authority \ Network Service。
通过仔细查看运行该特定IIS虚拟目录的实际应用程序池,您可以仔细检查。
从那里,您可以转到“应用程序池”文件夹并右键单击,然后选择“属性”。选择“标识”选项卡,它将显示当前正在运行应用程序池的用户帐户。
或者,您可以参考SharePoint SDK,类似于动态CRM中的ExtractCrmAuthenticationToken ,以提取身份验证令牌票证。
或者您可以使用Network Credential嵌入自己的自定义用户ID和密码。
希望这有帮助,
hadi teo
答案 1 :(得分:0)
我完全同意Hadi,如果这是您想要快速测试的内容,为了概念验证,您可以将应用程序池运行的凭据更改为具有权限的用户。或者您可以在配置文件中使用Identity Impersonate设置。
然而,在生产环境中抵制这样做的诱惑,请使用正确的身份验证。它会回来,咬你。
如果您需要将其设置为生产,您需要查看几个区域,复制SPN,并且可能是未正确配置的最常见区域。然而,您的错误指向没有发生冒充。
答案 2 :(得分:0)
还要确保将Web服务部署到尚未运行SharePoint的网站。如果您希望Web服务在与SharePoint同一网站上运行,请阅读Creating a Custom Web Service。
您可以按照Hadi编写的相同说明检查SharePoint正在使用的应用程序池标识,但是对于运行SharePoint的应用程序池。确保仅更改Web服务使用的应用程序池和非SharePoint ,否则SP中可能会发生其他权限错误。 (如果您有兴趣更改SharePoint follow these instructions使用的应用程序池标识,则应该没有理由。)
答案 3 :(得分:0)
解决方案是使用以下代码“模拟”作为SharePoint系统帐户:
SPSecurity.RunWithElevatedPrivileges(delegate()
{
// also dispose SPSite
using (SPSite siteCollection = new SPSite("http://localhost:89"))
{
using (SPWeb web = siteCollection.OpenWeb())
{
// ...
}
}
});