Проблема в создании таймера - PullRequest
6 голосов
/ 24 июня 2009

Я создал семейство сайтов в веб-приложении с пользователем 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();

Теперь, когда я вошел в систему с пользователем А и щелкнул по этой ссылке на странице «Настройки сайта», я получил исключение безопасности с сообщением «Доступ запрещен» в строке automaticArchiveJob.Update(). Но если я вошел в систему с правами администратора (я также вошел в систему на компьютере с помощью этого пользователя) и щелкнул по ссылке, он успешно создал задание. Также я сделал пользователя членом группы WSS_ADMIN_WPG, но проблема все еще остается. Есть ли что-то еще, что мне нужно сделать, чтобы решить эту проблему.

Ответы [ 3 ]

23 голосов
/ 24 июня 2009

«Отказано в доступе» - ожидаемое поведение с учетом того, что вы пытаетесь сделать. Позвольте мне объяснить.

Когда создается экземпляр задания таймера, он сохраняется в базе данных конфигурации фермы. Доступ к этой базе данных для целей записи является привилегированной операцией; как правило, успешной будет только учетная запись службы фермы (то есть учетная запись, под которой выполняется OWSTIMER.EXE) или учетные записи, которые явно имеют права, необходимые для выполнения такой операции над базой данных конфигурации (обычно это администраторы).

По умолчанию попытка создания задания таймера из контекста семейства сайтов завершится неудачно. Попытка выполнить операцию в блоке с повышенными привилегиями (через SPSecurity.RunWithElevatedPrivileges) приведет только к тому, что контекст учетной записи пула приложений веб-приложения будет использоваться вместо текущего пользовательского контекста; это будет успешным, только если учетная запись пула приложений имеет права на запись в базу данных конфигурации фермы. В этом случае обычно это происходит из-за того, что (а) учетная запись службы фермы используется в ролях, в которых она не должна быть (например, для запуска веб-приложений с контентом), или (б) были предоставлены дополнительные разрешения пулу приложений учетная запись. Оба случая представляют собой отклонение от оптимальной операционной модели.

Экземпляры заданий таймера, как правило, создаются во время активации компонента в области функций на уровне фермы или веб-приложения. Зачем? Поскольку эти функции обычно активируются администраторами либо из командной строки (при условии, что администратор также имеет права в базе данных конфигурации фермы), либо из центра администрирования (где активация происходит через учетную запись службы фермы), гарантированно иметь права на базу данных конфигурации ). Когда функция активирована и вызван метод FeatureActivation SPFeatureReceiver, безопасно (с точки зрения безопасности) настроить задание таймера.

Для правильного решения вашей конкретной проблемы потребуется немного перевернуть проблему с ног на голову. Вместо того, чтобы пытаться создать экземпляр задания таймера из семейства сайтов по требованию, я бы рекомендовал установить эквивалент задания таймера «развертки» во время активации вашей функции. По общему признанию, это требует больше планирования и усилий, чем то, что вы пытаетесь сделать, но ваш текущий путь будет работать только в том случае, если безопасность каким-то образом настроена - и это не рекомендуется.

Когда я собирал свою функцию очистки фермы BLOB-кеша (http://blobcachefarmflush.codeplex.com),, мне пришлось самому делать то же самое. Вы можете увидеть особенности того, как я работал при создании задания таймера в классе FeatureReceiver (BlobCacheFarmFlushSweepJobFeatureReceiver Остальная часть кода и связанная с ним документация также могут помочь в решении некоторых других проблем.

Не стесняйтесь использовать то, что вы найдете в любом случае; вот почему это там!

Надеюсь, это поможет. Если есть дополнительные вопросы, ответьте, и я отвечу как можно лучше: -)

0 голосов
/ 25 января 2016

Попробуйте переопределить метод SPPersistedObject.HasAdditionalUpdateAccess () и вернуть true.

protected override bool HasAdditionalUpdateAccess() { return true; }

0 голосов
/ 24 июня 2009

Я использовал RunWithElevatedPrivileges

SPSecurity.RunWithElevatedPrivileges (делегат () { });

У меня работает ..... У кого-нибудь есть другое решение? Если да, пожалуйста, дайте мне знать.

...