过去,我通过执行以下操作在 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,它很快变得非常难看。我相信确定用户的实际逻辑在非托管代码中。
那么,我可以这样做吗?
最佳答案
您需要真正的 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);
}
关于sharepoint - 您能否在不提供密码的情况下在 SharePoint 中执行模拟搜索?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1025409/