我遇到了一种不寻常的情况,我需要一个 SharePoint 计时器作业来既具有本地管理员 Windows 权限,又具有 SHAREPOINT\System SharePoint 权限。

我只需将计时器服务配置为使用本地管理员成员的帐户即可获得 Windows 权限。我知道这不是一个好的解决方案,因为它为 SharePoint 计时器服务提供了比其应有的更多权限。但它至少允许我的 SharePoint 计时器作业运行 stsadm.

在本地管理员下运行计时器服务的另一个问题是该用户不一定有 SHAREPOINT\System 此 SharePoint 作业也需要 SharePoint 权限。事实证明 SPSecurity.RunWithElevatedPrivileges 在这种情况下不起作用。反射镜显示 RunWithElevatedPrivileges 检查当前进程是否 owstimer (运行 SharePoint 作业的服务进程)并且不执行任何提升,就是这种情况(我猜,这里的理由是计时器服务应该在 NT AUTHORITY\NetworkService Windows 帐户有 SHAREPOINT\System SharePoint 权限,因此无需提升计时器作业的权限)。

这里唯一可能的解决方案似乎是在其通常的 NetworkService Windows 帐户下运行计时器服务,并通过将管理员凭据存储在某处并通过 StarInfo 的用户名将它们传递给 System.Diagnostics.Process.Run() 来以本地管理员身份运行 stsadm 、域名和密码。

看来现在一切都应该正常了,但目前我遇到了另一个问题。Stsamd 失败,并弹出以下错误消息 (!)(Winternals filemon 显示 stsadm 在这种情况下在管理员下运行):

The application failed to initialize properly (0x0c0000142).
Click OK to terminate the application.

事件查看器除了弹出窗口之外不注册任何内容。

本地管理员用户是我的帐户,当我刚刚运行时 stsadm 在这个帐户下交互一切正常。当我将计时器服务配置为在此帐户下运行时,它也可以正常工作。

任何建议表示赞赏:)

没有正确的解决方案

其他提示

我不在工作,所以这不是我的想法,但是:如果您获得了对该站点的引用,您可以尝试使用 SYSTEM-UserToken 创建一个新的 SPSite 吗?

SPUserToken sut = thisSite.RootWeb.AllUsers["SHAREPOINT\SYSTEM"].UserToken;

using (SPSite syssite = new SPSite(thisSite.Url,sut)
{
    // Do what you have to do
}

SharePoint 计时器作业使用 SharePoint 公司管理员凭据运行,因为信息进入 SharePoint 配置数据库。因此应用程序池将无权访问。

为了在开发环境中测试计时器作业,我们可以暂时将应用程序池帐户更改为用于管理中心的应用程序池帐户。

其他应用程序如果以这种方式运行(即来自具有显式凭据的计时器作业)以同样的方式失败,并显示“应用程序无法正确初始化”。我只是写了一个简单的应用程序,它采用另一个可执行文件的路径及其参数作为参数,当从该计时器作业运行时,它会以同样的方式失败。

internal class ExternalProcess
{
    public static void run(String executablePath, String workingDirectory, String programArguments, String domain, String userName,
                           String password, out Int32 exitCode, out String output)
    {
        Process process = new Process();

        process.StartInfo.UseShellExecute = false;
        process.StartInfo.RedirectStandardError = true;
        process.StartInfo.RedirectStandardOutput = true;

        StringBuilder outputString = new StringBuilder();
        Object synchObj = new object();

        DataReceivedEventHandler outputAppender =
            delegate(Object sender, DataReceivedEventArgs args)
                {
                    lock (synchObj)
                    {
                        outputString.AppendLine(args.Data);
                    }
                };

        process.OutputDataReceived += outputAppender;
        process.ErrorDataReceived += outputAppender;

        process.StartInfo.FileName = @"C:\AppRunner.exe";
        process.StartInfo.WorkingDirectory = workingDirectory;
        process.StartInfo.Arguments = @"""" + executablePath + @""" " + programArguments;

        process.StartInfo.UserName = userName;
        process.StartInfo.Domain = domain; 
        SecureString passwordString = new SecureString();

        foreach (Char c in password)
        {
            passwordString.AppendChar(c);
        }

        process.StartInfo.Password = passwordString;

        process.Start();

        process.BeginOutputReadLine();
        process.BeginErrorReadLine();

        process.WaitForExit();

        exitCode = process.ExitCode;
        output = outputString.ToString();
    }
}

AppRunner 基本上与上面的片段相同,但没有用户名和密码

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top