我过去通过执行以下操作在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,它很快就变得非常难看。我相信确定用户的实际逻辑是非托管代码。
那么,我可以这样做吗?
答案 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