您是否可以在不提供密码的情况下在SharePoint中执行模拟搜索?

时间:2009-06-22 03:53:33

标签: sharepoint search impersonation

我过去通过执行以下操作在SharePoint中进行了很多模仿。

SPWeb web = SPContext.Current.Web;
string currentWebUrl = web.Url;
SPUser user = web.EnsureUser(loginToImpersonate);
using (SPSite site = new SPSite(currentWebUrl, user.UserToken)
{
    using (SPWeb impersonatedWeb = site.OpenWeb())
    {
        // Any SharePoint access here to 'impersonatedWeb'
        // is impersonated as 'loginToImpersonate'
    }
}

请注意,这不需要您模拟的用户的密码,但需要运行某些代码访问安全性。作为旁注,EnsureUser调用还要求当前用户是管理员,但是还有其他方法可以代替EnsureUser来获取SPUser对象(尝试保持我的代码片段对于这个问题简单)。

现在我已经设置了阶段...我现在想要针对MOSS或WSS查询引擎执行FullTextSQLQuery或KeywordQuery,并根据模拟用户获取安全性修剪结果。两个对象都可以在构造函数上使用SPSite,但忽略我的模拟逻辑。它们与当前登录的用户一起使用(HTTPContext.Current.User)。

还有其他构造函数:应用程序名称(字符串),对于MOSS,有一个带有SSP的ServerContext,但我认为这些根本不会有所帮助。

我在KeywordQuery类和它的基本Query类上使用了Reflector,它很快就变得非常难看。我相信确定用户的实际逻辑是非托管代码。

那么,我可以这样做吗?

3 个答案:

答案 0 :(得分:4)

您需要真正的Windows模拟才能执行此操作。 SPSite模拟不是真正的模拟 - 它只是告诉WSS对象模型将另一个用户ID写入内容数据库中创建和修改的字段。

对于Windows模拟,您将不幸需要登录名和密码,除非您想使用SPSecurity.RunWithElevatedPrivileges模拟应用程序池帐户

您可以按如下方式实施Windows模拟:

using (Impersonator imp = new Impersonator("user", "domain", "password"))
{
  // Do stuff impersonated
}

将Impersonator类实现为:

public sealed class Impersonator : IDisposable
{
  private WindowsImpersonationContext impersonationContext;

  public Impersonator(string user, string domain, string password)
  {
    WindowsIdentity id = Logon(user, domain, password);
    impersonationContext = id.Impersonate();
  }

  public void Dispose()
  {
    if (impersonationContext != null)
    {
      impersonationContext.Undo();
      impersonationContext = null;
    }
  }

  private WindowsIdentity Logon(string user, string domain, string password)
  {
    WindowsIdentity identity;
    IntPtr handle = IntPtr.Zero;
    bool logonSucceeded = LogonUser(
      user, domain, password,
      8,   // LOGON32_LOGON_NETWORK_CLEARTEXT
      0,   // LOGON32_PROVIDER_DEFAULT
      ref handle);

    if (!logonSucceeded)
    {
      int errorCode = Marshal.GetLastWin32Error();
      throw new UnauthorizedAccessException("User logon failed. Error Number: " + errorCode);
    }

    identity = new WindowsIdentity(handle);
    CloseHandle(handle);

    return identity;
  }

  [DllImport("advapi32.dll", SetLastError = true)]
  private static extern bool LogonUser(string lpszUsername,
    string lpszDomain,
    string lpszPassword,
    int dwLogonType,
    int dwLogonProvider,
    ref IntPtr phToken);

  [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
  private static extern bool CloseHandle(IntPtr handle);
}

答案 1 :(得分:1)

事实证明,可以在没有密码的情况下在SharePoint中进行模拟搜索。我们在2009年8月发现了这个问题,并且在更新Stack Overflow时我一直没有回答。

有关详细信息,请参阅http://wiki.threewill.com/display/is/2010/06/18/Connect+to+SharePoint+-+Forwarding+User+Identities,并特别注意特殊要求。请注意,这适用于SharePoint 2007和SharePoint 2010。

非常感谢我的同事Eric Bowden完成了所有的工作!

答案 2 :(得分:0)

在使用对象模型执行搜索时,实际上还有另一种方法可以进行模拟。我可以通过在升高的priveleges下运行时进行模拟来使其工作。在这里查看我的帖子:http://vishalseth.com/post/2013/11/05/Impersonated-Searching-against-SharePoint.aspx