Наши разработчики должны иметь возможность запустить задание агента SQL Server из своего кода .Net. Я знаю, что могу вызвать msdb..sp_start_job, чтобы сделать это, но я не хочу давать обычным учетным записям прямой доступ к выполненным заданиям.
Я хотел бы создать хранимую процедуру в базе данных приложения, используя предложение WITH EXECUTE AS для олицетворения учетной записи прокси. Процедура, как мы имеем это:
CREATE PROCEDURE dbo.StartAgentJob
WITH EXECUTE AS 'agentProxy'
AS
BEGIN
EXEC msdb.dbo.sp_start_job N'RunThisJob';
END
Когда мы запускаем это, мы получаем следующее сообщение:
The EXECUTE permission was denied on the object 'sp_start_job', database 'msdb', schema 'dbo'.
Любые идеи? Это даже лучший способ сделать это в SQL2005?
sql-server-2005
sql
sql-server
Эд Лейтон-Дик
источник
источник
Ответы:
Вы поместили логин agentProxy в базу данных msdb и дали ему права на запуск sp_start_job? Если нет, вам нужно включить цепочку разрешений базы данных для базы данных msdb и вашей пользовательской базы данных.
Возможно, вам лучше поместить логин в базу данных msdb и предоставить ей правильные права.
источник
Я рад, что вы решили это, но цепочка владения не является рекомендуемым решением. Поскольку вы, кажется, действительно обеспокоены безопасностью и надлежащим уровнем детализации соответствующих прав, я добавляю этот ответ, хотя и поздно, в качестве ссылки на то, что происходит и как решить эти проблемы.
ВЫПОЛНИТЬ КАК сфера олицетворения
Предложения EXECUTE AS представлены в двух вариантах: EXECUTE AS LOGIN и EXECUTE AS USER. EXECUTE AS LOGIN аутентифицируется сервером и является контекстом олицетворения, которому доверяет весь экземпляр SQL (в области сервера):
EXECUTE AS USER аутентифицируется базой данных и является контекстом олицетворения, которому доверяет только эта база данных (в области баз данных):
Хранимая процедура с предложением EXECUTE AS создаст контекст олицетворения в области базы данных, и, таким образом, не сможет ссылаться на объекты вне базы данных, в данном случае вы не сможете ссылаться,
msdb.dbo.sp_start_job
потому что она находится вmsdb
. Есть много других доступных примеров, таких как попытка доступа к DMV области сервера, попытка использовать связанный сервер или попытка доставить сообщение компонента Service Broker в другую базу данных.Разрешить олицетворению в области базы данных доступ к ресурсу, который обычно не разрешается, следует доверять аутентификатору контекста олицетворения. Для олицетворения в области базы данных аутентификатором является база данных dbo. Это может быть достигнуто двумя возможными способами:
Эти подробности описаны в MSDN: Расширение олицетворения базы данных с помощью EXECUTE AS .
Когда вы решили проблему с помощью цепочки владения несколькими базами данных, вы включили цепочку между базами данных на всем уровне сервера, что считается угрозой безопасности. Наиболее контролируемый, тонко детализированный способ достижения желаемого результата - это использование подписи кода:
dbo.StartAgentJob
с этим сертификатомmsdb
msdb
msdb
Эти шаги гарантируют, что контексту EXECUTE AS
dbo.StartAgentJob
процедуры теперь доверяютmsdb
, потому что контекст подписан участником, имеющим разрешение AUTHENTICATEmsdb
. Это решает половину головоломки. Другая половина - фактически предоставить разрешение EXECUTEmsdb.dbo.sp_start_job
для доверенного контекста олицетворения. Есть несколько способов, как это можно сделать:agentProxy
пользователя вmsdb
и предоставить ему разрешение на выполнениеmsdb.dbo.sp_start_job
msdb
производному пользователю сертификата аутентификатораmsdb
и предоставьте разрешение на выполнение этому производному пользователюВариант 1. прост, но имеет большой недостаток:
agentProxy
пользователь теперь может выполнитьmsdb.dbo.sp_start_job
его по собственному желанию, он действительно имеет доступmsdb
и имеет разрешение на выполнение.Вариант 3, безусловно, правильный, но я чувствую, что это излишнее излишество.
Поэтому я предпочитаю вариант 2: предоставить разрешение EXECUTE для получателя
msdb.dbo.sp_start_job
сертификата, созданного вmsdb
.Вот соответствующий SQL:
В моем блоге есть несколько статей на эту тему, написанных в контексте активированных процедур Service Broker (поскольку для них требуется условие EXECUTE AS):
Кстати, если вы пытаетесь проверить мой сценарий и живете в восточном полушарии или в летнее время в Великобритании, обязательно прочитайте последнюю статью, которую я связал, перед тестированием.
источник
Поскольку вы пытаетесь запустить агент SQL Server из кода .NET, это может быть лучшим вопросом для StackOverflow?
http://www.stackoverflow.com
источник
Проверка случайного экземпляра SQL в сети SQLAgentOperatorRole не дает непосредственных привилегий sp_start_job, а наследует их от SQLAgentUserRole.
Дважды проверьте это с помощью:
Запустите это в MSDB и дважды проверьте, что вы не унаследовали явный отказ в доступе.
НТН.
источник
Один из способов достижения этого без предоставления дополнительных разрешений: не позволяйте хранимому процессу запускать задание напрямую, а просто позволяйте хранимому процессу немного перевернуться в таблице (в базе данных приложения); затем, пусть работа выполняется каждую минуту или около того, проверьте, перевернут ли бит, и если да, выполните работу и снова переверните бит. Если задание увидит, что бит не перевернут, задание просто завершится.
Работает как шарм, если вы не против задержки (и работа выполняется очень часто).
источник