6

过去,我通过执行以下操作在 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,它很快就变得非常难看。我相信确定用户的实际逻辑在非托管代码中处于关闭状态。

那么,我可以这样做吗?

4

3 回答 3

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);
}
于 2009-06-22T07:47:56.563 回答
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,他完成了所有的工作!

于 2010-06-21T13:24:04.770 回答
0

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

于 2013-11-05T22:48:38.897 回答