6

我在 Web 应用程序中创建了一个网站集,用户 A 作为网站集管理员。我在站点功能页面中添加了一个链接。单击该链接时,我正在尝试创建一个计时器作业。以下是单击该链接时执行的代码

//Allow unsafe updates.
 SPContext.Current.Web.AllowUnsafeUpdates = true;

//Get current web application.
SPWebApplication webApp = SPContext.Current.Site.WebApplication;

// Create new job.
ArchiveJob automaticArchiveJob = new ArchiveJob(scheduleDetails.scheduleName, webApp);

SPHourlySchedule hourlySchedule = new SPHourlySchedule();
hourlySchedule.BeginMinute = 0;
hourlySchedule.EndMinute = 1;
automaticArchiveJob.Schedule = hourlySchedule;

//Finally update archival job.
automaticArchiveJob.Update();

现在,当我使用用户 A 登录并单击“站点设置”页面上的该链接时,我在 line 处收到一条带有“Access Denied”消息的安全异常automaticArchiveJob.Update()。但是,如果我使用管理员用户登录(我也使用此用户登录到机器)并单击它成功创建作业的链接。我也让用户 A 成为WSS_ADMIN_WPG组的成员,但仍然遇到同样的问题。我还需要做些什么来解决这个问题。

4

3 回答 3

23

鉴于您正在尝试做的事情,“拒绝访问”是预期的行为。请允许我解释一下。

创建计时器作业实例时,它会持久保存到场配置数据库。出于写入目的访问此数据库是一项特权操作;根据经验,只有场服务帐户(即执行 OWSTIMER.EXE 的帐户)或明确具有在配置数据库上执行此类操作所需的权限的帐户(通常是管理员)才会成功。

默认情况下,尝试从网站集上下文中实例化计时器作业将失败。在提升的权限块中尝试操作(通过 SPSecurity.RunWithElevatedPrivileges)只会导致使用 Web 应用程序的应用程序池帐户上下文而不是当前用户上下文;仅当应用程序池帐户有权写入场配置数据库时,此操作才会成功。如果发生这种情况,通常是因为 (a) 场服务帐户被用于不应该使用的角色(例如,运行内容 Web 应用程序),或者 (b) 已向应用程序池授予额外权限帐户。这两种情况都代表了对最佳实践运营模型的偏离。

计时器作业实例通常在功能激活时在 Farm 或 WebApplication 级别范围内的功能中创建。为什么?因为这些功能通常由管理员从命令行(假设管理员在场配置数据库中也拥有权限)或从管理中心(通过场服务帐户进行激活)激活 - 保证拥有对配置数据库的权限)。当功能被激活并调用 SPFeatureReceiver 的 FeatureActivated 方法时,设置计时器作业是安全的(从安全角度来看)。

正确解决您的特定问题将涉及稍微改变问题。我建议不要在网站集中按需实例化计时器作业,而是在激活您的功能时设置相当于“扫描”计时器作业。诚然,这比您尝试做的事情需要更多的计划和努力,但您当前的路径只有在以某种方式调整安全性的情况下才会起作用 - 不建议这样做。

当我将我的 BLOB 缓存场刷新功能 ( http://blobcachefarmflush.codeplex.com ) 放在一起时,我必须自己做很多相同的事情。您可以在 FeatureReceiver 类 (BlobCacheFarmFlushSweepJobFeatureReceiver) 中查看我如何创建计时器作业的详细信息。其余代码和相关文档也可能有助于解决出现的其他一些挑战。

随意以任何方式使用你找到的东西;这就是它存在的原因!

我希望这会有所帮助。如果有后续问题,请开火,我会尽我所能回答:-)

于 2009-06-24T13:53:20.867 回答
0

尝试覆盖 SPPersistedObject.HasAdditionalUpdateAccess() 方法并返回 true。

protected override bool HasAdditionalUpdateAccess() { return true; }

于 2016-01-25T05:18:31.393 回答
-3

我用过 RunWithElevatedPrivileges

SPSecurity.RunWithElevatedPrivileges(delegate() { });

它对我有用.....有人有其他解决方案吗?如果是这样,请告诉我。

于 2009-06-24T06:49:52.050 回答